轻量级或工业级容器管理工具 Containerd

  • Containerd介绍

  1. 前言
  • 早在2016年3月,Docker 1.11的Docker Engine里就包含了containerd,而现在则是把containerd从Docker Engine里彻底剥离出来,作为一个独立的开源项目独立发展,目标是提供一个更加开放、稳定的容器运行基础设施。和原先包含在Docker Engine里containerd相比,独立的containerd将具有更多的功能,可以涵盖整个容器运行时管理的所有需求。
  • containerd并不是直接面向最终用户的,而是主要用于集成到更上层的系统里,比如Swarm, Kubernetes, Mesos等容器编排系统。
  • containerd以Daemon的形式运行在系统上,通过暴露底层的gRPC API,上层系统可以通过这些API管理机器上的容器。
  • 每个containerd只负责一台机器,Pull镜像,对容器的操作(启动、停止等),网络,存储都是由containerd完成。具体运行容器由runC负责,实际上只要是符合OCI规范的容器都可以支持。
  • 对于容器编排服务来说,运行时只需要使用containerd+runC,更加轻量,容易管理。
  • 独立之后containerd的特性演进可以和Docker Engine分开,专注容器运行时管理,可以更稳定。

  1. Containerd前世今生

2013年docker公司在推出docker产品后,由于其对全球技术产生了一定的影响力,Google公司明显感觉到自己公司内部所使用的Brog系统江湖地位受到的威胁,希望Docker公司能够与自己联合打造一款开源的容器运行时作为Docker核心依赖,但Docker公司拒绝了;接着Google公司联合RedHat、IBM等公司说服Docker公司把其容器核心技术libcontainer捐给中立社区(OCI,Open Container Intiative),并更名为runC。


为了进一步遏制Docker在未来技术市场影响力,避免在容器市场上Docker一家独大,Google公司带领导RedHat、IBM等成立了CNCF(Cloud Native Computing Fundation)基金会,即云原生计算基金会。CNCF的目标很明确,既然在容器应用领域无法与Docker相抗衡,那就做Google更有经验的技术市场------大规模容器编排应用场景,Google公司把自己内部使用的Brog系统开源------Kubernetes,也就是我们今天所说的云原生技术生态。

2016年Docker公司推出了Docker Swarm,意在一统Docker生态,让Docker既可以实现容器应用管理,也可以实现大规模容器编排,经过近1年左右时间的市场验证后,发现在容器编排方面无法独立抗衡kubernetes,所以Docker公司于2017年正式宣布原生支持Kubernetes,至此,Docker在大规模容器编排应用市场败下阵来,但是Docker依然不甘心失败,把Docker核心依赖Containerd捐给了CNCF,以此说明Docker依旧是一个PaaS平台。

2020年CNCF基金会宣布Kubernetes 1.20版本将不再仅支持Docker容器管理工具,此事的起因主要也与Docker捐给CNCF基金会的Containerd有关,早期为了实现Kubernetes能够使用Docker实现容器管理,专门在Kubernetes组件中集成一个shim(垫片)技术,用来将Kubernetes容器运行时接口(CRI,Container Runntime Interface)调用翻译成Docker的API,这样就可以很好地使用Docker了,但是随着Kubernetes在全球技术市场的广泛应用,有更多的容器管理工具的出现,它们都想能够借助于Kubernetes被用户所使用,所以就提出标准化容器运行时接口,只要适配了这个接口就可以集成到Kubernetes生态当中,所以Kubernetes取消了对shim的维护,并且由于Containerd技术的成功,可以实现无缝对接Kubernetes,所以接下来Kubernetes容器运行时的主角是Containerd。

  1. 容器及镜像操作命令简介

crictl是遵循CRI接口规范的一个命令行工具,通常用它来检查和管理kubelet节点上的容器运行时和镜像

ctr是containerd的一个客户端工具,

接下来就是crictl的的常见命令,其中能完全替代docker命令的参照下列表格

操作 crictl docker

查看运行容器 crictl ps docker ps

查看镜像 crictl images docker images

查看容器日志 crictl logs docker logs

登陆容器控制台 crictl exec docker exec

pull镜像 crictl pull docker pull

容器启动/停止 crictl start/stop docker start/stop

容器资源情况 crictl stats docker stats

