1. docker与containerd对比
在 V1.24 版本以前 k8s 默认使用docker容器引擎
在 V1.24 版本以后 k8s 移除了dockershim,改为默认使用Containerd
1.1. 调用链路的区别
使用docker作为容器引擎时需要通过dockershim对接docker再调用containerd。
使用containerd作为容器引擎时kubelt可以通过CRI-containerd直接调用containerd。
1.2. 标准输出日志路径的区别
docker | containerd | |
储存路径 | 如果 Kubernetes 使用 Docker 作为容器运行时,容器日志的落盘由docker来完成, 日志通常存储在 /var/lib/docker/containers/<container-id>-json.log。 | 如果 Kubernetes 使用 containerd 作为容器运行时,容器日志的落盘由kubelet来完成,路径 为/var/log/pods/<namespace>_<pod-name>_<pod-uid>/<container-name>/<container-id>,同时在/var/log/containers目录下创建软链接,指向日志文件 |
配置参数 | 在docker配置文件中指定: “log-driver”: “json-file”, “log-opts”: {“max-size”: “100m”,”max-file”: “5”} | 方法一:在kubelet参数中指定: –container-log-max-files=5 –container-log-max-s |
1.3. 配置文件路径
containerd配置文件/etc/containerd/config.toml
# 默认配置中还有两个关于存储的配置路径:
# 1、保存持久化数据,包括 Snapshots, Content, Metadata 以及各种插件的数据
root = "/var/lib/containerd"
# 2、保存运行时的临时数据的,包括 sockets、pid、挂载点、运行时状态以及不需要持久化的插件数据。
state = "/run/containerd"
ShellScript2. containerd 客户端命令介绍
2.1. crictl、ctr 命令
更换 containerd 后,以往我们常用的 docker 命令也不再使用,取而代之的分别是 crictl 和 ctr 两个命令客户端。
- crictl 命令(k8s提供):crictl 是遵循 CRI 接口规范的一个命令行工具,通常用它来检查和管理kubelet节点上的容器运行和镜像。
- ctr 命令(containerd提供):ctr 是 containerd 的一个客户端工具。
- 二者区别:ctr -v 输出的是 containerd 的版本,crictl -v 输出的是当前 k8s 的版本,从结果显而易见你可以认为 crictl 是用于 k8s 的。
注意:
# 使用crictl命令之前,需要先配置/etc/crictl.yaml如下(不配置的话,你用该命令会一直报warn警告)
cat > /etc/crictl.yaml << 'EOF'
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
# 也可以通过命令进行设置(会自动生成/etc/crictl.yaml)
sudo crictl config runtime-endpoint unix:///run/containerd/containerd.sock
sudo crictl config image-endpoint unix:///run/containerd/containerd.sock
ShellScript基础操作命令:
# 用于列出当前系统中的命名空间(namespaces)
sudo ctr ns ls
NAME LABELS
k8s.io
# 用于列出指定命名空间(namespace)中的镜像(images)列表
sudo ctr -n k8s.io image ls
# crictl 没有-n参数,操作都默认在`k8s.io`命名空间下
sudo crictl images
sudo crictl pods
ShellScript2.2. nerdctl 命令
前面我们介绍了可以使用 ctr 操作管理 containerd 镜像容器,但是大家都习惯了使用 docker cli,ctr 使用起来可能还是不太顺手,为了能够让大家更好的转到 containerd 上面来,社区提供了一个新的命令行工具:nerdctl。
nerdctl 是一个与 docker cli 风格兼容的 containerd 客户端工具,而且直接兼容 docker compose 的语法,这就大大提高了直接将 containerd 作为本地开发、测试或者单机容器部署使用的效率。
安装:
# 如果没有安装 nerdctl,则可以下载 nerdctl-full-<VERSION>-linux-amd64.tar.gz 包进行安装
wget https://github.com/containerd/nerdctl/releases/download/v1.7.6/nerdctl-1.7.6-linux-amd64.tar.gz
mkdir -p /usr/local/containerd/bin/ && tar -zxvf nerdctl-1.7.6-linux-amd64.tar.gz nerdctl && mv nerdctl /usr/local/containerd/bin/
ln -s /usr/local/containerd/bin/nerdctl /usr/local/bin/nerdctl
[root@k8s-node-01 ~]# nerdctl version # 报错warn,提示buildkit未安装
WARN[0000] unable to determine buildctl version: exec: "buildctl": executable file not found in $PATH
Client:
Version: v1.7.6
安装buildkit(参考:https://zhuanlan.zhihu.com/p/366671300)
wget https://github.com/moby/buildkit/releases/download/v0.13.2/buildkit-v0.13.2.linux-amd64.tar.gz
解压后得到一个bin目录,把这个bin目录放到 $PATH 里去
ShellScript2.3. 客户端命令 docker、ctr、crictl、nerdctl 详解
2.3.1. 名称空间
可以用 -n 指定名称空间,可以将镜像或者容器分散到不同的空间内,但并非所有命令都支持
docker | ctr (containerd) | crictl(k8s) | nerdctl | |
是否支持 | 不支持 | 支持 | 不支持 | 支持 |
示例 | ctr ns ls ctr -n k8s.io image ls # 查看指定名称空间下的镜像 ctr -n k8s.io container ls # 查看指定名称空间下的容器 | 默认所有操作都在k8s.io名称空间下 | nerdctl -n k8s.io image ls nerdctl -n k8s.io container ls |
2.3.2. 镜像相关命令
命令 | docker | ctr | crictl | nerdctl |
查看本地镜像 | docker images | ctr image ls | crictl images | 同docker命令 |
下载/拉取镜像 | docker pull | ctr image pull | ctictl pull | 同docker命令 |
给镜像打标签 | docker tag | ctr image tag | 无 | 同docker命令 |
上传/推送镜像 | docker push | ctr image push | 无 | 同docker命令 |
删除本地镜像 | docker rmi | ctr image rm | crictl rmi | 同docker命令 |
查看镜像详情 | docker inspect | 无 | crictl inspecti # 注意末尾是小写字母 i | 同docker命令 |
导出镜像 | docker save | ctr image export | 无 | 同docker命令 |
导入镜像 | docker load | ctr image import xx.tar docker.io/library/nginx:alpine | 无 | 同docker命令 |
登录镜像仓库 | docker login | 不支持,理由:ctr 工具主要是用于底层的容器操作和管 理,而不是直接与镜像仓库进行交互如推拉镜像等。 | 不支持,理由:主要用于管理 Pod 和容器,而非直接与镜像仓库交互。 | 支持 |
ctr(containerd)镜像命令详解
# 1、查看全部镜像
sudo ctr image ls # 分字段展示
sudo ctr image ls -q # 列出本地存储中的镜像(images)的 ID 列表,而不显示详细的镜像信息。
sudo ctr image check # 检测default名称空间下所有镜像的可用性,主要看STATUS为complete代表可用
# 2、拉取 Docker Hub 官方镜像 nginx:alpine,需要注意的是镜像地址需要加上 docker.io Host 地址
sudo ctr images pull docker.io/library/nginx:alpine
# 3、重新打标签
sudo ctr image tag docker.io/library/nginx:alpine harbor.k8s.local/course/nginx:alpine
# 4、上传镜像
sudo ctr images push docker.io/library/nginx:alpine --user xxx
# 5、删除镜像
sudo ctr image rm harbor.k8s.local/course/nginx:alpine
# 6、查看镜像详情
无
# 7、将镜像导出为压缩包
sudo ctr image export nginx.tar.gz docker.io/library/nginx:alpine
sudo ctr -n k8s.io image export a.tar.gz registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.11.1
# 8、从压缩包导入镜像
sudo ctr image import nginx.tar.gz
sudo ctr -n default image import a.tar.gz
# 直接导入可能会出现类似于 ctr: content digest sha256:xxxxxx not found 的错误,要解决这个办法需要 pull 可以通用/适用所有平台的镜像:
sudo ctr i pull --all-platforms docker.io/library/nginx:alpine
sudo ctr i export --all-platforms nginx.tar.gz docker.io/library/nginx:alpine
sudo ctr i rm docker.io/library/nginx:alpine
sudo ctr i import nginx.tar.gz
# 9、将镜像挂载到主机目录
sudo ctr image mount docker.io/library/nginx:alpine /mnt
sudo ctr image unmount /mnt
# 10、命名空间:Containerd 也有 namespaces 的概念,镜像或容器可以分散到不同的空间,对于多租户的场景十分有用
sudo ctr ns ls
sudo ctr ns create test
sudo ctr ns rm test
sudo ctr -n test image ls
# 说明:
# 1、Docker 其实也是默认调用的 containerd,事实上 Docker 使用的 containerd 下面的命名空间默认是 moby,而不是 default
# 2、Kubernetes 下使用的 containerd 默认命名空间是 k8s.io
ShellScriptcrictl(kubernetes)镜像命令详解
# crictl 没有-n参数,操作都在`k8s.io`命名空间下。
# sudo crictl image list 等同于 sudo ctr -n=k8s.io image list
# sudo crictl image ls 等同于 sudo ctr -n=k8s.io image ls
# 注意:
# sudo ctr images pull 拉取的镜像默认放在 default 而 sudo crictl pull 和 kubelet 默认拉取的镜像都在 k8s.io 命名空间下。所以通过 ctr 导入镜像的时候特别注意一点,最好指定命名空间。
ShellScriptnerdctl镜像命令详解
# 镜像管理
nerdctl images
nerdctl pull docker.io/library/busybox:latest
nerdctl login --username=xxx --password yyy registry.cn-shanghai.aliyuncs.com
nerdctl tag centos:7 registry.cn-shanghai.aliyuncs.com/egon/test:v1.0
nerdctl push registry.cn-shanghai.aliyuncs.com/egon/test:v1.0
nerdctl save -o busybox.tar.gz busybox:latest
nerdctl load -i busybox.tar.gz
nerdctl rmi busybox
# ctr不能 build 镜像,我们可以用 nerdctl
# 1、Dockerfile文件如下
FROM centos:7
CMD sleep 1000
# 2、构建镜像
nerdctl build -t test:v1.0 -f Dockerfile
# 可以看到有一个错误提示,需要我们安装 `buildctl` 并运行 `buildkitd`,这是因为 `nerdctl build` 需要依赖 `buildkit` 工具。
# buildkit 项目也是 Docker 公司开源的一个构建工具包,支持 OCI 标准的镜像构建。它主要包含以下部分:
# 1、服务端 `buildkitd`:当前支持 runc 和 containerd 作为 worker,默认是 runc,我们这里使用 containerd
# 2、客户端 `buildctl`:负责解析 Dockerfile,并向服务端 buildkitd 发出构建请求
# buildkit 是典型的 C/S 架构,客户端和服务端是可以不在一台服务器上,而 `nerdctl` 在构建镜像的时候也作为 `buildkitd` 的客户端,所以需要我们安装并运行 `buildkitd`。
# 安装buildkit
wget https://github.com/moby/buildkit/releases/download/v0.13.2/buildkit-v0.13.2.linux-amd64.tar.gz
tar -zxvf buildkit-v0.13.2.linux-amd64.tar.gz -C /usr/local/containerd/
ln -s /usr/local/containerd/bin/buildkitd /usr/local/bin/buildkitd
ln -s /usr/local/containerd/bin/buildctl /usr/local/bin/buildctl
cat > /etc/systemd/system/buildkit.service << "EOF"
[Unit]
Description=BuildKit
Documentation=https://github.com/moby/buildkit
[Service]
ExecStart=/usr/local/bin/buildkitd --oci-worker=false --containerd-worker=true
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable buildkit --now
systemctl status buildkit.service
# 重新构建镜像
[root@k8s-node-01 test]# nerdctl build -t test:v1.0 -f Dockerfile
FATA[0000] lstat /test/Containerfile: no such file or directory
[root@k8s-node-01 test]# ls
dockerfile
[root@k8s-node-01 test]#
[root@k8s-node-01 test]# mv dockerfile Containerfile
[root@k8s-node-01 test]# nerdctl build -t test:v1.0 -f Dockerfile
[root@k8s-node-01 test]# nerdctl images
# 启动测试
nerdctl run -d --name=test test:v1.0
nerdctl container ls
nerdctl exec -ti test sh
ShellScript2.3.2. 容器相关命令
命令 | docker | ctr | crictl |
显示本地运行的容器 | docker ps | ctr task ls/ctr container ls | crictl ps |
创建一个新容器 | docker create | ctr container create | crictl create |
运行一个新容器 | docker run | ctr run | 无(最小单元为 pod) |
启动容器 | docker start | ctr task start | crictl start |
关闭容器 | docker stop | ctr task kill | crictl stop |
删除容器 | docker rm | ctr container rm | crictl rm |
查看容器详情 | docker inspect | ctr container info | crictl inspect |
查看容器日志 | docker logs | 无 | crictl logs |
查看容器资源 | docker stats | 无 | crictl stats |
进入容器内部 | docker exec | 无 | crictl exec |
清空不用的容器 | docker image prune | 无 | crictl rmi –prune |
ctr(containerd)镜像命令详解
# 容器操作
## 创建容器
ctr image pull docker.io/library/nginx:alpine --hosts-dir=/etc/containerd/certs.d
ctr container create docker.io/library/nginx:alpine nginx
## 查看容器
ctr container ls
ctr container ls -q
ctr container info nginx
## 删除容器
ctr container rm nginx
# 任务
## (1)任务介绍
# 上面用container create只是创建了一个静态的容器对象,把运行容器需要的资源及配置数据例如namespaces、rootfs和容器的配置都初始化完毕了,但是容器内的进程还没有启动,即容器尚未处于运行状态
## (2) 启动任务(激活容器)
ctr task start -d nginx # nginx是你创建的容器名字
## (3)查看
ctr task ls
## (4)进入容器
# 注意必须要指定 --exec-id 参数,这个 id 可以随便写,只要唯一就行。
ctr task exec --exec-id 0 -t nginx sh
## (5)暂停容器
ctr task pause nginx # 可以查看容器ctr task ls发现状态变成PAUSED
## (6)恢复容器
ctr task resume nginx
## (7)ctr无法stop容器,只能暂停或杀死
ctr task kill nginx # 可以查看容器ctr task ls发现状态变成STOPPED
## (8)删掉
ctr task rm nginx
## (9)获取容器cgroup相关信息(内存、CPU 和 PID 的限额与使用量。)
ctr task metrics nginx # 记得要先启动才能看:ctr task start -d nginx
## (10)看容器中所有进程在宿主机中的 PID
ctr task ps nginx # 第一行的就对应容器内的1号进程
ShellScriptnerdctl 镜像命令详解
# 容器管理
nerdctl run -d -p 80:80 --name=nginx --restart=always nginx:alpine
nerdctl exec -it nginx /bin/sh
nerdctl ps
nerdctl ps -a
nerdctl inspect nginx
nerdctl logs
nerdctl logs -f
nerdctl stop nginx
nerdctl rm nginx
nerdctl rm -f nginx
# 更多命令操作,可以直jgdddgjkdgbkhgh接在命令行输入命令查看帮助。
docker --help
ctr --help
crictl --help
ShellScript3. kubectl 命令介绍
3.1. 基本语法
kubectl [command] [TYPE] [NAME] [flags]
# command
## 子命令,用于操作资源对象,例如create、get、describe、delete等
# TYPE
## 资源类型,区分大小写,并且可以简写,例如下述三个命令效果相同
kubectl get pods xxx
kubectl get pod xxx
kubectl get po xxx
# NAME
## 具体的资源名,区分大小写,如果不指定具体的资源NAME,则默认返回全部,并且在一条命令里指定多个资源操作
kubectl get pod xxx yyy zzz
kubectl get pod/xxx deployment/aaa
kubectl apply -f 1.yaml -f 2.yaml
# 了解:
kubectl create -f 1.yaml # 只能用于创建新资源,如果资源已存在create -f会报错
kubectl apply -f 1.yaml # 创建或更新,所以推荐使用apply -f
# flags
## 可选参数,例如
kubectl get pods xxx -o wide
kubectl get pods xxx -o yaml
ShellScript2.2. 常用用法
2.2.1. 查看
# 查看帮助文档
kubectl --help
kubectl apply --help # 查看二级帮助文档
kubectl api-resources # 查看资源类型
# 示例
kubectl get deploy,pods -o wide -n 某个名称空间 # -n可以直接跟在kubectl后
kubectl get deploy,pods -o wide -A # -A不能直接跟在kubectl后,要往后放,代表查看所有名称空间,
kubectl get deploy 具体的deploy名 -o yaml
kubectl logs -f pod名
kubectl describe node node01
# 关于describe的结果示例:
# Controlled By 指明此 Pod 是由 ReplicaSet/xxx 创建。Events 记录了 Pod 的启动过程。如果操作失败(比如 image 不存在),也能在这里查看到原因
ShellScript2.2.2. 增加
# 基于yaml创建
kubectl apply -f 1.yaml
# 直接用命令创建,
# 例如:启动临时容器,用于测试,exit退出后则删除
kubectl run -i --tty --image busybox:1.27 egon-test --restart=Never --rm sh
ShellScript2.2.3. 改
# 修改副本
kubectl scale deployment xxx --replicas=0
# 在线编辑
kubectl edit deployment xxx
ShellScript2.2.4. 删
kubectl delete deloyment xxx
kubectl delete pods,services -l <label-key>=<label-value> # 删除带有标签<label-key>=<label-value>的pod和svc
# 查出标签:kubectl get pods --show-labels
kubectl delete -f 1.yaml
ShellScript2.2.5. 进入pod内部
kubectl exec -it pod名字 -- bash
# 拷贝文件
kubectl cp pod名:/etc/fstab /tmp/a.txt # pod内文件拷贝到本机,必须指定文件名
kubectl cp /tmp/a.txt pod名:/tmp # 本机拷贝到pod内
ShellScript