目录

容器 | Containerd 命令行工具的使用

1. 工具介绍

Containerd 不支持 docker API 和 docker CLI,但是 containerd 可以通过以下这几种命令实现类似的功能。这几种命令跟 containerd 的交互如下所示:

1.1. ctr

这个是 containerd 官方的命令行工具,功能相对简单,但是拉取镜像和创建容器等基础功能都有。

需要注意的是: ctr 支持选择 namespace,这个 namespace 不是 kubernetes 中的 namespace,而是 containerd 中的 namespace,不过这两种 namespace 在概念上是差不多的。一个 namespace 中镜像、容器等资源,在另一个 namespace 中是看不到的。

默认情况下操作的 都是 default namespace 中的容器和镜像资源,kubernetes 集群中的容器、镜像等资源都放置在 k8s.io 这个 namespace 中。

我们可以使用 -n namespace 来指定操作的是哪个 namespace,也可以使用 ctr namespace ls 查看有哪些 namespace。比如,加上 -n k8s.io 选项之后就可以查看 kubernetes 中的容器和镜像资源了。

1.2. crictl

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。

1.3. 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

2. 工具使用

2.1. 使用例子

2.1.1. 查看镜像

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 查看默认 namespace 中的镜像
ctr image ls

# 指定 namespace 为 k8s.io,表示操作的是 kubernetes 集群中的镜像资源
ctr -n k8s.io image ls


# nerdctl 查看镜像
nerdctl images


# 查看 kubernetes 中的镜像
crictl image ls

2.1.2. 拉取镜像

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 拉取镜像,ctr 拉取时需要指定全路径
ctr image pull docker.io/library/nginx:latest

# 遇到 `http: server gave HTTP response to HTTPS client` 问题时,使用 --plain-http
ctr image pull registry-internal.oecp.aliyuncs.com:5000/oecp/busybox:stable --plain-http

# 指定 namespace 为 k8s.io,表示操作的是 kubernetes 集群中的镜像资源
ctr -n k8s.io image pull docker.io/library/nginx:latest


# 不需要指定全路径,会拉取 docker.io/library/nginx:latest 这个镜像
nerdctl image pull nginx

# 遇到 `http: server gave HTTP response to HTTPS client` 问题时,使用 --insecure-registry
nerdctl --insecure-registry image pull registry-internal.oecp.aliyuncs.com:5000/oecp/busybox:stable


# 拉取镜像,会拉取 docker.io/library/nginx:latest 这个镜像
crictl pull nginx

2.1.3. 推送镜像

同 pull

2.1.4. 删除镜像

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# ctr 删除 docker.io/library/nginx:latest 这个镜像
ctr image rm docker.io/library/nginx:latest


# nerdctl 删除 nginx 镜像,删除的是 docker.io/library/nginx:latest 这个镜像
# 同 nerdctl rmi nginx
nerdctl image rm nginx


# crictl 删除 nginx 镜像,删除的是 docker.io/library/nginx:latest 这个镜像
crictl rmi nginx

2.1.5. 查看容器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# ctr 查看容器,无 -a 选项
# 这里的 contaienr 和 task 是有区别的:
# 1. container 对象是指包含了一个容器所需要的资源及配置的数据结构,并没有处于运行状态,是一个静态容器。
#    这个时候 namespaces(containerd 中的,非 kubernetes 中的)、rootfs 和容器的配置都已经初始化成功了。
# 2. task 代表任务的意思,是 container 对象运行起来之后的表示。
#		 ctr task start CONTAINER_NAME 会真正启动一个容器。
# 容器真正 run 起来之后,会存在 container 和 task 两个对象!
# 查看 container 对象
ctr container ls
# 查看 task 对象,可以看到运行的状态
ctr task ls


# nerdctl 查看容器,-a 是指查看所有状态
nerdctl container ls
nerdctl ps -a


# crictl 查看容器,-a 是指查看所有状态
crictl ps
crictl ps -a

2.1.6. 启动容器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 1. 先创建名为 demo_container 的 container 对象
ctr container create docker.io/library/nginx:latest demo_container
# 2. 再紧接着执行 ctr task start 才会真正启动一个容器,container 对象只是一个静态的数据结构。-d 同 docker 中的 -d
ctr task start -d demo_container

# 效果同上,相同将上面两个步骤合为一步,直接启动一个真正的容器,也会有 container 和 task 两个对象
ctr run -d docker.io/library/nginx:latest demo_container