可以看到crictl对容器生命周期的管理基本已经覆盖,不过在crictl我们不能完成操作也比较多,比如对镜像的管理就不属于它的管理范围。

这部分还得依靠ctr来实现,操作方式同样可以参照下表

操作 ctr docker

查看镜像 ctr images ls docker images

镜像导入/导出 ctr images import/export   docker load/save

镜像拉取/推送 ctr images pull/push docker pull/push

镜像tag ctr images tag docker tag

  • Containerd安装

课程操作系统环境为rocky9.2

2.1 YUM方式安装

2.1.1 获取YUM源

获取阿里云YUM源
# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

containerd没有独立的yum源,docker-ce源中包含containerd

查看YUM源中Containerd软件
# dnf list | grep containerd
containerd.io.x86_64                                 1.7.19-3.1.el9                      docker-ce-stable

2.1.2 使用yum命令安装

安装Containerd.io软件,即可安装Containerd
# dnf -y install containerd.io

2.1.3 验证安装及启动服务

使用rpm -qa命令查看是否安装
# rpm -qa | grep containerd
containerd.io-1.7.19-3.1.el9.x86_64

设置containerd服务启动及开机自启动
# systemctl enable containerd
# systemctl start containerd

查看containerd服务启动状态
# systemctl status containerd
     Loaded: loaded (/usr/lib/systemd/system/containerd.service; enabled; preset: disabled)

     Active: active (running) since Thu 2024-08-08 00:23:30 CST; 10s ago

       Docs: https://containerd.io

    Process: 1160 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)

   Main PID: 1162 (containerd)

      Tasks: 9

     Memory: 17.1M

        CPU: 94ms

     CGroup: /system.slice/containerd.service

             └─1162 /usr/bin/containerd

           ......

2.1.4 验证可用性

安装Containerd时ctr命令亦可使用,ctr命令主要用于管理容器及容器镜像等。
使用ctr命令查看Containerd客户端及服务端相关信息。
# ctr version
Client:

  Version:  1.7.19

  Revision: 2bf793ef6dc9a18e00cb12efb64355c2c9d5eb41

  Go version: go1.21.12

Server:

  Version:  1.7.19

  Revision: 2bf793ef6dc9a18e00cb12efb64355c2c9d5eb41

  UUID: b8c923f7-a2ff-42fc-b748-f6c6cb22d496

  • Containerd容器镜像管理

3.1 Containerd容器镜像管理命令

  • docker使用docker images命令管理镜像
  • 单机containerd使用ctr images命令管理镜像,containerd本身的CLI
  • k8s中containerd使用crictl images命令管理镜像,Kubernetes社区的专用CLI工具

获取命令帮助
# ctr --help
NAME:

   ctr -

        __

  _____/ /______

 / ___/ __/ ___/

/ /__/ /_/ /

\___/\__/_/

containerd CLI

USAGE:

   ctr [global options] command [command options] [arguments...]

VERSION:

   1.7.19

DESCRIPTION:

ctr is an unsupported debug and administrative client for interacting

with the containerd daemon. Because it is unsupported, the commands,

options, and operations are not guaranteed to be backward compatible or

stable from release to release of the containerd project.

COMMANDS:

   plugins, plugin            Provides information about containerd plugins

   version                    Print the client and server versions

   containers, c, container   Manage containers

   content                    Manage content

   events, event              Display containerd events

   images, image, i           Manage images

   leases                     Manage leases

   namespaces, namespace, ns  Manage namespaces

   pprof                      Provide golang pprof outputs for containerd

   run                        Run a container

   snapshots, snapshot        Manage snapshots

   tasks, t, task             Manage tasks

   install                    Install a new package

   oci                        OCI tools

   sandboxes, sandbox, sb, s  Manage sandboxes

   info                       Print the server info

   deprecations

   shim                       Interact with a shim directly

   help, h                    Shows a list of commands or help for one command

GLOBAL OPTIONS:

   --debug                      Enable debug output in logs

   --address value, -a value    Address for containerd's GRPC server (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]

   --timeout value              Total timeout for ctr commands (default: 0s)

   --connect-timeout value      Timeout for connecting to containerd (default: 0s)

   --namespace value, -n value  Namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE]

   --help, -h                   show help

   --version, -v                print the version

获取命令帮助
# ctr images
NAME:
   ctr images - manage images

