KubernetesContainerd

一、概述

作为接替 Docker 运行时的 Containerd 在早在 Kubernetes1.7 时就能直接与 Kubelet 集成使用,只是大部分时候因熟悉 Docker,在部署集群时采用了默认的 dockershim。在V1.24起的版本的 kubelet 就彻底移除了dockershim,改为默认使用Containerd了,当然也使用 cri-dockerd 适配器来将 Docker Engine 与 Kubernetes 集成。可以参考官方文档:

https://kubernetes.io/zh-cn/docs/setup/production-environment/container-runtimes/#docker

Containerd ctr、crictl、nerdctl 客户端命令介绍与实战操作 - 图1

二、Containerd 常见命令操作

更换 Containerd 后,以往常用的 docker 命令也不再使用,取而代之的分别是 crictl 和 ctr 两个命令客户端。
  • crictl** 是遵循 CRI 接口规范的一个命令行工具,通常用它来检查和管理kubelet**节点上的容器运行时和镜像。
  • ctr** 是 containerd **的一个客户端工具。
  • ctr -v** 输出的是 containerd 的版本,crictl -v 输出的是当前 k8s 的版本,从结果显而易见可以认为 crictl 是用于 k8s 的。**
  • 一般来说某个主机安装了 k8s 后,命令行才会有 crictl 命令。而 ctr 是跟 k8s 无关的,主机安装了 containerd 服务后就可以操作 ctr 命令。
使用crictl命令之前,需要先配置/etc/crictl.yaml如下:
  1. runtime-endpoint: unix:///run/containerd/containerd.sock
  2. image-endpoint: unix:///run/containerd/containerd.sock
  3. timeout: 10
  4. debug: false
也可以通过命令进行设置:
  1. crictl config runtime-endpoint unix:///run/containerd/containerd.sock
  2. crictl config image-endpoint unix:///run/containerd/containerd.sock
命令 docker ctr(containerd) crictl(kubernetes)
查看运行的容器 docker ps ctr task ls/ctr container ls crictl ps
查看镜像 docker images ctr image ls crictl images
查看容器日志 docker logs 无 crictl logs
查看容器数据信息 docker inspect ctr container info crictl inspect
查看容器资源 docker stats 无 crictl stats
启动/关闭已有的容器 docker start/stop ctr task start/kill crictl start/stop
运行一个新的容器 docker run ctr run 无(最小单元为 pod)
打标签 docker tag ctr image tag 无
创建一个新的容器 docker create ctr container create crictl create
导入镜像 docker load ctr image import 无
导出镜像 docker save ctr image export 无
删除容器 docker rm ctr container rm crictl rm
删除镜像 docker rmi ctr image rm crictl rmi
拉取镜像 docker pull ctr image pull ctictl pull
推送镜像 docker push ctr image push 无
登录或在容器内部执行命令 docker exec 无 crictl exec
清空不用的容器 docker image prune 无 crictl rmi —prune
更多命令操作,可以直接在命令行输入命令查看帮助。
  1. docker --help
  2. ctr --help
  3. crictl --help
由于 Containerd 也有 namespaces 的概念,对于上层编排系统的支持,ctr 客户端 主要区分了 3 个命名空间分别是k8s.io、moby和default,以上用crictl操作的均在k8s.io命名空间,使用ctr 看镜像列表就需要加上-n 参数。crictl 是只有一个k8s.io命名空间,但是没有-n 参数。 【温馨提示】ctr images pull 拉取的镜像默认放在default,而 crictl pull 和 kubelet 默认拉取的镜像都在 k8s.io 命名空间下。所以通过ctr导入镜像的时候特别注意一点,最好指定命名空间。
  1. # 注意-n不能放在命令最后面,下面几行查看的镜像是一样的
  2. ctr -n=k8s.io image ls
  3. ctr -n k8s.io image ls
  4. # crictl 没有-n参数,操作都在`k8s.io`命名空间下。
  5. crictl image ls
  6. crictl images
  7. # crictl image list = ctr -n=k8s.io image list
  8. # crictl image ls = ctr -n=k8s.io image ls
  9. # crictl images = ctr -n=k8s.io image list
  10. # crictl images = ctr -n=k8s.io image ls
  11. # 使用ctr命令指定命名空间导入镜像
  12. ctr -n=k8s.io image import dashboard.tar
  13. #查看镜像,可以看到可以查询到了
  14. crictl images