# nerdctl 启动容器,默认使用的镜像是 docker.io/library/nginx:latest,同 docker 的使用
nerdctl run -d --name demo_nginx nginx 


# crictl 无法直接创建一个容器,需要在 sandbox 中创建容器
crictl run container-config.[json|yaml] pod-config.[json|yaml]

2.1.7. 删除容器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 1. 先 kill 掉 task 对象
ctr task kill demo_container
# 2. 再 rm 掉 container 对象
ctr container rm demo_container


# nerdctl 的使用同 docker
# 1. 先停止掉 container
# nerdctl stop demo_nginx 也可
nerdctl container stop demo_nginx

# 2. rm 掉 container
# nerdctl rm demo_nginx 也可
nerdctl container rm demo_nginx


# crictl 停止、删除容器
crictl stop CONTAINER-ID
crictl rm CONTAINER-ID

2.1.8. crictl 启动 Pod

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ cat sandbox-config.json
{
    "metadata": {
        "name": "nginx-sandbox",
        "namespace": "default",
        "attempt": 1,
        "uid": "hdishd83djaidwnduwk28bcsb"
    },
    "linux": {
    }
}

$ crictl runp sandbox-config.json
e1c83b0b8d481d4af8ba98d5f7812577fc175a37b10dc824335951f52addbb4e

2.1.9. crictl 启动容器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ cat container-config.json
{
  "metadata": {
      "name": "busybox"
  },
  "image":{
      "image": "busybox"
  },
  "command": [
      "top"
  ],
  "linux": {
  }
}

$ crictl create e1c83 container-config.json sandbox-config.json
0a2c761303163f2acaaeaee07d2ba143ee4cea7e3bde3d32190e2a36525c8a05
$ crictl ps -a
CONTAINER ID        IMAGE               CREATED             STATE               NAME                ATTEMPT
0a2c761303163       docker.io/busybox   2 hours ago         CONTAINER_CREATED   busybox             0
$ crictl start 0a2c
0a2c761303163f2acaaeaee07d2ba143ee4cea7e3bde3d32190e2a36525c8a05
$ crictl ps
CONTAINER ID        IMAGE               CREATED             STATE               NAME                ATTEMPT
0a2c761303163       docker.io/busybox   2 hours ago         CONTAINER_RUNNING   busybox             0

2.2. 使用对比图

ctr 或者 nerdctl 中假如没有指定 -n k8s.io 则表示查看非 kubernetes 中的容器、镜像资源;

ctr 或者 nerdctl 中指定了 -n k8s.io 则表示查看 kubernetes 中的容器、镜像资源。

命令 Docker containerd
docker crictl ctr nerdctl
查看容器列表 docker ps crictl ps ctr c ls(查看非 kubernetes 中的容器)ctr -n k8s.io c ls(查看 kubernetes 集群中的容器) nerdctl ps(查看非 kubernetes 中的容器)nerdctl -n k8s.io ps(查看 kubernetes 集群中的容器)
查看容器详情 docker inspect crictl inspect ctr c info nerdctl inspect
查看容器日志 docker logs crictl logs nerdctl logs
容器内执行命令 docker exec crictl exec ctr t exec nerdctl exec
挂载容器 docker attach crictl attach ctr t attach
显示容器资源使用情况 docker stats crictl stats
创建容器 docker create crictl create ctr c create
启动容器 docker start crictl start ctr t start(请看使用例子) nerdctl start
运行容器 docker run crictl run ctr run nerdctl run
停止容器 docker stop crictl stop ctr t kill (请看使用例子) nerdctl stop
删除容器 docker rm crictl rm ctr c rm nerdctl rm
查看镜像列表 docker images crictl images ctr i ls nerdctl images
查看镜像详情 docker inspect crictl inspecti nerdctl inspect
拉取镜像 docker pull crictl pull ctr i pull(请看使用例子) nerdctl pull
推送镜像 docker push ctr i push(请看使用例子) nerdctl push
删除镜像 docker rmi crictl rmi ctr i rm nerdctl rmi
查看Pod列表 crictl pods
查看Pod详情 crictl inspectp
启动Pod crictl runp
停止Pod crictl stopp

2.3. 详细文档

nerdctl 官方文档:

https://github.com/containerd/nerdctl#command-reference

ctr 官方文档:

建议使用 ctr -h 查看

crictl 官方文档:

建议使用 crictl -h 查看

https://github.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md

https://kubernetes.io/zh/docs/tasks/debug-application-cluster/crictl/#docker-cli-%E5%92%8C-crictl-%E7%9A%84%E6%98%A0%E5%B0%84