docker · 2024-05-04

containers 使用基础 ctr 命令

一、docker、ctr、crictl 命令

ctr 是一个用于管理 containerd 的命令行工具,可以用它来打包、拉取、上传镜像。

ctr 是 containerd 的一个客户端工具;crictl 是遵循 CRI 接口规范的一个命令行工具。

docker 的数据目录默认是在 /var/lib/docker 目录下;而切换到 containerd 时,数据目录默认为 /var/lib/containerd。

从containerd的角度来看启动一个容器:

ctr cli ---grpc---> containerd ---exec---> containerd-shim-runc ---exec---> runc

从 containerd 作为 k8s 的容器运行时来看:

crictl 与 kubelet ---CRI---> containerd ---exec---> containerd-shim-runc ---exec---> runc

containerd 实现了 k8s 的 CRI 接口,提供容器运行时核心功能,如镜像管理、容器管理等,也就是说 containerd 同样是一个 k8s CRI 的实现。

docker ctr (containerd) crictl (kubernetes) 作用
docker ps ctr task ls/ctr container ls crictl ps 查看运行的容器
docker images ctr image ls crictl images 查看镜像
docker logs 无 crictl logs 查看容器日志
docker inspect ctr container info crictl inspect 查看容器数据信息
docker stats 无 crictl stats 查看容器资源
docker start/stop ctr task start/kill crictl start/stop 启动/关闭已有的容器
docker run ctr run 无 (最小单元为pod) 运行一个新的容器
docker tag ctr image tag 无 修改镜像标签
docker create ctr container create crictl create 创建一个新的容器
docker load ctr image import 无 导入镜像
docker save ctr image export 无 导出镜像
docker rm ctr container rm crictl rm 删除容器
docker rmi ctr image rm crictl rmi 删除镜像
docker pull ctr image pull ctictl pull 拉取镜像
docker push ctr image push 无 推送镜像
docker exec 无 crictl exec 在容器内部执行命令

解释一个概念 containers 和 task ,在 docker 里面 container 概念被弱化 ,将 containers 和 task 整在一起 形成了 docker 中的 container。

ctr 中 containers 是镜像实例化的一个虚拟环境,提供一个磁盘,模拟空间,就好比你电脑处于关机状态一样。

ctr 中 tasks 是将容器运行起来,电脑开机了 ,初始化进程等 ,task 就是的这么个形式。

二、安装启动 containerd

1.安装 containerd

root@ctr-1:~# apt install containerd -y
root@ctr-1:~# ctr -v
ctr github.com/containerd/containerd 1.7.2

2.启动 containerd

root@ctr-1:~# ctr version
Client:
  Version:  1.7.2
  Revision: 
  Go version: go1.20.3

ctr: failed to dial "/run/containerd/containerd.sock": context deadline exceeded: connection error: desc = "transport: error while dialing: dial unix:///run/containerd/containerd.sock: timeout"

ctr version 若出现 failed to dial "/run/containerd/containerd.sock",表示服务没有启动
执行 containerd 或 systemctl start containerd,启动服务

root@ctr-1:~# ctr version
Client:
  Version:  1.7.2
  Revision: 
  Go version: go1.20.3

Server:
  Version:  1.7.2
  Revision: 
  UUID: deed1033-a829-419b-b232-fa64b992b077

3.生成配置文件

若需要修改默认的配置文件,需把默认的配置写入到 /etc/containerd/config.toml

root@ctr-1:~# mkdir -p /etc/containerd/
root@ctr-1:~# containerd config default > /etc/containerd/config.toml

4.配置国内仓库

以下是 containerd 1.6 之后的配置

1) 修改 /etc/containerd/config.toml 中的 config_path

    [plugins."io.containerd.grpc.v1.cri".registry]
      config_path = "/etc/containerd/certs.d"

2) 创建配置文件

创建 /etc/containerd/certs.d/docker.io 和 hosts.toml 文件

root@ctr-1:/# mkdir -p /etc/containerd/certs.d/docker.io
root@ctr-1:/# touch /etc/containerd/certs.d/docker.io/hosts.toml
root@ctr-1:/etc/containerd/certs.d/docker.io# cat hosts.toml 
server = "https://docker.io"
[host."https://docker.m.daocloud.io"]
  capabilities = ["pull","resolve"]
  # skip_verify = true

