容器化环境中的容器操作工具
May 14, 2022
Containerd 不支持 docker API 和 docker CLI。containerd可以使用下述工具交互。
ctr
containerd 命令行工具。支持选择 namespace,这个 namespace 不是 kubernetes 中的 namespace,而是 containerd 中的 namespace。一个 namespace 中镜像、容器等资源,在另一个 namespace 中是看不到的。
默认情况下操作的 都是 default namespace 中的容器和镜像资源,kubernetes 集群中的容器、镜像等资源都放置在 k8s.io 这个 namespace 中。
可以使用 -n namespace
来指定 namespace,可以用 ctr namespace ls
查看有哪些 namespace。
crictl
crictl 是 kubernetes cri-tools 的一部分,专门为 kubernetes 使用 containerd 而制作的,提供了 Pod、容器和镜像等资源的管理命令。
crictl 操作的时候指定了 containerd 的 namespace 为 k8s.io。非 kubernetes 创建的容器、镜像,crictl 是无法看到的,比如说 ctr run 在未指定 namespace 情况下运行起来的容器就无法使用 crictl 看到。当然 ctr 可以使用 -n k8s.io
指定操作的 namespace 为 k8s.io,从而可以看到/操作 kubernetes 集群中容器、镜像等资源。
nerdctl
nerdctl 是一个与 docker cli 风格兼容的 containerd 的 cli 工具,已经被作为子项目加入了 containerd 项目。从 nerdctl 0.8 开始,nerdctl 直接兼容了 docker compose 的语法(不包含 swarm)。
安装 nerdctl 之后,要想可以使用 nerdctl 还需要安装 CNI 相关工具和插件。containerd 不包含网络功能的实现,想要实现端口映射这样的容器网络能力,需要额外安装 CNI 相关工具和插件。
nerdctl 也可以使用 -n
指定 namespace。
各个工具的用法
查看镜像
# 查看 default 取名空间中的镜像
ctr image ls
# 查看指定取名空间中的镜像,以取名空间 k8s.io 为例
ctr -n k8s.io image ls
# 查看镜像
nerdctl images
# 查看镜像(仅查看k8s.io取名空间中的镜像)
crictl image ls
拉取镜像
# 拉取镜像
# 使用ctr时,对于docker镜像仓库,需要指定完全限定的路径
ctr image pull docker.io/library/nginx:latest
# 拉取镜像
# 使用ctr时,对于仅仅使用http协议,即不安全的镜像,需要指定 `--plain-http` 开关
ctr image pull localhost:5000/busybox:stable --plain-http
# 拉取镜像,并存入 k8s.io 取名空间
ctr -n k8s.io image pull docker.io/library/nginx:latest
# 拉取镜像
# 和 docker 命令相同,省略前缀会默认拉去 docker.io 仓库
nerdctl image pull nginx
# 拉取镜像
# 使用 nerdctl 时,对于仅仅使用http协议,即不安全的镜像,需要指定 `--insecure-registry` 开关
nerdctl image pull localhost:5000/busybox:stable --insecure-registry
# 拉取镜像
# 和 docker 命令相同,省略前缀会默认拉去 docker.io 仓库
crictl pull nginx
推送镜像
# 推送镜像
# 使用ctr时,对于docker镜像仓库,需要指定完全限定的路径
ctr image push docker.io/library/nginx:latest
# 推送镜像
# 使用ctr时,对于仅仅使用http协议,即不安全的镜像,需要指定 `--plain-http` 开关
ctr image push localhost:5000/busybox:stable --plain-http
# 推送镜像,推送 k8s.io 取名空间中的镜像
ctr -n k8s.io image push docker.io/library/nginx:latest
# 推送镜像
# 和 docker 命令相同,省略前缀会默认拉去 docker.io 仓库
nerdctl image push nginx
# 推送镜像
# 使用 nerdctl 时,对于仅仅使用http协议,即不安全的镜像,需要指定 `--insecure-registry` 开关
nerdctl image push localhost:5000/busybox:stable --insecure-registry
# 推送镜像
# 和 docker 命令相同,省略前缀会默认拉去 docker.io 仓库
crictl push nginx
删除本地镜像
# 删除镜像
# ctr 需要指定完全限定的路径
ctr image rm docker.io/library/nginx:latest
# 删除镜像
nerdctl image rm nginx
# 删除镜像
nerdctl image rmi nginx
# 删除镜像
crictl rmi nginx
查看容器
# 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
启动容器
# 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]
删除容器
# 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
启动 Pod
$ cat sandbox-config.json
{
"metadata": {
"name": "nginx-sandbox",
"namespace": "default",
"attempt": 1,
"uid": "hdishd83djaidwnduwk28bcsb"
},
"linux": {
}
}
$ crictl runp sandbox-config.json
e1c83b0b8d481d4af8ba98d5f7812577fc175a37b10dc824335951f52addbb4e
启动容器
$ 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
ctr、crictl、nerdctl三者对照表
docker | ctr | crictl | nerdctl |
---|---|---|---|
默认命名空间 | - | default | k8s.io |
客户端命令 | docker | ctr | crictl |
容器列表 | docker ps |
ctr c ls ctl -n k8s.io c ls |
crictl ps |
审视容器 | docker inspect |
ctr c info |
crictl inspect |
查看容器日志 | docker logs |
- | crictl logs |
容器内执行命令 | docker exec |
ctr t exec |
crictl exec |
挂载容器 | docker attach |
ctr t attach |
crictl attach |
显示容器资源使用情况 | docker stats |
- | crictl stats |
创建容器 | docker create |
ctr c create |
crictl create |
启动容器 | docker start |
ctr t start |
crictl 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
| -
文档 | <docs.docker.com> | ctr -h
| crictl -h
| https://github.com/containerd/nerdctl#command-reference