Kubernetes容器运行时弃用Docker转型Containerd

Kubernetes社区在2020年7月份发布的版本中已经开始了dockershim的移除计划,在1.20版本中将内置的dockershim进行分离,这个版本依旧还可以使用dockershim,但是在1.24中被删除。从1.24开始,大家需要使用其他受到支持的运行时选项(例如containerd或CRI-O);如果选择Docker Engine作为运行时,则需要使用cri-dockerd

文章目录

  • 容器进行时调用过程
  • Kubernetes 1.20 版本开始将弃用 Docker,是时候拥抱 Containerd 和 Podman 了!
  • CRI 详解
  • Containerd 发展史
  • 哪些容器运行时引擎支持CRI?
  • Containerd
  • Containerd 安装
  • 容器进行时调用过程

    Kubernetes容器运行时弃用Docker转型Containerd-每日运维
    起因

    圈子话题

    Kubernetes 1.20 版本开始将弃用 Docker,是时候拥抱 Containerd 和 Podman 了!

    Kubernetes容器运行时弃用Docker转型Containerd-每日运维
    当Docker要创建一个容器时,需要进行下面的步骤:
    1652382926896.png

  • Kubelet 通过CRI接口(gRPC)调用dockershim,请求创建一个容器。(CRI即容器运行时接口)
  • dockershim 收到请求后,转换成Docker Daemon能听懂的请求,发到Docker Daemon上请求创建容器。
  • Docker Daemon 早在1.12版本中就已经针对容器的操作转移到另外一个进程--containerd,因此Docker Daemon不会帮我们创建容器,而是要求containerd创建一个容器
  • Containerd收到请求后,并不会直接去操作容器,而是创建一个叫做containerd-shim的进程,让containerd-shim去操作容器。这是因为容器进程需要一个父进程来做收集状态,而加入这个父进程就是containerd,那每次containerd挂掉或者升级,整个宿主机上的容器都会退出。而引用containerd-shim就避免了这个问题 (containerd和shim并不是父子进程的关系)
  • OCI (Open Container Initiative,开放容器标准)。OCI执行namespace和cgroups,挂载root filesystem等操作,OCI参考RunC,containerd-shim在这一步调用RunC命令行来启动容器。实际上RunC就是一个二进制命令
  • runC启动完成后本身会直接退出,containerd-shim则会为容器进程的父进程,负责收集容器进程的状态,上报给containerd,并在容器中pid为1的进程退出后接管容器中的子进程进行清理,确保不会出现僵尸进程
  • OCI (Open Container Initiative,开放容器标准) runC实际上就是参考OCI实现,OCI实际上就是一个标准文档,主要规定了容器镜像的结构、以及容器需要接收那些操作指令,比如create、start、stop、delete等

    实际上我们是可以直接通过调用RunC来实现容器的创建,实际上RunC就是调用的我们内核来进行操作。但是我们直接调用Runc不是很方便,所以就有了OCI。不需要了解底层原理,也可以通过调用OCI来进行容器的创建
    containerd-shim则会为容器进程的父进程,负责收集容器进程的状态,上报给containerd,并在容器中pid为1的进程退出后接管容器中的子进程进行清理,确保不会出现僵尸进程

    [root@k8s-01 ~]# ps -ef|grep docker
    root      1100     1  1 Apr19 ?        05:43:15 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
    root      1425  1043  0 Apr19 ?        00:00:50 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/306ca6264fdd2bf673b65ba64ef91b9ec4357cb7a21545085199826ad991a3f1 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
    root      2120  1043  0 Apr19 ?        00:00:46 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/b608189a56350e04d20057f4b4158fe1ef0e6521ecae4030fdc5b03d7cee55c2 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
    root      2121  1043  0 Apr19 ?        00:00:51 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/847c04dc6aa2ba3e2df261629dee8ff934b27a548392d928c8737f29688ddd1f -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
    ...

    通过ps -ef过滤docker,我们可以看到docker中实际上就是通过containerd-shim来创建的

    containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/306ca6264fdd2bf673b65ba64ef91b9ec4357cb7a21545085199826ad991a3f1 -address /run/containerd/containerd.sock -containerd-binary

    containerd-shim垫片的主要作用是用于containerd与Runc的匹配CRI-shim垫片主要用于kubelet与containerd之间的匹配,并且两者之间没有任何关联

    CRI 详解

    为什么在Kubernetes 1.20之后不推荐使用docker了?可以继续往下看

    在Kubernetes早起的时候,Kubernetes为了支持Docker,通过硬编码的方式直接调用Docker API。后面随着Docker的不断发展以及Google的主导,出现了更多容器运行时可以使用,Kubernetes为了支持更多精简的容器运行时,google就和redhat主导推出了OCI标准,用于将Kubernetes平台和特定的容器运行时解耦
    CRI (Container Runtime Interface容器运行时接口)本质就是Kubernetes定义的一组与容器运行时进行交互的接口
    CRI实际上就是一组单纯的gRPC接口,核心有如下:

  • RuntimeService 对容器操作的接口,包括创建,启停容器等
  • ImageService 对镜像操作的接口,包括镜像的增删改查等
  • 可以通过kubelet中--container-runtime-endpoint和--image-service-endpoint来手动配置
    官方文档:https://kubernetes.io/zh/docs/concepts/architecture/cri/https://kubernetes.io/blog/2016/12/container-runtime-interface-cri-in-kubernetes/
    CRI大概通过了下面的几个项目构成了Kubernetes的Runtime生态

  • OCI Compatible: runC
  • CRI Compatible: Docker (借助dockershim),containerd (借助CRI-containerd)
  • 由于早期Kubernetes在市场没有主导地位,有一些容器运行时可能不会自身实现CRI接口,于是就有了shim,一个shim的职责就是作为适配器,将各种容器运行时的本身的接口适配到Kubernetes的CRI接口上

    1652383957048.png

    cri-runtime主要为了取消docker

    cri-runtime和oci-runtime 容器运行时实际上调用步骤如下

    Orchestration API -> Container API(cri-runtime) -> Kernel API(oci-runtime)

    Kubelet通过gRPC 框架与容器运行时或shim进行通信,其中 kubelet 作为客户端,CRI shim(也可能是容器运行时本身)

    Containerd 发展史

    在Containerd 1.0中,对CRI的适配通过了一个单独的进程CRI-containerd来完成
    Kubernetes容器运行时弃用Docker转型Containerd-每日运维
    containerd 1.1中,砍掉了CRI-containerd这个进程,直接把适配逻辑作为插件放进了containerd主进程中Kubernetes容器运行时弃用Docker转型Containerd-每日运维
    containerd 1.1中做的事情,实际上Kubernetes社区做了一个更漂亮的cri-o,兼容CRI和OCIKubernetes容器运行时弃用Docker转型Containerd-每日运维
    Containerd与Docker区别?

    实际上containerd只是一个精简版docker,为了更好的支持Kubernetes而已

    1651115028474.png

    哪些容器运行时引擎支持CRI?

    容器运行时
    Kubernetes 平台中的支持
    优点
    缺点
    Containerd谷歌 Kubernetes 引擎、IBM Kubernetes 服务、阿里巴巴经过大规模测试,用于所有 Docker 容器。比 Docker 使用更少的内存和 CPU。支持 Linux 和 Windows没有 Docker API 套接字。缺少 Docker 方便的 CLI 工具。
    CRI-O红帽 OpenShift,SUSE 容器即服务轻量级,Kubernetes 所需的所有功能,仅此而已。类似 UNIX 的关注点分离(客户端、注册表、构建)主要在RedHat平台内使用不易安装在非RedHat操作系统上仅在Windows Server2019及更高版本中支持
    Kata Containers开放堆栈提供基于 QEMUI 的完全虚拟化改进的安全性与 Docker、CRI-O、containerd 和 Firecracker 集成支持 ARM、x86_64、AMD64更高的资源利用率不适合轻量级容器用例
    AWS Firecracker所有 AWS 服务可通过直接 API 或使用 seccomp jailer 的 containerdTight 内核访问来访问新项目,不如其他运行时成熟需要更多手动步骤,开发人员体验仍在不断变化

    通过下图,我们可以看到这3个的区别,目前Kubernetes官网已经支持containerd、CRI-o容器运行时支持
    1651133795024.png

    Containerd

    早期Containerd是在Docker Engine中,目前将containerd从Docker中拆分出来,作为一个独立的开源项目,目标是提供一个更加开放、稳定的容器运行基础设施。分离出来的containerd将具有更多的功能,覆盖整个容器运行时的所有需求,提供更强大的支持
    Containerd是一个工业级标准的容器运行时,它强调简单性、可移植性

  • [x] 管理容器的生命周期 (从create到delete)
  • [x] 拉取/推送镜像容器
  • [x] 存储管理
  • [ ] 调用runc运行容器
  • [ ] 管理容器网络接口
  • Containerd 架构
    服务端通过 unix domain socket 暴露低层的 gRPC API 接口出去,客户端通过这些 API 管理节点上的容器,每个containerd只负责一台机器,Pull镜像,对容器的操作(启动、停止等),网络,存储都是由containerd完成。具体运行容器由runc负责,实际上只要是符合OCI规范的容器都可以支持
    Kubernetes容器运行时弃用Docker转型Containerd-每日运维
    为了解耦,containerd 将系统划分成了不同的组件,每个组件都由一个或多个模块协作完成(Core 部分),每一种类型的模块都以插件的形式集成到 Containerd 中,而且插件之间是相互依赖的,例如,上图中的每一个长虚线的方框都表示一种类型的插件,包括 Service Plugin、Metadata Plugin、GC Plugin、Runtime Plugin 等,其中 Service Plugin 又会依赖 Metadata Plugin、GC Plugin 和 Runtime Plugin。每一个小方框都表示一个细分的插件,例如 Metadata Plugin 依赖 Containers Plugin、Content Plugin 等
    Content Plugin: 提供对镜像中可寻址内容的访问,所有不可变的内容都被存储在这里。Snapshot Plugin: 用来管理容器镜像的文件系统快照,镜像中的每一层都会被解压成文件系统快照,类似于 Docker 中的 graphdriver
    对于K8s来说,实际需要Containerd即可,中间的垫片(shim)是完全可以省略,减少调用链
    1652386081939.png

    Containerd已经将shim集成到kubelet中,减少了shim,但是如果我们使用containerd,那么将无法使用docker ps或者docker exec命令来获取容器。可以使用docker pull和docker build命令来构建镜像

    Kubernetes容器运行时弃用Docker转型Containerd-每日运维
    参考文档:https://www.cnblogs.com/charlieroro/articles/10998203.htmlhttps://www.qikqiak.com/post/containerd-usage/#:~:text=containerd%20%E6%98%AF%E4%B8%80%E4%B8%AA%E5%B7%A5%E4%B8%9A%E7%BA%A7,%E5%8F%8A%E5%AE%B9%E5%99%A8%E6%95%B0%E6%8D%AE%E7%9A%84%E5%AD%98%E5%82%A8%EF%BC%89

    Containerd 安装

    Kubernetes社区在2020年7月份发布的版本中已经开始了dockershim的移除计划,在1.20版本中将内置的dockershim进行分离,这个版本依旧还可以使用dockershim,但是在1.24中被删除。从1.24开始,大家需要使用其他受到支持的运行时选项(例如containerd或CRI-O);如果您选择Docker Engine作为运行时,则需要使用cri-dockerd

    本次环境信息

    [root@ops ~]# cat /etc/redhat-release
    CentOS Linux release 7.4.1708 (Core)
    
    [root@ops ~]# uname -r
    3.10.0-693.el7.x86_64

    下载containerd
    github地址:https://containerd.io/downloads/
    Containerd安装我们使用1.6.1版本号

    containerd-1.6.1-linux-amd64.tar.gz 只包含containerdcri-containerd-cni-1.6.4-linux-amd64.tar.gz 包含containerd以及cri runc等相关工具包,建议下载本包

    #下载tar.gz包
    #containerd工具包,包含cri runc等
    https://github.com/containerd/containerd/releases/download/v1.6.4/cri-containerd-cni-1.6.4-linux-amd64.tar.gz
    
    #containerd包
    wget https://github.com/containerd/containerd/releases/download/v1.6.1/containerd-1.6.1-linux-amd64.tar.gz
    
    #备用下载地址
    https://d.frps.cn/file/kubernetes/containerd/cri-containerd-cni-1.6.4-linux-amd64.tar.gz
    https://d.frps.cn/file/kubernetes/containerd/containerd-1.6.1-linux-amd64.tar.gz

    工具包文件如下

    #cri-containerd-cni会将我们整个containerd相关的依赖都进行下载下来
    
    [root@ops containerd]# tar zxvf cri-containerd-cni-1.6.4-linux-amd64.tar.gz -C /   #我们直接让它给我们对应的目录给替换掉
    etc/
    etc/systemd/
    etc/systemd/system/
    etc/systemd/system/containerd.service
    etc/crictl.yaml
    etc/cni/
    etc/cni/net.d/
    etc/cni/net.d/10-containerd-net.conflist
    usr/
    usr/local/
    usr/local/sbin/
    usr/local/sbin/runc
    usr/local/bin/
    usr/local/bin/crictl
    usr/local/bin/ctd-decoder
    usr/local/bin/ctr
    usr/local/bin/containerd-shim
    usr/local/bin/containerd
    usr/local/bin/containerd-shim-runc-v1
    usr/local/bin/critest
    usr/local/bin/containerd-shim-runc-v2
    usr/local/bin/containerd-stress
    opt/
    opt/containerd/
    opt/containerd/cluster/
    opt/containerd/cluster/version
    opt/containerd/cluster/gce/
    opt/containerd/cluster/gce/cni.template
    opt/containerd/cluster/gce/env
    opt/containerd/cluster/gce/configure.sh
    opt/containerd/cluster/gce/cloud-init/
    opt/containerd/cluster/gce/cloud-init/node.yaml
    opt/containerd/cluster/gce/cloud-init/master.yaml
    opt/cni/
    opt/cni/bin/
    opt/cni/bin/firewall
    opt/cni/bin/portmap
    opt/cni/bin/host-local
    opt/cni/bin/ipvlan
    opt/cni/bin/host-device
    opt/cni/bin/sbr
    opt/cni/bin/vrf
    opt/cni/bin/static
    opt/cni/bin/tuning
    opt/cni/bin/bridge
    opt/cni/bin/macvlan
    opt/cni/bin/bandwidth
    opt/cni/bin/vlan
    opt/cni/bin/dhcp
    opt/cni/bin/loopback
    opt/cni/bin/ptp

    上面的文件都是二进制文件,直接移动到对应的目录并配置好环境变量就可以进行使用了。

    升级libseccomp,libseccomp需要高于2.4版本

    #卸载原来的
    [i4t@web01 ~]# rpm -qa | grep libseccomp
    libseccomp-devel-2.3.1-4.el7.x86_64
    libseccomp-2.3.1-4.el7.x86_64
    [i4t@web01 ~]# rpm -e libseccomp-devel-2.3.1-4.el7.x86_64 --nodeps
    [i4t@web01 ~]# rpm -e libseccomp-2.3.1-4.el7.x86_64 --nodeps
    
    #下载高于2.4以上的包
    [i4t@web01 ~]# wget http://rpmfind.net/linux/centos/8-stream/BaseOS/x86_64/os/Packages/libseccomp-2.5.1-1.el8.x86_64.rpm
    
    #安装
    [i4t@web01 ~]# rpm -ivh libseccomp-2.5.1-1.el8.x86_64.rpm 
    warning: libseccomp-2.5.1-1.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
    Preparing...                          ################################# [100%]
    Updating / installing...
       1:libseccomp-2.5.1-1.el8           ################################# [100%]
    
    #查看当前版本
    [root@web01 ~]# rpm -qa | grep libseccomp
    libseccomp-2.5.1-1.el8.x86_64

    如果我们机器上通过yum安装docker了,可以用下面的命令进行卸载

    sudo yum remove docker 
                      docker-client 
                      docker-client-latest 
                      docker-common 
                      docker-latest 
                      docker-latest-logrotate 
                      docker-logrotate 
                      docker-engine

    接下来我们为Containerd设置一个配置文件

    #创建配置文件目录
    [root@web01 ~]# mkdir /etc/containerd
    
    #生成默认配置文件
    [root@web01 ~]# containerd config default > /etc/containerd/config.toml
    
    #--config,-c可以在启动守护程序时更改此路径
    #配置文件的默认路径位于/etc/containerd/config.toml

    Containerd官方操作手册
    默认cri-containerd-cni包中会有containerd启动脚本,我们已经解压到对应的目录,可以直接调用启动

    [root@web01 ~]# systemctl enable containerd --now   
    Created symlink from /etc/systemd/system/multi-user.target.wants/containerd.service to /etc/systemd/system/containerd.service.
    
    [root@web01 ~]# systemctl status containerd   #查看containerd启动状态
    ● containerd.service - containerd container runtime
       Loaded: loaded (/etc/systemd/system/containerd.service; enabled; vendor preset: disabled)
       Active: active (running) since Thu 2022-05-12 22:59:19 EDT; 3s ago
         Docs: https://containerd.io
      Process: 30048 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
     Main PID: 30050 (containerd)
       Memory: 24.5M
       CGroup: /system.slice/containerd.service
               └─30050 /usr/local/bin/containerd
    
    May 12 22:59:19 web01 containerd[30050]: time="2022-05-12T22:59:19.153514446-04:00" level=info msg="Get image filesystem path "/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs""
    May 12 22:59:19 web01 containerd[30050]: time="2022-05-12T22:59:19.154085898-04:00" level=info msg="Start subscribing containerd event"
    May 12 22:59:19 web01 containerd[30050]: time="2022-05-12T22:59:19.154137039-04:00" level=info msg="Start recovering state"
    May 12 22:59:19 web01 containerd[30050]: time="2022-05-12T22:59:19.154230615-04:00" level=info msg="Start event monitor"
    May 12 22:59:19 web01 containerd[30050]: time="2022-05-12T22:59:19.154276701-04:00" level=info msg="Start snapshots syncer"
    May 12 22:59:19 web01 containerd[30050]: time="2022-05-12T22:59:19.154299287-04:00" level=info msg="Start cni network conf syncer for default"
    May 12 22:59:19 web01 containerd[30050]: time="2022-05-12T22:59:19.154316094-04:00" level=info msg="Start streaming server"
    May 12 22:59:19 web01 containerd[30050]: time="2022-05-12T22:59:19.154675632-04:00" level=info msg=serving... address=/run/containerd/containerd.sock.ttrpc
    May 12 22:59:19 web01 containerd[30050]: time="2022-05-12T22:59:19.154755704-04:00" level=info msg=serving... address=/run/containerd/containerd.sock
    May 12 22:59:19 web01 containerd[30050]: time="2022-05-12T22:59:19.155220379-04:00" level=info msg="containerd successfully booted in 0.027654s"

    containerd配置每个顶级配置块的命名都是plugin."io.containerd.xxx.vxx.xxx"这种形式,其实每个顶级配置块都代表一个插件,其中io.containerd.xxx.vxx表示插件类型,vxx后面的xxx表示 插件ID。并且可以通过命令ctr查看到

    ...
    [plugins]
    
      [plugins."io.containerd.gc.v1.scheduler"]
        deletion_threshold = 0
        mutation_threshold = 100
        pause_threshold = 0.02
        schedule_delay = "0s"
        startup_delay = "100ms"
    
      [plugins."io.containerd.grpc.v1.cri"]
        device_ownership_from_security_context = false
        disable_apparmor = false
        disable_cgroup = false
        disable_hugetlb_controller = true
        disable_proc_mount = false
    ...
    
    [root@web01 ~]# ctr plugin ls
    TYPE                                  ID                       PLATFORMS      STATUS    
    io.containerd.content.v1              content                  -              ok        
    io.containerd.snapshotter.v1          aufs                     linux/amd64    skip      
    io.containerd.snapshotter.v1          btrfs                    linux/amd64    skip      
    io.containerd.snapshotter.v1          devmapper                linux/amd64    error   
    ...

    containerd配置文件详解https://www.cnblogs.com/FengGeBlog/p/15057399.html
    (可以设置containerd中的一些相关参数)
    Containerd属于cs架构需要安装ctr,通过crt进行管理控制;ctr实际上就是containerd的客户端工具

    ctr -->Containerd-->RunC

    ctr在我们解压包中已经附带了,直接可以使用

    [root@web01 ~]# ctr version
    Client:     #ctr版本号
      Version:  v1.6.4
      Revision: 212e8b6fa2f44b9c21b2798135fc6fb7c53efc16
      Go version: go1.17.9
    
    Server:
      Version:  v1.6.4     #containerd版本号
      Revision: 212e8b6fa2f44b9c21b2798135fc6fb7c53efc16
      UUID: b376d7b6-c97e-4b39-8144-9624ade3ba84
    
    #可以使用下面命令查看containerd版本号
    [root@web01 ~]# containerd --version
    containerd github.com/containerd/containerd v1.6.4 212e8b6fa2f44b9c21b2798135fc6fb7c53efc16

    拉取镜像

    在containerd中拉取docker的相关镜像也需要补全

    [root@web01 ~]# ctr i pull docker.io/library/nginx:alpine --all-platforms
    docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++| 
    index-sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31:    exists         |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:1763babed2bf50e37dd065d287227c9066c8be5ec3c0caafb9a9eaa5bf6d934a: done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:efc09388b15fb423c402f0b8b28ca70c7fd20fe31f8d7531ae1896bbb4944999: exists         |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:1968f73dbbc39b1a32a71755552f195085f1d639e6e71d1639a47449ee5c0074: done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:152fd38e0474de5973743948275ca96c96634db454513357913cc9418de319bf: waiting        |--------------------------------------| 
    manifest-sha256:1746c349c5113b180cd0c2d5c0420c89563a65a5555655b5253cf0f2575a027c: done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:dbf24ebd77347ab1ab85469bc4248100e49916ca7612c13a48ace9d097ddea86: done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:134e4709956d97c3c6723f06294d2146e9e31586563872c82f9080b09dd3eb97: done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:4071be97c256d6f5ab0e05ebdebcfec3d0779a5e199ad0d71a5fccba4b3e2ce4:    exists         |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:5867cba5fcbd3ae827c5801e76d20e7dc91cbb626ac5c871ec6c4d04eb818b16:    exists         |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:4b639e65cb3ba47e77db93f93c6625a62ba1b9eec99160b254db380115ae009d:    exists         |++++++++++++++++++++++++++++++++++++++| 
    config-sha256:51696c87e77e4ff7a53af9be837f35d4eacdb47b4ca83ba5fd5e4b5101d98502:   exists         |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:061ed9e2b9762825b9869a899a696ce8b56e7e0ec1e1892b980969bf7bcda56a:    exists         |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:df9b9388f04ad6279a7410b85cedfdcb2208c0a003da7ab5613af71079148139:    exists         |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:bc19f3e8eeb1bb75268787f8689edec9a42deda5cdecdf2f95b3c6df8eb57a48:    exists         |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:7c96ccaee678fe6c901f93fa9aee2bdfd7aed78ad970e61c6fe17ec5242d6f63:    downloading    |--------------------------------------|    0.0 B/1.4 KiB 
    config-sha256:84f7fa8153d66e1a97aa567161d9fd0810d656036800b06f2225e2476ff82a67:   downloading    |--------------------------------------|    0.0 B/8.7 KiB 
    docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++| 
    index-sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31:    exists         |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:1763babed2bf50e37dd065d287227c9066c8be5ec3c0caafb9a9eaa5bf6d934a: done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:efc09388b15fb423c402f0b8b28ca70c7fd20fe31f8d7531ae1896bbb4944999: exists         |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:1968f73dbbc39b1a32a71755552f195085f1d639e6e71d1639a47449ee5c0074: done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:152fd38e0474de5973743948275ca96c96634db454513357913cc9418de319bf: waiting        |--------------------------------------| 
    manifest-sha256:1746c349c5113b180cd0c2d5c0420c89563a65a5555655b5253cf0f2575a027c: done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:dbf24ebd77347ab1ab85469bc4248100e49916ca7612c13a48ace9d097ddea86: done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:134e4709956d97c3c6723f06294d2146e9e31586563872c82f9080b09dd3eb97: done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:4071be97c256d6f5ab0e05ebdebcfec3d0779a5e199ad0d71a5fccba4b3e2ce4:    exists         |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:5867cba5fcbd3ae827c5801e76d20e7dc91cbb626ac5c871ec6c4d04eb818b16:    exists         |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:4b639e65cb3ba47e77db93f93c6625a62ba1b9eec99160b254db380115ae009d:    exists         |++++++++++++++++++++++++++++++++++++++| 
    config-sha256:51696c87e77e4ff7a53af9be837f35d4eacdb47b4ca83ba5fd5e4b5101d98502:   exists         |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:061ed9e2b9762825b9869a899a696ce8b56e7e0ec1e1892b980969bf7bcda56a:    exists         |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:df9b9388f04ad6279a7410b85cedfdcb2208c0a003da7ab5613af71079148139:    exists         |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:bc19f3e8eeb1bb75268787f8689edec9a42deda5cdecdf2f95b3c6df8eb57a48:    exists         |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:7c96ccaee678fe6c901f93fa9aee2bdfd7aed78ad970e61c6fe17ec5242d6f63:    downloading    |--------------------------------------|    0.0 B/1.4 KiB 
    config-sha256:84f7fa8153d66e1a97aa567161d9fd0810d656036800b06f2225e2476ff82a67:   downloading    |--------------------------------------|    0.0 B/8.7 KiB 
    docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++| 
    index-sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31:    exists         |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:1763babed2bf50e37dd065d287227c9066c8be5ec3c0caafb9a9eaa5bf6d934a: done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:efc09388b15fb423c402f0b8b28ca70c7fd20fe31f8d7531ae1896bbb4944999: exists         |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:1968f73dbbc39b1a32a71755552f195085f1d639e6e71d1639a47449ee5c0074: done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:152fd38e0474de5973743948275ca96c96634db454513357913cc9418de319bf: waiting        |--------------------------------------| 
    manifest-sha256:1746c349c5113b180cd0c2d5c0420c89563a65a5555655b5253cf0f2575a027c: done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:dbf24ebd77347ab1ab85469bc4248100e49916ca7612c13a48ace9d097ddea86: done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:134e4709956d97c3c6723f06294d2146e9e31586563872c82f9080b09dd3eb97: done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:4071be97c256d6f5ab0e05ebdebcfec3d0779a5e199ad0d71a5fccba4b   #nginx镜像需要写全
    docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++| 
    index-sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31:    done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:efc09388b15fb423c402f0b8b28ca70c7fd20fe31f8d7531ae1896bbb4944999: done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:4071be97c256d6f5ab0e05ebdebcfec3d0779a5e199ad0d71a5fccba4b3e2ce4:    done           |++++++++++++++++++++++++++++++++++++++| 
    config-sha256:51696c87e77e4ff7a53af9be837f35d4eacdb47b4ca83ba5fd5e4b5101d98502:   done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:df9b9388f04ad6279a7410b85cedfdcb2208c0a003da7ab5613af71079148139:    done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:5867cba5fcbd3ae827c5801e76d20e7dc91cbb626ac5c871ec6c4d04eb818b16:    done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:4b639e65cb3ba47e77db93f93c6625a62ba1b9eec99160b254db380115ae009d:    done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:061ed9e2b9762825b9869a899a696ce8b56e7e0ec1e1892b980969bf7bcda56a:    done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:bc19f3e8eeb1bb75268787f8689edec9a42deda5cdecdf2f95b3c6df8eb57a48:    done           |++++++++++++++++++++++++++++++++++++++| 
    elapsed: 10.1s                                                                    total:  9.7 Mi (983.4 KiB/s)                                     
    unpacking linux/amd64 sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31...
    done: 874.877199ms
    
    #例如我拉取自己的镜像
    [root@web01 ~]# ctr i pull docker.io/frps9/tools:SynologyNAS

    拉取镜像添加了--all-platforms会将所有平台都下载下来

    unpacking linux/amd64 sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31...
    unpacking linux/arm/v6 sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31...
    unpacking linux/arm/v7 sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31...
    unpacking linux/arm64/v8 sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31...
    unpacking linux/386 sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31...
    unpacking linux/ppc64le sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31...
    unpacking linux/s390x sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31...
    
    #否则默认下载当前平台

    并且containerd相比于docker , 多了namespace概念, 每个image和containe都会在各自的namespace下可见, 目前k8s会使用k8s.io作为命名空间,默认containerd会使用default

    [root@web01 ~]# ctr ns ls
    NAME    LABELS 
    default        
    [root@web01 ~]# ctr ns 
    NAME:
       ctr namespaces - manage namespaces
    
    USAGE:
       ctr namespaces command [command options] [arguments...]
    
    COMMANDS:
       create, c   create a new namespace
       list, ls    list namespaces
       remove, rm  remove one or more namespaces
       label       set and clear labels for a namespace
    
    OPTIONS:
       --help, -h  show help
    
    #同样containerd也支持标签

    查看当前所有namespace

    [root@web01 ~]# ctr ns ls
    NAME    LABELS 
    default        

    如果我们不指定namespace,默认就会使用default

    创建containerd namespace

    [root@web01 ~]# ctr ns create i4t
    [root@web01 ~]# ctr ns ls
    NAME    LABELS 
    default        
    i4t          
    
    #删除一样
    ctr ns delete [NameSpace]

    接下来我们所有的containerd中的操作,都可以添加-n ns_namespace指定到专属的命名空间中

    #我这里使用-n i4t 下载镜像进行测试,后续在ctr -n 指定命名空间即可
    #命名空间只如果不指定,默认是看不到,这点和k8s namespace作用相同
    [root@web01 ~]# ctr -n i4t i pull docker.io/library/nginx:alpine --all-platforms
    docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++| 
    index-sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31:    done           |++++++++++++++++++++++++++++++++++++++| 
    manifest-sha256:efc09388b15fb423c402f0b8b28ca70c7fd20fe31f8d7531ae1896bbb4944999: done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:4071be97c256d6f5ab0e05ebdebcfec3d0779a5e199ad0d71a5fccba4b3e2ce4:    done           |++++++++++++++++++++++++++++++++++++++| 
    config-sha256:51696c87e77e4ff7a53af9be837f35d4eacdb47b4ca83ba5fd5e4b5101d98502:   done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:df9b9388f04ad6279a7410b85cedfdcb2208c0a003da7ab5613af71079148139:    done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:4b639e65cb3ba47e77db93f93c6625a62ba1b9eec99160b254db380115ae009d:    done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:5867cba5fcbd3ae827c5801e76d20e7dc91cbb626ac5c871ec6c4d04eb818b16:    done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:061ed9e2b9762825b9869a899a696ce8b56e7e0ec1e1892b980969bf7bcda56a:    done           |++++++++++++++++++++++++++++++++++++++| 
    layer-sha256:bc19f3e8eeb1bb75268787f8689edec9a42deda5cdecdf2f95b3c6df8eb57a48:    done           |++++++++++++++++++++++++++++++++++++++| 
    elapsed: 2.3 s                                                                    total:  3.1 Ki (1.4 KiB/s)                                       
    unpacking linux/amd64 sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31...
    done: 807.366874ms
    [root@web01 ~]# ctr -n i4t i ls -q
    docker.io/library/nginx:alpine

    查看镜像

    #查看镜像可以使用i或者image
    #-q设置只获取我们的名称
    
    [root@web01 ~]# ctr i ls
    REF                               TYPE                                                      DIGEST                                                                  SIZE      PLATFORMS                                                                                LABELS 
    docker.io/frps9/tools:SynologyNAS application/vnd.docker.distribution.manifest.v2+json      sha256:28e355e3ebe86c731af14bcf132543a23ff3dc3a34a3c830691ec59b65df21e6 341.7 MiB linux/amd64                                                                              -      
    docker.io/library/nginx:alpine    application/vnd.docker.distribution.manifest.list.v2+json sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31 9.7 MiB   linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -      
    
    [root@web01 ~]# ctr i ls -q
    docker.io/frps9/tools:SynologyNAS
    docker.io/library/nginx:alpine

    tag重新打标签

    #这里的tag基本上和docker命令方式相同
    [root@web01 ~]# ctr i tag docker.io/library/nginx:alpine docker.io/library/nginx:i4t
    docker.io/library/nginx:i4t
    
    [root@web01 ~]# ctr i ls -q
    docker.io/frps9/tools:SynologyNAS
    docker.io/library/nginx:alpine
    docker.io/library/nginx:i4t   #新增tag

    删除镜像

    #delete, del, remove, rm  remove one or more images by reference
    #以上的方法都可以进行删除
    [root@web01 ~]# ctr i ls -q
    docker.io/frps9/tools:SynologyNAS
    docker.io/library/nginx:alpine
    docker.io/library/nginx:i4t
    [root@web01 ~]# 
    [root@web01 ~]# 
    [root@web01 ~]# ctr i rm docker.io/frps9/tools:SynologyNAS
    docker.io/frps9/tools:SynologyNAS
    [root@web01 ~]# 
    [root@web01 ~]# ctr i ls -q
    docker.io/library/nginx:alpine
    docker.io/library/nginx:i4t

    mount镜像
    mount镜像实际上就是可以将我们镜像中的文件,挂载到宿主机的目录中去

    [root@web01 ~]# mkdir ctr_demo_nginx  #创建挂载目录
    [root@web01 ~]# ctr i ls -q         #查看镜像
    docker.io/library/nginx:alpine
    docker.io/library/nginx:i4t
    [root@web01 ~]# ctr i mount docker.io/library/nginx:alpine /root/ctr_demo_nginx  #执行挂载
    sha256:1380ce106a10fac3c312f83ddf8406d187d5c0dd567d9a2454abe6ba563114cd
    /root/ctr_demo_nginx
    [root@web01 ~]# ls /root/ctr_demo_nginx/    #查看挂载文件
    bin  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    

    mount参数系统为只读状态,只可以读取,不可以写入数据使用--rw Enable write support on the mount可以开启只读

    取消mount挂载

    #有mount,当然也有umount
    [root@web01 ~]# ctr i unmount /root/ctr_demo_nginx
    /root/ctr_demo_nginx
    [root@web01 ~]# 
    [root@web01 ~]# ls /root/ctr_demo_nginx/

    推送镜像

    ctr  i push -k docker.io/library/nginx:alpine
    #跳过ssl验证--skip-verify, -k     skip SSL certificate validation

    导出导入镜像

    #import #导入
    #export #导出
    #默认export导出的为OCI tar,只要我们容器支持OCI,基本上都是可以使用的
    #同时导出可以使用--platform导出其它平台的(例如arm)
    #--all-platforms为导出所有平台
    
    [root@web01 ~]# ctr i export --all-platforms nginx.tar docker.io/library/nginx:alpine
    
    # -all-platforms添不添加都可以
    # /root/nginx_alpine_1.tar为导出的文件名称
    # docker.io/xxx/xxx:alpine为镜像地址以及tag号
    
    [root@web01 ~]# ll /root/nginx_alpine_1.tar 
    -rw-r--r--. 1 root root 10184704 May 15 07:01 /root/nginx_alpine_1.tar
    [root@web01 ~]# 
    
    #导入
    [root@web01 tmp]# ctr i import nginx.tar 
    unpacking docker.io/library/nginx:alpine (sha256:5a0df7fb7c8c03e4158ae9974bfbd6a15da2bdfdeded4fb694367ec812325d31)...done
    [root@web01 tmp]# ctr i ls -q
    docker.io/library/nginx:alpine
    docker.io/library/nginx:i4t

    ctr不支持 build,commit 镜像

    创建容器

    #基本参数
    
    [root@web01 ~]# ctr c
    NAME:
       ctr containers - manage containers
    
    USAGE:
       ctr containers command [command options] [arguments...]
    
    COMMANDS:
       create                   create container
       delete, del, remove, rm  delete one or more existing containers
       info                     get info about a container
       list, ls                 list containers
       label                    set and clear labels for a container
       checkpoint               checkpoint a container
       restore                  restore a container from checkpoint
    
    OPTIONS:
       --help, -h  show help
    
    #创建容器可以使用的参数
    [root@web01 ~]# ctr c create -h
    NAME:
       ctr containers create - create container
    
    USAGE:
       ctr containers create [command options] [flags] Image|RootFS CONTAINER [COMMAND] [ARG...]
    
    OPTIONS:
       --snapshotter value               snapshotter name. Empty value stands for the default value. [$CONTAINERD_SNAPSHOTTER]
       --snapshotter-label value         labels added to the new snapshot for this container.
       --config value, -c value          path to the runtime-specific spec config file
       --cwd value                       specify the working directory of the process
       --env value                       specify additional container environment variables (e.g. FOO=bar)
       --env-file value                  specify additional container environment variables in a file(e.g. FOO=bar, one per line)
       --label value                     specify additional labels (e.g. foo=bar)
       --mount value                     specify additional container mount (e.g. type=bind,src=/tmp,dst=/host,options=rbind:ro)
       --net-host                        enable host networking for the container
       --privileged                      run privileged container
       --read-only                       set the containers filesystem as readonly
       --runtime value                   runtime name (default: "io.containerd.runc.v2")
       --runtime-config-path value       optional runtime config path
       --tty, -t                         allocate a TTY for the container
       --with-ns value                   specify existing Linux namespaces to join at container runtime (format '<nstype>:<path>')
       --pid-file value                  file path to write the task's pid
       --gpus value                      add gpus to the container
       --allow-new-privs                 turn off OCI spec's NoNewPrivileges feature flag
       --memory-limit value              memory limit (in bytes) for the container (default: 0)
       --device value                    file path to a device to add to the container; or a path to a directory tree of devices to add to the container
       --cap-add value                   add Linux capabilities (Set capabilities with 'CAP_' prefix)
       --cap-drop value                  drop Linux capabilities (Set capabilities with 'CAP_' prefix)
       --seccomp                         enable the default seccomp profile
       --seccomp-profile value           file path to custom seccomp profile. seccomp must be set to true, before using seccomp-profile
       --apparmor-default-profile value  enable AppArmor with the default profile with the specified name, e.g. "cri-containerd.apparmor.d"
       --apparmor-profile value          enable AppArmor with an existing custom profile
       --rdt-class value                 name of the RDT class to associate the container with. Specifies a Class of Service (CLOS) for cache and memory bandwidth management.
       --rootfs                          use custom rootfs that is not managed by containerd snapshotter
       --no-pivot                        disable use of pivot-root (linux only)
       --cpu-quota value                 Limit CPU CFS quota (default: -1)
       --cpu-period value                Limit CPU CFS period (default: 0)
       --rootfs-propagation value        set the propagation of the container rootfs

    这里我创建一个nginx容器

    [root@web01 ~]# ctr -n i4t  c create --net-host docker.io/library/nginx:alpine nginx 
    
    # -n 指定命名空间
    # c create 创建容器
    # --net-host 使用宿主机网络
    # docker.io/xx/xxx:xxx 镜像地址
    # nginx 容器名称
    
    [root@web01 ~]# ctr -n i4t c ls  #查看容器列表
    CONTAINER    IMAGE                             RUNTIME                  
    nginx        docker.io/library/nginx:alpine    io.containerd.runc.v2    
    
    [root@web01 ~]# ctr -n i4t c ls -q #只获取容器名称
    nginx

    可以通过info参数查看容器的相关信息

    [root@web01 ~]# ctr -n i4t c info nginx|less
    #info后面添加容器名称
    
    {
        "ID": "nginx",
        "Labels": {
            "io.containerd.image.config.stop-signal": "SIGQUIT",
            "maintainer": "NGINX Docker Maintainers u003cdocker-maint@nginx.comu003e"
        },
        "Image": "docker.io/library/nginx:alpine",
        "Runtime": {
            "Name": "io.containerd.runc.v2",
            "Options": {
                "type_url": "containerd.runc.v1.Options"
            }
        },
        "SnapshotKey": "nginx",
        "Snapshotter": "overlayfs",
        "CreatedAt": "2022-05-15T12:02:46.133798687Z",
        "UpdatedAt": "2022-05-15T12:02:46.133798687Z",
        "Extensions": null,
        "Spec": {
            "ociVersion": "1.0.2-dev",
            "process": {
                "user": {
                    "uid": 0,
                    "gid": 0,
                    "additionalGids": [
                        1,
                        2,
                        3,
                        4,
                        6,
                        10,
                        11,
                        20,
                        26,
                        27
                    ]
                },
                "args": [
                    "/docker-entrypoint.sh",
                    "nginx",
                    "-g",

    Task任务在containerd中有一个task任务的概念,刚刚我们使用containerd create创建的容器,这时候并没有running;在Docker中可以直接run容器,但是在containerd是需要先create在通过task启动容器。create 容器并不会启动容器,可以理解只是声明了一个container,并不会启动和执行相关操作

    在task我们也可以管理容器的网络,以及容器的监控等。实际上就是增强版的docker ps

    #可以通过下面的命令进行查看正在运行的容器
    
    [root@web01 ~]# ctr -n i4t task ls
    TASK    PID    STATUS    

    task可以操作的相关命令

    COMMANDS:
       attach                   attach to the IO of a running container
       checkpoint               checkpoint a container
       delete, del, remove, rm  delete one or more tasks
       exec                     execute additional processes in an existing container
       list, ls                 list tasks
       kill                     signal a container (default: SIGTERM)
       pause                    pause an existing container
       ps                       list processes for container
       resume                   resume a paused container
       start                    start a container that has been created
       metrics, metric          get a single data point of metrics for a task with the built-in Linux runtime

    使用task启动容器

    [root@web01 ~]# ctr -n i4t task start -d nginx  #-d后台运行
    
    #容器运行状态
    [root@web01 ~]# ctr -n i4t task ls
    TASK     PID     STATUS    
    nginx    1465    RUNNING

    现在我们通过ps -ef就可以看到进程了

    [root@web01 ~]# ps -ef|grep nginx
    root      1446     1  0 08:53 ?        00:00:00 /usr/local/bin/containerd-shim-runc-v2 -namespace i4t -id nginx -address /run/containerd/containerd.sock
    root      1465  1446  0 08:53 ?        00:00:00 nginx: master process nginx -g daemon off;
    101       1504  1465  0 08:54 ?        00:00:00 nginx: worker process
    101       1505  1465  0 08:54 ?        00:00:00 nginx: worker process
    101       1506  1465  0 08:54 ?        00:00:00 nginx: worker process
    101       1507  1465  0 08:54 ?        00:00:00 nginx: worker process
    root      1515  1287  0 08:59 pts/0    00:00:00 grep --color=auto nginx

    进入容器

    [root@web01 ~]# ctr -n i4t task ls  #查看当前运行容器
    TASK     PID     STATUS    
    nginx    1465    RUNNING
    
    [root@web01 ~]# ctr -n i4t task exec --exec-id 1 -t nginx sh  #进入容器
    
    #exec task进入容器操作
    #--exec-id 设置一个id,唯一即可
    #-t --tty为container分配一个tty
    #nginx 容器名称
    #sh && bash即可
    
    #进入容器内部和docker exec基本上相同
    [root@web01 ~]# ctr -n i4t task exec --exec-id 1 -t nginx sh
    / # 
    / # ps -ef|grep nginx
        1 root      0:00 nginx: master process nginx -g daemon off;
       32 nginx     0:00 nginx: worker process
       33 nginx     0:00 nginx: worker process
       34 nginx     0:00 nginx: worker process
       35 nginx     0:00 nginx: worker process
       69 root      0:00 grep nginx

    暂停容器

    [root@web01 ~]# ctr -n i4t task ls
    TASK     PID     STATUS    
    nginx    1465    RUNNING
    
    #停止容器
    [root@web01 ~]# ctr -n i4t task pause nginx
    #pause为停止容器
    
    #查看状态
    [root@web01 ~]# ctr -n i4t task ls
    TASK     PID     STATUS    
    nginx    1465    PAUSED

    有暂停容器当然也有恢复容器

    需要注意暂停和恢复容器不等于重启容器

    [root@web01 ~]# ctr -n i4t task ls
    TASK     PID     STATUS    
    nginx    1465    PAUSED
    [root@web01 ~]# 
    [root@web01 ~]# ctr -n i4t task resume nginx
    [root@web01 ~]# 
    [root@web01 ~]# ctr -n i4t task ls
    TASK     PID     STATUS    
    nginx    1465    RUNNING

    如果我们需要停止容器,只能通过kill来进行停止,然后在重新start;在containerd中没有stop和restart参数

    [root@web01 ~]# ctr -n i4t task kill nginx   #kill停止task任务
    [root@web01 ~]# ctr -n i4t task ls
    TASK     PID     STATUS    
    nginx    1465    STOPPED
    [root@web01 ~]# ctr -n i4t task rm nginx   #删除task任务
    [root@web01 ~]# ctr -n i4t task ls
    TASK    PID    STATUS    
    
    #删除task并不会删除container
    [root@web01 ~]# ctr -n i4t c ls
    CONTAINER    IMAGE                             RUNTIME                  
    nginx        docker.io/library/nginx:alpine    io.containerd.runc.v2   

    删除容器

    [root@web01 ~]#  ctr -n i4t c rm nginx
    
    #-n 指定命名空间
    #c rm代表删除容器
    #nginx 容器名称

    task还可以通过metrcis命令,获取到容器内部资源使用情况

    [root@web01 ~]# ctr -n i4t task ls
    TASK     PID     STATUS    
    nginx    2010    RUNNING
    [root@web01 ~]# ctr -n i4t task metrics nginx   #使用metrics查看资源使用情况
    ID       TIMESTAMP                                  
    nginx    2022-05-15 13:35:13.767932408 +0000 UTC    
    
    METRIC                   VALUE                                
    memory.usage_in_bytes    3788800                              
    memory.limit_in_bytes    9223372036854771712                  
    memory.stat.cache        24576                                
    cpuacct.usage            23007334                             
    cpuacct.usage_percpu     [7718201 3737243 3983818 7568072]    
    pids.current             5                                    
    pids.limit               0    

    task ps可以看到在宿主机上容器的进程

    [root@web01 ~]# ctr -n i4t task ls
    TASK     PID     STATUS    
    nginx    2010    RUNNING
    
    [root@web01 ~]# ctr -n i4t task ps nginx   #PID为宿主机上的PID
    PID     INFO
    2010    -
    2040    -
    2041    -
    2042    -
    2043    -
    [root@web01 ~]# ps -ef|grep 2010
    root      2010  1990  0 09:34 ?        00:00:00 nginx: master process nginx -g daemon off;
    101       2040  2010  0 09:34 ?        00:00:00 nginx: worker process
    101       2041  2010  0 09:34 ?        00:00:00 nginx: worker process
    101       2042  2010  0 09:34 ?        00:00:00 nginx: worker process
    101       2043  2010  0 09:34 ?        00:00:00 nginx: worker process
    root      2084  1287  0 09:36 pts/0    00:00:00 grep --color=auto 2010

    Docker ctr nerdctl命令直接的区别
    crictl是kubernetes cri-tools的一部分,是专门为kubernetes使用containerd而专门制作的,提供了Pod、容器和镜像等资源的管理命令。

    需要注意的是:使用其他非 kubernetes创建的容器、镜像,crictl是无法看到和调试的,比如说ctr run在未指定namespace情况下运行起来的容器就无法使用crictl看到。当然ctr可以使用-n k8s.io指定操作的namespace为 k8s.io,从而可以看到/操作kubernetes 集群中容器、镜像等资源。可以理解为:crictl 操作的时候指定了containerd 的namespace为k8s.io。

    nerdctl ctr功能简单,而且对已经习惯使用docker cli的人来说,ctr并不友好(比如无法像 docker cli 那样)。这个时候nerdctl就可以替代ctr了。nerdctl是一个与docker cli风格兼容的containerd的cli工具,并且已经被作为子项目加入了 containerd 项目中。从nerdctl 0.8开始,nerdctl直接兼容了docker compose的语法(不包含 swarm), 这很大程度上提高了直接将 containerd 作为本地开发、测试和单机容器部署使用的体验。
    需要注意的是:安装 nerdctl 之后,要想可以使用 nerdctl 还需要安装 CNI 相关工具和插件。containerd不包含网络功能的实现,想要实现端口映射这样的容器网络能力,需要额外安装 CNI 相关工具和插件。

    另外 nerdctl 也可以使用 -n 指定使用的 namespace。

     
    docker
    crictl
    ctr
    nerdctl
    查看容器列表docker pscrictl psctr c ls(查看非 kubernetes 中的容器)ctr -n k8s.io c ls(查看 kubernetes 集群中的容器)nerdctl ps(查看非 kubernetes 中的容器)nerdctl -n k8s.io ps(查看 kubernetes 集群中的容器)
    查看容器详情docker inspectcrictl inspectctr c infonerdctl inspect
    查看容器日志docker logscrictl logsnerdctl logs
    容器内执行命令docker execcrictl execctr t execnerdctl exec
    挂载容器docker attachcrictl attachctr t attach
    显示容器资源使用情况docker statscrictl statsctr task metrics
    创建容器docker createcrictl createctr c create
    启动容器docker startcrictl startctr t startnerdctl start
    运行容器docker runcrictl runctr runnerdctl run
    停止容器docker stopcrictl stopctr t killnerdctl stop
    删除容器docker rmcrictl rmctr c rmnerdctl rm
    查看镜像列表docker imagescrictl imagesctr i lsnerdctl images
    查看镜像详情docker inspectcrictl inspectinerdctl inspect
    拉取镜像docker pullcrictl pullctr i pullnerdctl pull
    推送镜像docker pushctr i pushnerdctl push
    删除镜像docker rmicrictl rmictr i rmnerdctl rmi
    查看Pod列表crictl pods
    查看Pod详情crictl inspectp
    启动Podcrictl runp
    停止Podcrictl stopp

    相关文章:

    1. Kubernetes 1.14 二进制集群安装
    2. Docker 镜像及Docker仓库配置 [四]
    3. Kubenetes 1.13.5 集群二进制安装
    4. Kuerbernetes 1.11 集群二进制安装