USAGE:
   ctr images command [command options] [arguments...]

COMMANDS:
   check                    check existing images to ensure all content is available locally
   export                   export images
   import                   import images
   list, ls                 list images known to containerd
   mount                    mount an image to a target path
   unmount                  unmount the image from the target
   pull                     pull an image from a remote
   push                     push an image to a remote
   delete, del, remove, rm  remove one or more images by reference
   tag                      tag an image
   label                    set and clear labels for an image
   convert                  convert an image

OPTIONS:
   --help, -h  show help

3.2 查看镜像

# ctr images ls
REF TYPE DIGEST SIZE PLATFORMS LABELS

3.3 下载镜像

containerd支持oci标准的镜像,所以可以直接使用docker官方或dockerfile构建的镜像

# 编辑 /etc/containerd/config.toml 文件,添加以下内容

添加docker hub镜像源:

[plugins]

  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]

endpoint = ["https://registry-1.docker.io"]

。。。

# ctr i pull --all-platforms docker.io/library/nginx:1.24

# ctr i pull --platform linux/amd64 docker.io/library/nginx:1.24

说明:

--platform linux/amd64 指定系统平台,也可以使用--all-platforms指定所有平台镜像,不加可自动识别。

这里ctr命令pull镜像时,不能直接把镜像名字写成“nginx:1.24”,需要加上镜像源才行

查看已下载容器镜像


# ctr images ls
REF                            TYPE                                    DIGEST                                                                  SIZE     PLATFORMS                                                                                                               LABELS

docker.io/library/nginx:1.20 application/vnd.oci.image.index.v1+json sha256:5ed8fcc66f4ed123c1b2560ed708dc148755b6e4cbd8b943fab094f2c6bfa91e 69.0 MiB linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/mips64le,linux/ppc64le,linux/s390x,unknown/unknown -

注:下面是对每一部分的解释:

- docker.io/library/nginx:1.24:这是镜像的完整名称,包括了注册服务器地址(docker.io)、镜像仓库(library/nginx)以及镜像标签(latest)。latest 标签通常表示该镜像的最新版本。

- application/vnd.oci.image.index.v1+json:这是镜像的类型,表明这是一个符合 OCI(Open Container Initiative)标准的镜像索引文件,格式为 JSON。

- sha256:5ed8fcc66f4ed123c1b2560ed708dc148755b6e4cbd8b943fab094f2c6bfa91e:这是镜像内容的 SHA256 哈希值,用于确保镜像的完整性和验证镜像是否被篡改。

- 69.0 MiB:表示这个镜像的大小为 69.0 兆字节(MiB)。

- linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/mips64le,linux/ppc64le,linux/s390x,unknown/unknown:列出了这个镜像支持的平台架构。这意味着这个镜像包含了多个平台的版本,可以在多种不同的 CPU 架构上运行,包括:

  - linux/386:Linux 操作系统,386 架构。

  - linux/amd64:Linux 操作系统,AMD64(x86_64)架构。

  - linux/arm/v5:Linux 操作系统,ARMv5 架构。

  - linux/arm/v7:Linux 操作系统,ARMv7 架构。

  - linux/arm64/v8:Linux 操作系统,ARM64v8 架构。

  - linux/mips64le:Linux 操作系统,MIPS64 架构,小端模式。

  - linux/ppc64le:Linux 操作系统,PowerPC 64 位小端架构。

  - linux/s390x:Linux 操作系统,IBM S390x 架构。

  - unknown/unknown:表示未知或不特定的平台。

这行信息表明,这个 nginx:1.20 镜像是一个多平台镜像,可以在多种不同的操作系统和架构上运行。这对于需要在多种环境中部署应用的场景非常有用。

3.4 镜像挂载方便查看镜像中包含的内容。

把已下载的容器镜像挂载至当前文件系统
[root@localhost ~]# ctr images mount docker.io/library/nginx:1.24 /mnt

[root@localhost ~]# ls /mnt
bin  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

卸载
# umount /mnt

3.5 镜像导出

# ctr i export --platform linux/amd64 nginx.tar docker.io/library/nginx:1.24

查看已导出容器镜像
# ls
nginx.tar
 

3.6 镜像删除

删除指定容器镜像
# ctr image rm docker.io/library/nginx:1.24

