• Containerd ctr、crictl、nerdctl客户端命令——筑梦之路


     一、概述

    作为接替 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 常见命令操作

    更换 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
    5. 或者使用命令:
    6. crictl config runtime-endpoint unix:///run/containerd/containerd.sock
    7. crictl config image-endpoint unix:///run/containerd/containerd.sock
    命令dockerctr(containerd)crictl(kubernetes)
    查看运行的容器docker psctr task ls/ctr container lscrictl ps
    查看镜像docker imagesctr image lscrictl images
    查看容器日志docker logscrictl logs
    查看容器数据信息docker inspectctr container infocrictl inspect
    查看容器资源docker statscrictl stats
    启动/关闭已有的容器docker start/stopctr task start/killcrictl start/stop
    运行一个新的容器docker runctr run无(最小单元为 pod)
    打标签docker tagctr image tag
    创建一个新的容器docker createctr container createcrictl create
    导入镜像docker loadctr image import
    导出镜像docker savectr image export
    删除容器docker rmctr container rmcrictl rm
    删除镜像docker rmictr image rmcrictl rmi
    拉取镜像docker pullctr image pullctictl pull
    推送镜像docker pushctr image push
    登录或在容器内部执行命令docker execcrictl exec
    清空不用的容器docker image prunecrictl rmi --prune
    命令docker/nerdctlctrcrictl
    查看运行的容器docker/nerdctl  psctr task ls/ctr container lscrictl ps
    查看镜像docker/nerdctl imagesctr image lscrictl images
    查看容器日志docker/nerdctl logscrictl logs
    查看容器数据信息docker/nerdctl inspectctr container infocrictl inspect
    查看容器资源docker/nerdctl statscrictl stats
    启动/关闭已有的容器docker/nerdctl start/stopctr task start/killcrictl start/stop
    运行一个新的容器docker/nerdctl  runctr run无(最小单元为 pod)
    打标签docker/nerdctl tagctr image tag
    创建一个新的容器docker/nerdctl  createctr container createcrictl create
    导入镜像docker/nerdctl loadctr image import
    导出镜像docker/nerdctl savectr image export
    删除容器docker/nerdctl rmctr container rmcrictl rm
    删除镜像docker/nerdctl rmictr image rmcrictl rmi
    拉取镜像docker /nerdctl  pullctr image pullctictl pull
    推送镜像docker/nerdctl  pushctr image push
    登录或在容器内部执行命令docker/nerdctl  execcrictl exec
    清空不用的容器docker/nerdctl image prunecrictl rmi --prune
    登录镜像仓库docker/nerdctl  login
    查看网络情况docker/nerdctl  network ls
    查看数据卷情况docker/nerdctl   volume ls

     

    由于 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 客户端工具 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 使用 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 支持构建镜像

    1. buildkit GitHub 地址:
    2. 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
    13. systemctl daemon-reload
    14. systemctl enable buildkit --now

    四、实战操作

    1)修改 containerd 配置文件

    配置如下:

    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"]
    15. #重新加载配置
    16. systemctl daemon-reload
    17. #重启containerd
    18. 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

     不想-u user:password 每次必须使用 ctr pull/ctr push, 可以使用nerdctl 。

    3)镜像构建

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

    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

    开始将镜像推送到 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用户名及密码

     搜集自网络

  • 相关阅读:
    LyScript 内存扫描与查壳实现
    【ROS入门】使用 ROS 话题(Topic)机制实现消息发布与订阅及launch文件的封装
    设计模式之单例模式
    HttpServletRequest和HttpServletResponse
    Python万圣节蝙蝠
    Centos一键安装、切换各版本JDK
    数据库系统原理与应用教程(073)—— MySQL 练习题:操作题 131-140(十七):综合练习
    Spring框架系列(12) - Spring AOP实现原理详解之JDK代理实现
    Flink算子通用状态应用测试样例
    Mendeley教程(3)引用各种文献
  • 原文地址:https://blog.csdn.net/qq_34777982/article/details/126652195