Containerd

基本概念

  • namespace
  • image
  • container
  • task
  • content
  • leases
  • snapshot
  • plugin

https://containerd.io/scope/#scope 可以看到 containerd 的功能规划。

进程结构

  • containerd 创建子进程 containerd-shim-runc-v2
    • 注意 containerd-shim-runc-v2 的父进程是 PID 1,这是为了防止 containerd 崩溃时,不影响容器。
    • containerd-shim-runc-v2 会监控容器进程,并上报信息给 containerd
  • containerd-shim-runc-v2 创建子进程 runc
  • runc 创建子进程:容器进程。容器进程运行后,runc 进程退出,容器进程由 containerd-shim-runc-v2 接管。

config.toml

containerd 的配置文件路径默认是 /etc/containerd/config.toml。 如果这个文件没有,可以自己创建。containerd config default | sudo tee /etc/containerd/config.toml

目录结构和配置具体见 https://github.com/containerd/containerd/blob/main/docs/ops.md

镜像加速

修改 config.toml 配置文件。

下面这种写法已废弃。

[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
    endpoint = ["http://local-registry-mirror"]

(顺便吐槽 TOML 语法,在深度嵌套的情况下,冗余字段太多了)

应当使用这种写法:

首先创建文件,比如如果要加速 docker.io 下的镜像,就得创建目录:

/etc/containerd/certs.d
└── docker.io
    └── hosts.toml
cat <<EOF > /etc/containerd/certs.d/docker.io/hosts.toml
server = "https://docker.io"

[host."https://dockerproxy.com"]
  capabilities = ["pull", "resolve"]
EOF

具体配置详见 https://github.com/containerd/containerd/blob/main/docs/cri/config.md#registry-configuration

镜像站详见 https://tools.adoyle.me/docker/#%E9%95%9C%E5%83%8F%E5%8A%A0%E9%80%9F

然后重启 containerd 使之生效。

rootless containerd

crictl

crictl 是遵循 CRI 接口规范的 kubelet 专用 CLI 工具。用来检查和管理 kubelet 节点上的容器运行时和镜像。

ctr

ctr 是 containerd 的客户端 CLI,类似简单版的 docker 客户端。

ctr 命名空间

# ctr 用 namespace 分离数据,一般来说 docker 对应 `moby`,k8s 对应 `k8s.io`,buildkit 对应 `buildkit`。
$ ctr ns ls
NAME LABELS
buildkit
k8s.io
moby

所有 ctr 一般都要带上 -n <namespace> 指定命名空间,否则用的是 default 命名空间,通常这个命名空间都没有东西。

If you do not provide a namespace, ctr client commands will all use the default namespace, which is simply named “default”.

https://github.com/containerd/containerd/blob/main/docs/namespaces.md#inspecting-namespaces

ctr 基本操作

# 等价于 docker ps
$ ctr -n moby containers ls
CONTAINER                                                           IMAGE    RUNTIME
49b6578cad79f499f14006847befc34949739ff191e05511c364ce040864eeb1    -        io.containerd.runc.v2

# 等价于 docker images。但一般来说是空的,因为 docker images 元数据都存在 docker 的 data 目录,不在 containerd 的目录下。
$ ctr -n moby images ls
REF TYPE DIGEST SIZE PLATFORMS LABELS

# k8s 直接使用 containerd,所以能看到镜像列表
$ ctr -n k8s.io images ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
docker.io/rancher/pause:3.6 application/vnd.docker.distribution.manifest.list.v2+json sha256:036d575e82945c112ef84e4585caff3648322a2f9ed4c3a6ce409dd10abc4f34 292.4 KiB linux/amd64,linux/s390x,windows/amd64 io.cri-containerd.image=managed

# 列出镜像和容器等内容。这里的 DIGEST 对应 docker image 的 RepoDigests
$ ctr -n moby content ls
DIGEST                                                                  SIZE    AGE             LABELS
sha256:036d575e82945c112ef84e4585caff3648322a2f9ed4c3a6ce409dd10abc4f34 1.452kB 2 hours         -
sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300 1.638kB 7 days          -
sha256:239a084766f3ebab94cba271f15bb0d4a93a6727bf8aa7f8e80eb5ebe0ea8166 1.076kB 7 days          -
sha256:3532a0050f8ec628e5d8dc9b16d8d6f97204d6893bb271063aa24edf1f6fc9cc 1.047kB 24 hours        -
sha256:396663e3d1c6102ea20893bf62a4693177dbe6b7463b961c56e6b62f81078070 4.501kB 7 days          -
sha256:58a917928b05ecfd19725325e1a5e0ed82994636114cab97b5fdb7fa8b431f06 946B    7 days          -
sha256:63a01e508ada5a123942b5afe24105d738f98ce543381ff48b1f9f905c22845e 1.159kB 2 hours         -
sha256:74bf6fc6be13c4ec53a86a5acf9fdbc6787b176db0693659ad6ac89f115e182c 526B    2 hours         -
sha256:87e303efe2f359ff82a6a61f4015c5f1cb5b49f6d679e34c9eb36fc0db5c6adb 740B    7 days          -
sha256:a2ec07de39cf5efd201ceb04403e1762ea296fb1c5d4b7e2175c11c8bf0b7f71 1.638kB 7 days          -
sha256:cffc8dd2df93619abeecc219fec2f2070a130cb26698a1bbea65ee002ccec432 736B    24 hours        -
sha256:d73ca8aeb30461ac010b03e9759b98e86bda9898ca5f6ec9a14bc3193de1a2c4 1.862kB 7 days          -
sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3 528B    7 days          -

用 ctr 停止容器

ctr container 只有 rm 命令,没有 stop 命令。

要停止容器需要执行 ctr task kill

# 查看运行中的 task
$ ctr -n k8s.io task ls
TASK                                                                PID       STATUS
33c2291ab2ab21829cf4ad55bebcb03ca841f1b6577de2d314f577c5aa573722    141842    RUNNING
368fb09b4b9a65251179fec90274ca81cf76673283c46aef73fa2b9ce74f2510    142118    RUNNING
0afb12de38d45f0f8e03594f1158a80f5928da3c52d423357c4209997d67e0b9    141807    RUNNING
1f1ba56a4808cbd05c0f06a4f14a34ef27f39a2e5cbb4e0101911686908de61d    141991    RUNNING
6af20e392355c2f0bd87d96c9f6dfa703cd8bbdb27dbf59bd3a2d963dbd9c5ae    143557    RUNNING
1e691ddb33b8812ae746e8554b1762bb3b52c247026f0eb15310510c8ce7e083    143641    RUNNING
12f4fd075298343e6c8e77caf47c2d36658cf2da02754269fc2250a7502c1f03    143672    RUNNING
d2e59bc8c827ae168669194324b901925267822999e5d64e9fcfcf64f2fd99ed    143508    RUNNING
b675f8032f31d6c5be35e98ce19c28527817d7c9f05cf7aba554d879f7628694    141990    RUNNING
78aa82b621abdb886616b47b24c82973db404f279f5f65fb0edda2f1abd62fb4    143594    RUNNING
dbe515f07196c27624aa19dc60585a5972de9d9380c1c65717e55e60cfc7d8d2    142114    RUNNING

# 停止所有 task,即向容器发送 SIGTERM 信号
$ ctr -n k8s.io task ls -q | xargs -n 1 ctr -n k8s.io task kill

# 对于 kill 不掉的进程,可以试试发送 SIGKILL 信号
$ ctr -n k8s.io task ls -q | xargs -n 1 ctr -n k8s.io task kill --signal SIGKILL

# 彻底删除容器
$ ctr -n k8s.io c ls -q | xargs -n 1 ctr -n k8s.io c rm

ctr shell 自动补全

见 https://github.com/containerd/containerd/tree/main/contrib/autocomplete