再次查看容器镜像
# ctr images ls

3.7 镜像导入

复制镜像备份文件nginx1u20.tar到本地

# ctr i import  nginx1u20.tar

3.8 添加镜像tag

# ctr images tag docker.io/library/nginx:1.20 nginx:1.20

修改后对容器镜像做检查比对
# ctr images check
REF                            TYPE                                                      DIGEST                                                                  STATUS         SIZE            UNPACKED
docker.io/library/nginx:1.20 application/vnd.docker.distribution.manifest.list.v2+json sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3 complete (7/7) 9.7 MiB/9.7 MiB true

nginx:1.20                   application/vnd.docker.distribution.manifest.list.v2+json sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3 complete (7/7) 9.7 MiB/9.7 MiB true

  • Containerd容器管理

4.1 获取命令帮助

4.1.1 获取ctr命令帮助

[root@localhost ~]# ctr --help
COMMANDS:
   plugins, plugin            provides information about containerd plugins
   version                    print the client and server versions
   containers, c, container   manage containers
   content                    manage content
   events, event              display containerd events
   images, image, i           manage images
   leases                     manage leases
   namespaces, namespace, ns  manage namespaces
   pprof                      provide golang pprof outputs for containerd
   run                        run a container
   snapshots, snapshot        manage snapshots
   tasks, t, task             manage tasks
   install                    install a new package
   oci                        OCI tools
   shim                       interact with a shim directly
   help, h                    Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug                      enable debug output in logs
   --address value, -a value    address for containerd's GRPC server (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]
   --timeout value              total timeout for ctr commands (default: 0s)
   --connect-timeout value      timeout for connecting to containerd (default: 0s)
   --namespace value, -n value  namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE]
   --help, -h                   show help
   --version, -v                print the version

4.1.2 获取创建静态容器命令帮助

# ctr container

说明:

使用“ctr container create令创建容器后,容器并没有处于运行状态,其只是一个静态的容器。这个 container 对象只是包含了运行一个容器所需的资源及配置的数据结构,例如: namespaces、rootfs 和容器的配置都已经初始化成功了,只是用户进程(本案例为nginx)还没有启动。需要使用ctr tasks令才能获取一个动态容器。

4.1.3 获取动态容器命令帮助

# ctr run

说明:
使用ctr run令可以创建一个静态容器并使其运行。一步到位运行容器。

4.2 查看容器

container表示静态容器,可用c缩写代表container

# ctr container ls
CONTAINER    IMAGE    RUNTIME

# ctr c ls
CONTAINER    IMAGE    RUNTIME

4.3 查看任务

task表示容器里跑的进程, 可用t缩写代表task

# ctr task ls
TASK    PID    STATUS

 或

# ctr t ls
TASK    PID    STATUS

4.4 创建静态容器

# ctr c create docker.io/library/nginx:1.20 nginx1

# ctr container ls
CONTAINER    IMAGE                             RUNTIME
nginx1       docker.io/library/nginx:1.20    io.containerd.runc.v2

查看容器详细信息
# ctr container info nginx1

4.5 静态容器启动为动态容器

启动task,即表时在容器中运行了进程,即为动态容器。
# ctr task start -d nginx1

说明:
-d表示daemon或者后台的意思,否则会卡住终端

查看容器所在宿主机进程,是以宿主机进程的方式存在的。
# ctr task ls
TASK      PID     STATUS
nginx1    3395    RUNNING

查看容器的进程(都是物理机的进程)
# ctr task ps nginx1
PID     INFO
3395    -
3434    -

物理机查看到相应的进程
# ps -ef | grep 3395
root       3395   3375  0 19:16 ?        00:00:00 nginx: master process nginx -g daemon off;
101        3434   3395  0 19:16 ?        00:00:00 nginx: worker process

4.6 进入容器操作

# ctr task exec --exec-id 1 -t nginx1 /bin/sh


ifconfig 查看网卡信息
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

curl 127.0.0.1 

访问本地提供的web服务

说明:
为exec进程设定一个id,可以随意输入,只要保证唯一即可,也可使用$RANDOM变量。

4.7 直接运行一个动态容器

# ctr run -d --net-host docker.io/library/nginx:1.20 nginx2
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/

说明:
* -d 代表dameon,后台运行
* --net-host 代表容器的IP就是宿主机的IP(相当于docker里的host类型网络)