3) 使用国内仓库

若要使用指定的仓库,拉取镜像时,需指定 --hosts-dir

ctr image pull docker.io/library/nginx:1.23.3 --hosts-dir /etc/containerd/certs.d   

5.拉取镜像

root@ctr-1:~# ctr image pull docker.io/library/nginx:1.23.3
docker.io/library/nginx:1.23.3: resolving      |--------------------------------------| 
elapsed: 0.4 s                  total:   0.0 B (0.0 B/s)                                         
INFO[0000] trying next host                              error="failed to do request: Head \"https://registry-1.docker.io/v2/library/nginx/manifests/1.23.3\": tls: failed to verify certificate: x509: certificate signed by unknown authority" host=registry-1.docker.io
ctr: failed to resolve reference "docker.io/library/nginx:1.23.3": failed to do request: Head "https://registry-1.docker.io/v2/library/nginx/manifests/1.23.3": tls: failed to verify certificate: x509: certificate signed by unknown authority

若出现 failed to verify certificate: x509,则需要安装 ca-certificates

root@ctr-1:~# apt install ca-certificates -y
root@ctr-1:~# ctr image pull docker.io/library/nginx:1.23.3
docker.io/library/nginx:1.23.3:                                                   resolved       |++++++++++++++++++++++++++++++++++++++| 
index-sha256:f4e3b6489888647ce1834b601c6c06b9f8c03dee6e097e13ed3e28c01ea3ac8c:    done           |++++++++++++++++++++++++++++++++++++++| 
...
layer-sha256:84181e80d10e844350789d3324e848cf728df4f3d0f6c978789dd489f493934a:    done           |++++++++++++++++++++++++++++++++++++++| 
elapsed: 12.3s                                                                    total:  54.0 M (4.4 MiB/s)    
root@ctr-1:~# ctr image list
REF                            TYPE                                                      DIGEST                                                                  SIZE     PLATFORMS                                                                                               LABELS 
docker.io/library/nginx:1.23.3 application/vnd.docker.distribution.manifest.list.v2+json sha256:f4e3b6489888647ce1834b601c6c06b9f8c03dee6e097e13ed3e28c01ea3ac8c 54.3 MiB linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/mips64le,linux/ppc64le,linux/s390x

三、ctr 命令操作镜像

1.拉取镜像

命令:

ctr images pull <image_name>

指定平台:

  • --all-platforms:所有平台(amd64 、arm、386 、ppc64le 等),不加的话下载当前平台架构
  • --platform:指定linux/amd64平台

例:

root@ctr-1:~# ctr image pull docker.io/library/nginx:1.23.3
docker.io/library/nginx:1.23.3:                                                   resolved       |++++++++++++++++++++++++++++++++++++++| 
index-sha256:f4e3b6489888647ce1834b601c6c06b9f8c03dee6e097e13ed3e28c01ea3ac8c:    done           |++++++++++++++++++++++++++++++++++++++| 
manifest-sha256:557c9ede65655e5a70e4a32f1651638ea3bfb0802edd982810884602f700ba25: done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:84181e80d10e844350789d3324e848cf728df4f3d0f6c978789dd489f493934a:    done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:d4ceccbfc2696101c94fbf2149036e4ff815e4723e518721ff85105ce5aa8afc:    done           |++++++++++++++++++++++++++++++++++++++| 
config-sha256:ac232364af842735579e922641ae2f67d5b8ea97df33a207c5ea05f60c63a92d:   done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:f1f26f5702560b7e591bef5c4d840f76a232bf13fd5aefc4e22077a1ae4440c7:    done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:1ff0f94a80076ab49af75159e23f062a30a75d333a8e9c021bf39669230afcfe:    done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:d776269cad101c9f8e33e2baa0a05993ed0786604d86ea525f62d5d7ae7b9540:    done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:e9427fcfa8642f8ddf5106f742a75eca0dbac676cf8145598623d04fa45dd74e:    done           |++++++++++++++++++++++++++++++++++++++| 
elapsed: 29.8s                                                                    total:  53.3 M (1.8 MiB/s)                                       
unpacking linux/amd64 sha256:f4e3b6489888647ce1834b601c6c06b9f8c03dee6e097e13ed3e28c01ea3ac8c...
done: 1.856878044s
ctr images pull --platform linux/arm docker.io/library/nginx:1.25-alpine

