K8s 弃用 Docker!一文介绍 containerd ctr、crictl 使用

containerd 是一个高级容器运行时,又名 容器管理器。简单来说,它是一个守护进程,在单个主机上管理完整的容器生命周期:创建、启动、停止容器、拉取和存储镜像、配置挂载、网络等。

containerd 旨在轻松嵌入到更大的系统中。Docker 在底层使用 containerd 来运行容器。Kubernetes 可以通过 CRI 使用 containerd 来管理单个节点上的容器。但是较小的项目也可以从与 containerd 的轻松集成中受益——例如,faasd 使用 containerd(我们需要更多的 d!)在独立服务器上启动一个服务。

K8s 弃用 Docker!一文介绍 containerd ctr、crictl 使用_第1张图片

但是,以编程方式使用 containerd 并不是唯一的选择。它还可以通过可用客户端之一从命令行使用。由此产生的容器 UX 可能不像 docker 客户端提供的那样全面和用户友好,但它仍然是有用的,例如,用于调试或学习目的。

K8s 弃用 Docker!一文介绍 containerd ctr、crictl 使用_第2张图片

如何在 ctr 中使用 containerd

ctr 是作为 containerd 项目的一部分提供的命令行客户端。如果您在机器上运行了 containerd,则 ctr 二进制文件很可能也在那里。

该 ctr 界面 与 Docker CLI 不兼容,乍一看,可能看起来不那么用户友好。显然,它的主要受众是测试守护进程的容器开发人员。但是,由于它是最接近实际 containerd API 的东西,因此它可以作为一种很好的探索手段——通过检查可用命令,您可以大致了解 containerd 可以做什么和不能做什么。

ctr 也非常适合学习的能力低级别的使用人员,因为 ctr + containerd 是更接近实际的容器比 docker + dockerd。

使用 ctr 处理容器镜像

拉取镜像,似乎是必需和完全合规的,但是你不能忽略注册表或标签部分:

$ ctr images pull docker.io/library/nginx:1.21
$ ctr images pull docker.io/kennethreitz/httpbin:latest
$ ctr images pull docker.io/kennethreitz/httpbin:latest
$ ctr images pull quay.io/quay/redis:latest

要列出本地镜像,可以使用:

$ ctr images ls

令人惊讶的是,containerd 不提供开箱即用的镜像构建支持。但是 containerd 经常被更高级别的工具用来构建镜像。

ctr 您可以导入使用 docker build 或其他 OCI 兼容软件构建的现有镜像,而不是使用构建镜像:

$ docker build -t my-app .
$ docker save -o my-app.tar my-app

$ ctr images import my-app.tar

使用 ctr,您还可以学习和探索下挂载镜像:

$ mkdir /tmp/httpbin
$ ctr images mount docker.io/kennethreitz/httpbin:latest /tmp/httpbin

$ ls -l /tmp/httpbin/
total 80
drwxr-xr-x 2 root root 4096 Oct 18  2018 bin
drwxr-xr-x 2 root root 4096 Apr 24  2018 boot
drwxr-xr-x 4 root root 4096 Oct 18  2018 dev
drwxr-xr-x 1 root root 4096 Oct 24  2018 etc
drwxr-xr-x 2 root root 4096 Apr 24  2018 home
drwxr-xr-x 3 root root 4096 Oct 24  2018 httpbin
...

$ ctr images unmount /tmp/httpbin

要使用删除镜像 ctr,请运行:

$ ctr images remove docker.io/library/nginx:1.21

使用 ctr 处理容器

你可以运行一个容器用ctr run image-ref container-id。例如:

$ ctr run --rm -t docker.io/library/debian:latest cont1

请注意,ctr 与用户友好地 docker run 为您生成唯一容器 ID 不同,您必须自己提供唯一容器 ID。该 ctr run 命令还只支持一些熟悉的 docker run 标志:--env,-t,--tty,-d,--detach,--rm等,但没有端口指定或自动重启容器--restart=always

与镜像类似,您可以使用以下命令列出现有容器:

$ ctr containers ls

有趣的是,该 ctr run 命令实际上是快捷方式ctr container create + ctr task start:

$ ctr container create -t docker.io/library/nginx:latest nginx_1
$ ctr container ls
CONTAINER    IMAGE                              RUNTIME
nginx_1      docker.io/library/nginx:latest     io.containerd.runc.v2

$ ctr task ls
TASK    PID    STATUS        # Empty!

$ ctr task start -d nginx_1  # -d for --detach
$ ctr task list
TASK     PID      STATUS
nginx_1  10074    RUNNING

我喜欢 container 和 task 子命令的这种分离,因为它反映了 OCI 容器经常被遗忘的性质。尽管普遍认为容器不是进程 -容器是资源被隔离和执行受限制的进程。

使用 ctr task attach,您可以重新连接到在容器内运行的现有任务的 stdio 流:

$ ctr task attach nginx_1
2021/09/12 15:42:20 [notice] 1#1: using the "epoll" event method
2021/09/12 15:42:20 [notice] 1#1: nginx/1.21.3
2021/09/12 15:42:20 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/09/12 15:42:20 [notice] 1#1: OS: Linux 4.19.0-17-amd64
2021/09/12 15:42:20 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1024:1024
2021/09/12 15:42:20 [notice] 1#1: start worker processes
2021/09/12 15:42:20 [notice] 1#1: start worker process 31
...

与 docker 非常相似,您可以在现有容器中执行命令:

$ ctr task exec -t --exec-id bash_1 nginx_1 bash

# From inside the container:
$ root@host:/# curl 127.0.0.1:80



Welcome to nginx!