容器化环境中的容器操作工具

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