注意:containerd 支持 oci 标准的镜像,所以可以直接使用 docker 官方或 dockerfile 构建的镜像,需要注意的是,与 docker 不同,拉取镜像时要加上 docker.io/liarary

2.查看镜像

命令:

ctr images list
ctr i ls
ctr i ls -q
  • 查看镜像可以使用 i 简写或者image
  • -q 只打印镜像名称

例:

root@ctr-1:~# ctr images list
REF                            TYPE                                                      DIGEST                                                                  SIZE     PLATFORMS                                                                                               LABELS 
docker.io/library/nginx:1.23.3 application/vnd.docker.distribution.manifest.list.v2+json sha256:f4e3b6489888647ce1834b601c6c06b9f8c03dee6e097e13ed3e28c01ea3ac8c 54.3 MiB linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/mips64le,linux/ppc64le,linux/s390x - 
root@ctr-1:~# ctr i ls -q
docker.io/library/nginx:1.23.3

3.检测镜像

例:

root@ctr-1:~# ctr images check
REF                            TYPE                                                      DIGEST                                                                  STATUS         SIZE              UNPACKED 
docker.io/library/nginx:1.23.3 application/vnd.docker.distribution.manifest.list.v2+json sha256:f4e3b6489888647ce1834b601c6c06b9f8c03dee6e097e13ed3e28c01ea3ac8c complete (7/7) 54.3 MiB/54.3 MiB true

4.删除镜像

命令:

ctr images rm  <image_name>

例:

root@ctr-1:~# ctr images rm docker.io/library/nginx:1.25-alpine
docker.io/library/nginx:1.25-alpine

5.镜像打标签

命令:

ctr images tag <images_name> <new _image_name>

例:

ctr images tag docker.io/library/nginx:1.23.3 docker.io/activepirate/nginx:1.23.3

6.导入导出镜像

ctr image export <image_file_name> <image_name>
ctr images import <image_file_name>

7.挂载镜像

命令:

ctr images mount <image_name> <dir_path>
ctr images unmount <dir_path>

把已下载的容器镜像挂载至当前文件系统,是为了方便查看镜像中包含的内容

例:

root@ctr-1:~# ctr images mount docker.io/library/nginx:1.23.3 /root/tmp
sha256:31888883f307f2ea78ac1dd1abd26ddae38ebe9aacfbb0250995a636b8531d8f
/root/tmp
root@ctr-1:~# ls /root/tmp/
bin  boot  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@ctr-1:~# ctr images unmount /root/tmp/
/root/tmp/
root@ctr-1:~# ls -lh /root/tmp/
total 0

四、ctr 命令操作容器