查看已运行容器
# ctr container ls
CONTAINER    IMAGE                             RUNTIME
nginx2       docker.io/library/nginx:1.20    io.containerd.runc.v2

查看已运行容器中运行的进程,既tasks
# ctr tasks ls
TASK      PID     STATUS
nginx2    4061    RUNNING

进入容器
# ctr task exec --exec-id 1 -t nginx2 /bin/sh

/ # ifconfig
ens160    Link encap:Ethernet  HWaddr 00:0C:29:BE:42:28

          inet addr:192.168.10.11  Bcast:192.168.10.255  Mask:255.255.255.0

          inet6 addr: fe80::20c:29ff:febe:4228/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:188350 errors:0 dropped:0 overruns:0 frame:0

          TX packets:81120 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:168226584 (160.4 MiB)  TX bytes:5173221 (4.9 MiB)

lo        Link encap:Local Loopback

          inet addr:127.0.0.1  Mask:255.0.0.0

          inet6 addr: ::1/128 Scope:Host

          UP LOOPBACK RUNNING  MTU:65536  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

为容器中运行的网站添加网站文件
/ # echo "nginx2" > /usr/share/nginx/html/index.html
/ # exit

在宿主机上访问网站
[root@localhost ~]# curl 192.168.10.11
nginx2

4.8 暂停容器

查看容器状态
# ctr tasks ls
TASK      PID     STATUS
nginx2    4061    RUNNING

暂停容器
# ctr tasks pause nginx2

再次查看容器状态,看到其状态为PAUSED,表示停止。
# ctr tasks ls
TASK      PID     STATUS
nginx2    4061    PAUSED

[root@localhost ~]# curl http://192.168.10.11
在宿主机访问,发现不可以访问到网站

4.9 恢复容器

使用resume命令恢复容器
# ctr tasks resume nginx2

查看恢复后状态
# ctr tasks ls
TASK      PID     STATUS
nginx2    4061    RUNNING

在宿主机上访问容器中提供的服务
# curl http://192.168.10.11
nginx2

4.10 停止容器

使用kill命令停止容器中运行的进程,既为停止容器
# ctr tasks kill nginx2

查看容器停止后状态,STATUS为STOPPED
# ctr tasks ls
TASK      PID     STATUS
nginx1    3395    RUNNING
nginx2    4061    STOPPED

4.11 删除容器

# ctr tasks delete nginx2
必须先停止tasks或先删除task,再删除容器

查看静态容器,确认其还存在于系统中
# ctr container ls
CONTAINER    IMAGE                             RUNTIME
nginx2       docker.io/library/nginx:1.20    io.containerd.runc.v2

删除容器
# ctr container delete nginx2

  • Containerd使用私有容器镜像仓库 Harbor

5.1 Harbor准备按以前centos7.9上面的配置即可,IP地址192.168.10.14

5.2 配置Containerd使用Harbor仓库

下载容器镜像
# ctr images pull --platform linux/amd64 docker.io/library/nginx:1.20

说明:
* --platform linux/amd64 指定系统平台,也可以使用--all-platforms指定所有平台镜像,不加可自动识别。

查看已下载容器镜像
# ctr images ls

上传到Harbor library项目

重新生成新的tag
# ctr images tag docker.io/library/nginx:1.20 192.168.10.14/library/nginx:1.20
192.168.10.14/library/nginx:1.20

查看已生成容器镜像
# ctr images ls

推送容器镜像至Harbor
# ctr images push --platform linux/amd64 --plain-http -u admin:Harbor12345 192.168.10.14/library/nginx:1.20

注意:

如果出现如下错误,说明使用的harbor服务器需要域名解析,修改/etc/hosts即可                    

ctr: failed to authorize: failed to fetch oauth token: Post "http://harbor.test.com/service/token": read tcp 192.168.10.11:50196->69.167.164.199:80: read: connection reset by peer

说明:

* 先tag再push
* 因为我们harbor是http协议,不是https协议,所以需要加上--plain-http
* --user admin:Harbor12345定harbor的用户名与密码

删除本地已有镜像

# ctr images rm 192.168.10.14/library/nginx:1.20

下载已上传容器镜像
# ctr images pull --plain-http 192.168.10.14/library/nginx:1.20

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