1. 工具介绍
Containerd 不支持 docker API 和 docker CLI,但是 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. 查看镜像
# 查看默认 namespace 中的镜像
ctr image ls
# 指定 namespace 为 k8s.io,表示操作的是 kubernetes 集群中的镜像资源
ctr -n k8s.io image ls
# nerdctl 查看镜像
nerdctl images
# 查看 kubernetes 中的镜像
crictl image ls
2.1.2. 拉取镜像
# 拉取镜像,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. 删除镜像
# 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. 查看容器
# 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. 先创建名为 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. 先 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
$ 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 启动容器
$ 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-和-crictl-的映射