通过 container create 命令创建的容器,并没有处于运行状态,只是一个静态的容器(仅仅只是一个创建容器的声明

1.查看容器

ctr containers list
ctr containers ls
ctr c ls

2.创建容器

ctr container create <image_name> <container_name>
  • –net-host: 主机网络

例:

ctr container create docker.io/library/nginx:1.23.3 nginx_1
ctr container create --net-host docker.io/library/nginx:1.23.3 nginx_

五、ctr 命令操作任务

1.开始任务

ctr task start -d <container_name>

例:

root@ctr-1:~# ctr task start -d nginx_1
root@ctr-1:~# ps -ef | grep nginx_1
root       22023       1  0 20:27 ?        00:00:01 /usr/bin/containerd-shim-runc-v2 -namespace default -id nginx_1 -address /run/containerd/containerd.sock

可以看出 containerd 中是存在 namespace 概念的,这样可以将不同业务和应用进行隔离

2.列出任务

命令用于管理容器中运行的任务

ctr tasks list
ctr t ls

例:

root@ctr-1:~# ctr tasks list
TASK       PID      STATUS
nginx_1    18895    RUNNING
root@ctr-1:~# ctr task ls -q
nginx_1

3.进入到容器

命令:

ctr task exec --exec-id <exec_id> -t <container_name> sh

注意必须要指定 --exec-id 参数,这个 id 可以随便写,只要唯一就行

例:

root@ctr-1:~# ctr tasks exec --exec-id $RANDOM -t busybox_1 sh
/ # ls
bin    dev    etc    home   lib    lib64  proc   root   run    sys    tmp    usr    var
/ # exit
root@ctr-1:~# ctr task exec --exec-id 0 -t nginx_1 sh
# ls
bin  boot  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

5.暂停任务

命令:

ctr task pause <container_name>

例:

root@ctr-1:~# ctr task pause nginx_1
root@ctr-1:~# ctr task ls
TASK       PID      STATUS
nginx_1    18895    PAUSED

6.恢复任务

命令:

ctr task resume <container_name>

例:

root@ctr-1:~# ctr task resume nginx_1
root@ctr-1:~# ctr task ls
TASK       PID      STATUS
nginx_1    18895    RUNNING

7.杀死任务

ctr 没有 stop 容器的功能,只能暂停或者杀死容器,杀死容器可以使用 task kill 命令

命令:

ctr task kill <container_name>

例:

root@ctr-1:~# ctr task kill nginx_1
root@ctr-1:~# ctr task kill -s 9 nginx_1
root@ctr-1:~# ctr task list
TASK       PID      STATUS
nginx_1    18895    STOPPED

8.删除任务

命令:

ctr task rm <container_name>

例:

root@ctr-1:~# ctr task rm nginx_1
root@ctr-1:~# ctr task list
TASK    PID    STATUS

9.ctr run

ctr run 命令实际上是快捷方式ctr container create + ctr task start

  • –net-host: 主机网络

例:

root@ctr-1:~# ctr run -d docker.io/library/nginx:1.23.3 nginx_2
root@ctr-1:~# ctr run --net-host -d docker.io/library/nginx:1.23.3 nginx_3
root@ctr-1:~# curl http://127.0.0.1:80

六、ctr 命令操作命名空间

containerd 相比于docker,多了 namespace 概念,每个 image 和containe 都会在各自的 namespace 下可见

1.查看命名空间

命令:

ctr namespaces list
ctr ns ls

例:

root@ctr-1:~# ctr namespaces list
NAME    LABELS
default
dev
root@ctr-1:~# ctr ns ls
NAME    LABELS 
default
dev

2.创建命名空间

命令:

ctr namespaces create <ns_name>
ctr ns create <ns_name>

3.删除命名空间

命令:

ctr namespaces rm <ns_name>
ctr ns rm <ns_name>

4.拉取镜像到指定的命令空间

ctr -n <ns_name> images pull <image_name>

例:

root@ctr-1:~# ctr -n dev images pull docker.io/library/nginx:1.25-alpine

5.查看指定命名空间下的镜像

ctr -n <ns_name> images ls

例:

root@ctr-1:~# ctr -n dev images list
REF                                 TYPE                                    DIGEST                                                                  SIZE     PLATFORMS                                                                                                LABELS 
docker.io/library/nginx:1.25-alpine application/vnd.oci.image.index.v1+json sha256:fdbfdaea4fc323f44590e9afeb271da8c345a733bf44c4ad7861201676a95f42 19.5 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x,unknown/unknown -

七、网络

默认 containerd 管理的容器仅有 lo 网络,无法访问容器之外的网络,可以为其添加网络插件。

便于测试,使用 nicolaka/netshoot 镜像,内置的有查看容器的 ip 的命令。

ctr-1:~# ctr image pull docker.io/nicolaka/netshoot:v0.13

1.默认

ctr-1:~# ctr container create docker.io/nicolaka/netshoot:v0.13 netshoot_1
ctr-1:~# ctr task start -d netshoot_1
ctr-1:~# ctr task exec --exec-id 1 -t netshoot_1 bash
ctr-1:~# ifconfig
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

2.使用主机网络

  • --net-host 为容器启用主机网络,让容器共享主机的网络命名空间,这意味着容器将使用主机的 IP 地址和端口,而不是创建一个新的独立网络命名空间。
ctr-1:~# ctr container create --net-host docker.io/nicolaka/netshoot:v0.13 netshoot_2
ctr-1:~# ctr task start -d netshoot_2
ctr-1:~# ctr task exec --exec-id 2 -t netshoot_2 bash
ctr-1:~# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:234707 errors:0 dropped:0 overruns:0 frame:0
          TX packets:127521 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:322696737 (307.7 MiB)  TX bytes:8564271 (8.1 MiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)