Containerd ctr、crictl、nerdctl 客户端命令介绍与实战操作 - 图2

三、containerd 客户端工具 nerdctl

推荐使用 nerdctl,使用效果与 docker 命令的语法一致,github 下载链接:

https://github.com/containerd/nerdctl/releases

  • 精简 (nerdctl—linux-amd64.tar.gz): 只包含 nerdctl
  • 完整 (nerdctl-full—linux-amd64.tar.gz): **包含 containerd, runc, and CNI 等依赖**
nerdctl 的目标并不是单纯地复制 docker 的功能,它还实现了很多 docker 不具备的功能,例如延迟拉取镜像(lazy-pulling)、镜像加密(imgcrypt)等。具体看 nerdctl。

Containerd ctr、crictl、nerdctl 客户端命令介绍与实战操作 - 图3
延迟拉取镜像功能可以参考这篇文章:Containerd 使用 Stargz Snapshotter 延迟拉取镜像

https://icloudnative.io/posts/startup-containers-in-lightning-speed-with-lazy-image-distribution-on-containerd/

1)安装 nerdctl(精简版)

  1. wget https://github.com/containerd/nerdctl/releases/download/v0.22.2/nerdctl-0.22.2-linux-amd64.tar.gz
  2. # 解压
  3. tar -xf nerdctl-0.22.2-linux-amd64.tar.gz
  4. ln -s /opt/k8s/nerdctl/nerdctl /usr/local/bin/nerdctl

2)安装 nerdctl(完整版,这里不装)

  1. wget https://github.com/containerd/nerdctl/releases/download/v0.22.2/nerdctl-full-0.22.2-linux-amd64.tar.gz
  2. tar -xf nerdctl-full-0.16.0-linux-amd64.tar.gz -C /usr/local/
  3. cp /usr/local/lib/systemd/system/*.service /etc/systemd/system/
启动服务 buildkit
  1. systemctl enable buildkit containerd --now
  2. systemctl status buildkit containerd

3)安装 buildkit 支持构建镜像

buildkit GitHub 地址:https://github.com/moby/buildkit 使用精简版 nerdctl 无法直接通过 containerd 构建镜像,需要与 buildkit 组全使用以实现镜像构建。当然也可以安装上面的完整 nerdctl;buildkit 项目是 Docker 公司开源出来的一个构建工具包,支持 OCI 标准的镜像构建。它主要包含以下部分:
  • 服务端 buildkitd,当前支持 runc 和 containerd 作为 worker,默认是 runc;
  • 客户端 buildctl,负责解析 Dockerfile,并向服务端 buildkitd 发出构建请求。
buildkit 是典型的C/S 架构,client 和 server 可以不在一台服务器上。而 nerdctl 在构建镜像方面也可以作为 buildkitd 的客户端。
  1. # https://github.com/moby/buildkit/releases
  2. wget https://github.com/moby/buildkit/releases/download/v0.10.4/buildkit-v0.10.4.linux-amd64.tar.gz
  3. tar -xf buildkit-v0.10.4.linux-amd64.tar.gz -C /usr/local/
配置 buildkit 的启动文件,可以从这里下载: https://github.com/moby/buildkit/tree/master/examples/systemd buildkit 需要配置两个文件
  • /usr/lib/systemd/system/buildkit.socket
  1. cat > /usr/lib/systemd/system/buildkit.socket <<EOF
  2. [Unit]
  3. Description=BuildKit
  4. Documentation=https://github.com/moby/buildkit
  5. [Socket]
  6. ListenStream=%t/buildkit/buildkitd.sock
  7. SocketMode=0660
  8. [Install]
  9. WantedBy=sockets.target
  10. EOF
  • /usr/lib/systemd/system/buildkit.service
  1. cat > /usr/lib/systemd/system/buildkit.service << EOF
  2. [Unit]
  3. Description=BuildKit
  4. Requires=buildkit.socket
  5. After=buildkit.socket
  6. Documentation=https://github.com/moby/buildkit
  7. [Service]
  8. # Replace runc builds with containerd builds
  9. ExecStart=/usr/local/bin/buildkitd --addr fd://
  10. [Install]
  11. WantedBy=multi-user.target
  12. EOF
启动 buildkit
  1. systemctl daemon-reload
  2. systemctl enable buildkit --now

Containerd ctr、crictl、nerdctl 客户端命令介绍与实战操作 - 图4

四、实战操作

1)修改 containerd 配置文件

  1. containerd config default > /etc/containerd/config.toml
配置如下:
  1. [plugins."io.containerd.grpc.v1.cri".registry]
  2. config_path = ""
  3. [plugins."io.containerd.grpc.v1.cri".registry.auths]
  4. [plugins."io.containerd.grpc.v1.cri".registry.configs]
  5. [plugins."io.containerd.grpc.v1.cri".registry.configs."myharbor-minio.com".tls]
  6. insecure_skip_verify = true #跳过认证
  7. ca_file = "/etc/containerd/myharbor-minio.com/ca.crt"
  8. [plugins."io.containerd.grpc.v1.cri".registry.configs."myharbor-minio.com".auth]
  9. username = "admin"
  10. password = "Harbor12345"
  11. [plugins."io.containerd.grpc.v1.cri".registry.headers]
  12. [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
  13. [plugins."io.containerd.grpc.v1.cri".registry.mirrors."myharbor-minio.com"]
  14. endpoint = ["https://myharbor-minio.com"]

Containerd ctr、crictl、nerdctl 客户端命令介绍与实战操作 - 图5
重启 containerd

  1. #重新加载配置
  2. systemctl daemon-reload
  3. #重启containerd
  4. systemctl restart containerd
注意:这个配置文件是给crictl和kubelet使用,ctr是不可以用这个配置文件的,ctr 不使用 CRI,因此它不读取 plugins.”io.containerd.grpc.v1.cri”配置。

2)ctr 拉取推送镜像

  1. # 推送镜像到harbor
  2. ctr --namespace=k8s.io images push myharbor-minio.com/bigdata/minio:2022.8.22-debian-11-r0 --skip-verify --user admin:Harbor12345
  3. # --namespace=k8s.io 指定命名空间,不是必须,根据环境而定
  4. # --skip-verify 跳过认证
  5. # --user 指定harbor用户名及密码
  6. ctr images pull --user admin:Harbor12345 --tlscacert=/etc/containerd/myharbor-minio.com/ca.crt myharbor-minio.com/bigdata/minio:2022.8.22-debian-11-r0
不想<font style="color:rgb(58, 58, 58);">-u user:password</font> 每次必须使用 ctr pull/ctr push, 可以使用<font style="color:rgb(155, 110, 35);background-color:rgb(255, 245, 227);">nerdctl</font><font style="color:rgb(58, 58, 58);"> </font>。

3)镜像构建

  1. cat > Dockerfile <<EOF
  2. FROM nginx:alpine
  3. RUN echo 'Hello Nerdctl From Containerd' > /usr/share/nginx/html/index.html
  4. EOF
然后在文件所在目录执行镜像构建命令:
  1. # 不加-n指定命名空间,crictl看不到,kubelet也不能使用它,默认在default命名空间下
  2. nerdctl -n k8s.io build -t nginx:nerctl -f ./Dockerfile .
  3. ### 参数解释
  4. # -t:指定镜像名称
  5. # . :当前目录Dockerfile
  6. # -f:指定Dockerfile路径
  7. # --no-cache:不缓存

Containerd ctr、crictl、nerdctl 客户端命令介绍与实战操作 - 图6

4)打标签 tag

  1. # crictl没有tag命令,只能使用nerdctl和ctr,必须指定命名空间,要不然kubelet无法使用。
  2. ctr -n k8s.io i tag
  3. nerdctl -n k8s.io tag nginx:nerctl myharbor-minio.com/bigdata/nginx:nerctl
  4. # ctr -n k8s.io tag nginx:nerctl myharbor-minio.com/bigdata/nginx:nerctl
  5. # 查看镜像
  6. nerdctl -n k8s.io images myharbor-minio.com/bigdata/nginx:nerctl

5)将镜像推送到 Harbor

第一种情况:http方式,配置如下:
  1. # 以下两个哪个都可以
  2. # mkdir -p /etc/docker/certs.d/myharbor-minio.com:443
  3. mkdir -p /etc/containerd/certs.d/myharbor-minio.com:443
  4. cat > /etc/containerd/certs.d/myharbor-minio.com\:443/hosts.toml <<EOF
  5. server = "https://docker.io"
  6. [host."http://myharbor-minio.com:80"]
  7. capabilities = ["pull", "resolve","push"]
  8. #skip_verify = true
  9. #ca = "ca.crt" #相对路径
  10. #ca = "/opt/auth/ca.crt" #绝对路径
  11. #ca = ["/opt/auth/ca.crt"]
  12. #ca = ["ca.crt"]
  13. #client = [["/opt/auth/nginx.cclinux.cn.crt", "/opt/auth/nginx.cclinux.cn.key"]]
  14. EOF
第一种情况:https方式,配置如下:
  1. # 以下两个哪个都可以
  2. # mkdir -p /etc/docker/certs.d/myharbor-minio.com:443
  3. mkdir -p /etc/containerd/certs.d/myharbor-minio.com:443
  4. cat > /etc/containerd/certs.d/myharbor-minio.com\:443/hosts.toml <<EOF
  5. server = "https://docker.io"
  6. [host."https://myharbor-minio.com:443"]
  7. capabilities = ["pull", "resolve","push"]
  8. skip_verify = true
  9. #ca = "ca.crt" #相对路径
  10. #ca = "/opt/auth/ca.crt" #绝对路径
  11. #ca = ["/opt/auth/ca.crt"]
  12. ca = ["/etc/containerd/myharbor-minio.com/ca.crt"]
  13. #client = [["/opt/auth/nginx.cclinux.cn.crt", "/opt/auth/nginx.cclinux.cn.key"]]
  14. EOF
通过 nerdctl 登录 harbor
  1. echo Harbor12345 | nerdctl login --username "admin" --password-stdin myharbor-minio.com:443
  2. # nerdctl login --username "admin" --password Harbor12345 myharbor-minio.com:443
  3. # 登出
  4. # nerdctl logout

Containerd ctr、crictl、nerdctl 客户端命令介绍与实战操作 - 图7

开始将镜像推送到 harbor
  1. ### 推送到Harbor
  2. # --insecure-registry skips verifying HTTPS certs, and allows falling back to plain HTTP
  3. nerdctl --insecure-registry --namespace=k8s.io push myharbor-minio.com/bigdata/nginx:nerctl
  4. # ctr --namespace=k8s.io images push myharbor-minio.com/bigdata/nginx:nerctl --skip-verify --user admin:Harbor12345
  5. # --namespace=k8s.io 指定命名空间,跟-n一样,不是必须,根据环境而定
  6. # --skip-verify 跳过认证
  7. # --user 指定harbor用户名及密码

Containerd ctr、crictl、nerdctl 客户端命令介绍与实战操作 - 图8

Containerd ctr,crictl,nerdctl 客户端命令介绍与实战操作就到这里了。