hugo-teek is loading...

containerd的本地CLI工具ctr使用

最后更新于:

containerd的本地CLI工具ctr使用

****

目录

[toc]

1、帮助命令

我们知道 Docker CLI 工具提供了需要增强用户体验的功能,containerd 同样也提供一个对应的 CLI 工具:ctr,不过 ctr 的功能没有 docker 完善,但是关于镜像和容器的基本功能都是有的。接下来我们就先简单介绍下 ctr 的使用。

直接输入 ctr 命令即可获得所有相关的操作命令使用方式:

 1[root@containerd ~]#ctr
 2NAME:
 3   ctr -
 4        __
 5  _____/ /______
 6 / ___/ __/ ___/
 7/ /__/ /_/ /
 8\___/\__/_/
 9
10containerd CLI
11
12
13USAGE:
14   ctr [global options] command [command options] [arguments...] #注意这个用法!
15
16VERSION:
17   v1.5.5
18
19DESCRIPTION:
20
21ctr is an unsupported debug and administrative client for interacting
22with the containerd daemon. Because it is unsupported, the commands,
23options, and operations are not guaranteed to be backward compatible or
24stable from release to release of the containerd project.
25
26COMMANDS:
27   plugins, plugin            provides information about containerd plugins
28   version                    print the client and server versions
29   containers, c, container   manage containers
30   content                    manage content
31   events, event              display containerd events
32   images, image, i           manage images
33   leases                     manage leases
34   namespaces, namespace, ns  manage namespaces
35   pprof                      provide golang pprof outputs for containerd
36   run                        run a container
37   snapshots, snapshot        manage snapshots
38   tasks, t, task             manage tasks
39   install                    install a new package
40   oci                        OCI tools
41   shim                       interact with a shim directly
42   help, h                    Shows a list of commands or help for one command
43
44GLOBAL OPTIONS:
45   --debug                      enable debug output in logs
46   --address value, -a value    address for containerd's GRPC server (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]
47   --timeout value              total timeout for ctr commands (default: 0s)
48   --connect-timeout value      timeout for connecting to containerd (default: 0s)
49   --namespace value, -n value  namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE]
50   --help, -h                   show help
51   --version, -v                print the version
52[root@containerd ~]#

注意:如何查看command的命令选项呢?(直接回车或者加上-h都行)

 1[root@containerd ~]#ctr plugin
 2NAME:
 3   ctr plugins - provides information about containerd plugins
 4
 5USAGE:
 6   ctr plugins command [command options] [arguments...]
 7
 8COMMANDS:
 9   list, ls  lists containerd plugins
10
11OPTIONS:
12   --help, -h  show help
13
14[root@containerd ~]#ctr plugin ls

2、镜像操作

1.拉取镜像

拉取镜像可以使用 ctr image pull 来完成,比如拉取 Docker Hub 官方镜像 nginx:alpine,需要注意的是镜像地址需要加上 docker.io Host 地址:(这个需要注意下)

1ctr i pull docker.io/library/nginx:alpine
2
3ctr i pull --all-platforms docker.io/library/nginx:alpine #建议使用这个命令,否则后面import会报错
 1[root@containerd ~]#ctr i pull docker.io/library/nginx:alpine
 2docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
 3index-sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3:    done           |++++++++++++++++++++++++++++++++++++++|
 4manifest-sha256:af466e4f12e3abe41fcfb59ca0573a3a5c640573b389d5287207a49d1324abd8: done           |++++++++++++++++++++++++++++++++++++++|
 5layer-sha256:61074acc7dd227cfbeaf719f9b5cdfb64711bc6b60b3865c7b886b7099c15d15:    done           |++++++++++++++++++++++++++++++++++++++|
 6config-sha256:513f9a9d8748b25cdb0ec6f16b4523af7bba216a6bf0f43f70af75b4cf7cb780:   done           |++++++++++++++++++++++++++++++++++++++|
 7layer-sha256:a0d0a0d46f8b52473982a3c466318f479767577551a53ffc9074c9fa7035982e:    done           |++++++++++++++++++++++++++++++++++++++|
 8layer-sha256:4dd4efe90939ab5711aaf5fcd9fd8feb34307bab48ba93030e8b845f8312ed8e:    done           |++++++++++++++++++++++++++++++++++++++|
 9layer-sha256:c1368e94e1ec563b31c3fb1fea02c9fbdc4c79a95e9ad0cac6df29c228ee2df3:    done           |++++++++++++++++++++++++++++++++++++++|
10layer-sha256:3e72c40d0ff43c52c5cc37713b75053e8cb5baea8e137a784d480123814982a2:    done           |++++++++++++++++++++++++++++++++++++++|
11layer-sha256:969825a5ca61c8320c63ff9ce0e8b24b83442503d79c5940ba4e2f0bd9e34df8:    done           |++++++++++++++++++++++++++++++++++++++|
12elapsed: 13.9s                                                                    total:  8.7 Mi (640.7 KiB/s)
13unpacking linux/amd64 sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...
14done: 839.71453ms
15
16#查看拉取到的镜像
17[root@containerd ~]#ctr i ls
18REF                            TYPE                                                      DIGEST                                                                  SIZE    PLATFORMS                                                                                LABELS
19docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3 9.5 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -
20[root@containerd ~]#ctr i ls -q
21docker.io/library/nginx:alpine
22[root@containerd ~]#

也可以使用 --platform 选项指定对应平台的镜像。当然对应的也有推送镜像的命令 ctr image push,如果是私有镜像则在推送的时候可以通过 --user 来自定义仓库的用户名和密码。

2.列出本地镜像

1#查看拉取到的镜像
2[root@containerd ~]#ctr i ls
3REF                            TYPE                                                      DIGEST                                                                  SIZE    PLATFORMS                                                                                LABELS
4docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3 9.5 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -
5
6#使用 `-q(--quiet)` 选项可以只打印镜像名称。
7[root@containerd ~]#ctr i ls -q 
8docker.io/library/nginx:alpine
9[root@containerd ~]#

3.检测本地镜像

1[root@containerd ~]#ctr i check #主要查看其中的 `STATUS`,`complete` 表示镜像是完整可用的状态。
2REF                            TYPE                                                      DIGEST                                                                  STATUS         SIZE            UNPACKED
3docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3 complete (7/7) 9.5 MiB/9.5 MiB true
4
5[root@containerd ~]#ctr i check -q
6docker.io/library/nginx:alpine
7[root@containerd ~]#

4.重新打标签

同样的我们也可以重新给指定的镜像打一个 Tag:

1[root@containerd ~]#ctr i tag docker.io/library/nginx:alpine harbor.k8s.local/course/nginx:alpine
2harbor.k8s.local/course/nginx:alpine
3[root@containerd ~]#ctr i ls -q
4docker.io/library/nginx:alpine
5harbor.k8s.local/course/nginx:alpine
6[root@containerd ~]#

5.删除镜像

不需要使用的镜像也可以使用 ctr image rm 进行删除:

 1[root@containerd ~]#ctr i ls -q
 2docker.io/library/nginx:alpine
 3harbor.k8s.local/course/nginx:alpine
 4
 5[root@containerd ~]#ctr i rm harbor.k8s.local/course/nginx:alpine
 6harbor.k8s.local/course/nginx:alpine
 7
 8[root@containerd ~]#ctr i ls -q
 9docker.io/library/nginx:alpine
10[root@containerd ~]#

加上 --sync 选项可以同步删除镜像和所有相关的资源。 (疑问:这里所有相关的资源指的是什么??)

6.将镜像挂载到主机目录

 1[root@containerd ~]#ctr i mount docker.io/library/nginx:alpine /mnt
 2sha256:5da2ba1075ada2783aada4fa30ec8cdd56a072759ea7c283de1c505b56ed0e70
 3/mnt
 4[root@containerd ~]#tree -L 1 /mnt/
 5/mnt/
 6├── bin
 7├── dev
 8├── docker-entrypoint.d
 9├── docker-entrypoint.sh
10├── etc
11├── home
12├── lib
13├── media
14├── mnt
15├── opt
16├── proc
17├── root
18├── run
19├── sbin
20├── srv
21├── sys
22├── tmp
23├── usr
24└── var
25
2618 directories, 1 file
27[root@containerd ~]#

7.将镜像从主机目录上卸载

1[root@containerd ~]#ctr i unmount /mnt
2/mnt
3[root@containerd ~]#

8.将镜像导出为压缩包 & 从压缩包导入镜像

1、将镜像导出为压缩包

1ctr image export --all-platforms nginx.tar.gz image
2或者
3ctr image export --platform=linux/amd64 nginx.tar.gz image#添加什么参数区别于当时在拉取的时候添加的是什么参数;(这里要特别注意下)

这里需要注意下:在使用export命令是需要添加–platform参数,否则会报错。

🍀 如下测试过程:

 1#查看export命令参数
 2[root@containerd ~]#ctr i export -h
 3NAME:
 4   ctr images export - export images
 5
 6USAGE:
 7   ctr images export [command options] [flags] <out> <image> ...
 8
 9DESCRIPTION:
10   Export images to an OCI tar archive.
11
12Tar output is formatted as an OCI archive, a Docker manifest is provided for the platform.
13Use '--skip-manifest-json' to avoid including the Docker manifest.json file.
14Use '--platform' to define the output platform.
15When '--all-platforms' is given all images in a manifest list must be available.
16
17
18OPTIONS:
19   --skip-manifest-json      do not add Docker compatible manifest.json to archive
20   --skip-non-distributable  do not add non-distributable blobs such as Windows layers to archive
21   --platform value          Pull content from a specific platform
22   --all-platforms           exports content from all platforms
23
24[root@containerd ~]#
25
26(1)
27[root@containerd ~]#ctr i ls -q
28docker.io/library/nginx:alpine
29
30[root@containerd ~]#ctr i export nginx.tar.gz docker.io/library/nginx:alpine #注意这里一定要加上--platform字段才可以,否则会报错
31ctr: content digest sha256:c8ca916e00dd0c56c91a81100ca79b668196642492153498e5d77619ccb55f9a: not found
32
33
34[root@containerd ~]#ctr image export --all-platforms nginx.tar.gz docker.io/library/nginx:alpine #加上--all-platforms参数也会报错的
35ctr: content digest sha256:826624c15f5e49e591d80f3e0c696f92a2d5967b989017572fe241edac294a2a: not found
36
37[root@containerd ~]#ctr image export --platform=linux/amd64 nginx.tar.gz #加上--platform=linux/amd64就没有报错了……
38docker.io/library/nginx:alpine
39[root@containerd ~]#ll -h
40total 131M
41-rw-r--r-- 1 root root 122M Jul 30 01:16 cri-containerd-cni-1.5.5-linux-amd64.tar.gz
42-rw-r--r-- 1 root root 9.6M Oct 24 11:29 nginx.tar.gz
43[root@containerd ~]#

2、从压缩包导入镜像

1[root@containerd ~]#ctr i import nginx.tar.gz
2ctr: content digest sha256:c8ca916e00dd0c56c91a81100ca79b668196642492153498e5d77619ccb55f9a: not found
3[root@containerd ~]#

🍀 注意:

直接导入可能会出现类似于 ctr: content digest sha256:xxxxxx not found 的错误,要解决这个办法需要 pull 所有平台镜像:

解决办法如下:

1  ~ ctr i pull --all-platforms docker.io/library/nginx:alpine
2  ~ ctr i export --all-platforms nginx.tar.gz docker.io/library/nginx:alpine
3  ~ ctr i rm docker.io/library/nginx:alpine
4  ~ ctr i import nginx.tar.gz

测试过程如下:

=>测试成功,有效果! 这个是在拉取、导出的时候都加了这个–all-platforms参数了,后面再使用import命令导入时就没报错了; 那应该是在拉取/导出都一般建议加上–platform=linux/amd64才行了,经测试,还是不行,必须要加上–all-paltforms;。。。

常见的cpu架构: linux/amd linux/arm linux/386 linux/ppc64le linux/s390x;

 1#测试1 -all-platforms参数 =>测试成功!
 2[root@containerd ~]#ctr i ls -q
 3
 4[root@containerd ~]#ctr i pull --all-platforms docker.io/library/nginx:alpine
 5docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
 6index-sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3:    done           |++++++++++++++++++++++++++++++++++++++|
 7manifest-sha256:9a5737495f65a20ba47a51777a8a62e6624b80718f2dc3fae474204e13a7e84d: done           |++++++++++++++++++++++++++++++++++++++|
 8manifest-sha256:1eae607e3ae6e25635d84d9d77477d175c760a04b6a14bc959a6e5681ee8d9e3: done           |++++++++++++++++++++++++++++++++++++++|
 9manifest-sha256:fa27d916cd6d3f1af3059dfb02cc5ce2a148728c7834f0ca16f5cca72851ba3e: done           |++++++++++++++++++++++++++++++++++++++|
10manifest-sha256:af466e4f12e3abe41fcfb59ca0573a3a5c640573b389d5287207a49d1324abd8: done           |++++++++++++++++++++++++++++++++++++++|
11……
12layer-sha256:51e249e97c0f2774e0cddc52b690c7ba43e390c6435b5a9f9720ecd322475f89:    done           |++++++++++++++++++++++++++++++++++++++|
13layer-sha256:d054f694df8acb81d335f71957611be009908c6f82c698ab0202b847452b8d3d:    done           |++++++++++++++++++++++++++++++++++++++|
14config-sha256:cae4aab78dd0f7d3bf32ccf5bee5fcc68eaadc9dc6b3c638dc150a592753464e:   done           |++++++++++++++++++++++++++++++++++++++|
15layer-sha256:31b7e7ccca9e17fd08b39c9a4ffd3ded380b62816c489d6c3758c9bb5a632430:    done           |++++++++++++++++++++++++++++++++++++++|
16layer-sha256:78dc23c8e094badc973f6de7a898c92e45402fbede9c0c6f5d0ad093431d54e5:    done           |++++++++++++++++++++++++++++++++++++++|
17layer-sha256:92558b0d876a60f4d90ba21b551071c84d03dbb3b534ffd73f9c86842814dc7e:    done           |++++++++++++++++++++++++++++++++++++++|
18layer-sha256:f7f841035be926c8de3cbd1a5c5734f5e15ff7606e9d995cfa246a95fef5b0ca:    done           |++++++++++++++++++++++++++++++++++++++|
19layer-sha256:ffc8cae1e0f917be25d70d24fe1eb2172515c29385af29d993551f2af4dbd59c:    done           |++++++++++++++++++++++++++++++++++++++|
20elapsed: 38.7s                                                                    total:  65.2 M (1.7 MiB/s)   
21unpacking linux/amd64 sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...
22unpacking linux/arm/v6 sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...
23unpacking linux/arm/v7 sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...
24unpacking linux/arm64/v8 sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...
25unpacking linux/386 sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...
26unpacking linux/ppc64le sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...
27unpacking linux/s390x sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...
28done: 5.731487623s
29[root@containerd ~]#ctr i export --all-platforms nginx.tar.gz docker.io/library/nginx:alpine
30[root@containerd ~]#ll -h
31total 187M
32-rw-r--r-- 1 root root 122M Jul 30 01:16 cri-containerd-cni-1.5.5-linux-amd64.tar.gz
33-rw-r--r-- 1 root root  66M Oct 24 11:39 nginx.tar.gz
34[root@containerd ~]#ctr i import nginx.tar.gz
35unpacking docker.io/library/nginx:alpine (sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3)...done
36[root@containerd ~]#ctr i ls -q
37docker.io/library/nginx:alpine
38[root@containerd ~]#
 1#测试2:--platform=linux/amd64参数 =>测试失败
 2[root@containerd ~]#ctr i ls -q
 3docker.io/library/nginx:alpine
 4[root@containerd ~]#ctr i rm docker.io/library/nginx:alpine
 5docker.io/library/nginx:alpine
 6[root@containerd ~]#ctr i ls -q
 7[root@containerd ~]#
 8[root@containerd ~]#
 9[root@containerd ~]#ctr i pull --platform=linux/amd64 docker.io/library/nginx:alpine
10docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
11index-sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3:    done           |++++++++++++++++++++++++++++++++++++++|
12manifest-sha256:af466e4f12e3abe41fcfb59ca0573a3a5c640573b389d5287207a49d1324abd8: done           |++++++++++++++++++++++++++++++++++++++|
13layer-sha256:61074acc7dd227cfbeaf719f9b5cdfb64711bc6b60b3865c7b886b7099c15d15:    done           |++++++++++++++++++++++++++++++++++++++|
14config-sha256:513f9a9d8748b25cdb0ec6f16b4523af7bba216a6bf0f43f70af75b4cf7cb780:   done           |++++++++++++++++++++++++++++++++++++++|
15layer-sha256:a0d0a0d46f8b52473982a3c466318f479767577551a53ffc9074c9fa7035982e:    done           |++++++++++++++++++++++++++++++++++++++|
16layer-sha256:4dd4efe90939ab5711aaf5fcd9fd8feb34307bab48ba93030e8b845f8312ed8e:    done           |++++++++++++++++++++++++++++++++++++++|
17layer-sha256:c1368e94e1ec563b31c3fb1fea02c9fbdc4c79a95e9ad0cac6df29c228ee2df3:    done           |++++++++++++++++++++++++++++++++++++++|
18layer-sha256:3e72c40d0ff43c52c5cc37713b75053e8cb5baea8e137a784d480123814982a2:    done           |++++++++++++++++++++++++++++++++++++++|
19layer-sha256:969825a5ca61c8320c63ff9ce0e8b24b83442503d79c5940ba4e2f0bd9e34df8:    done           |++++++++++++++++++++++++++++++++++++++|
20elapsed: 20.3s                                                                    total:  8.8 Mi (445.4 KiB/s)
21unpacking linux/amd64 sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...
22done: 17.093491ms
23[root@containerd ~]#ctr i ls -q
24docker.io/library/nginx:alpine
25[root@containerd ~]#
26[root@containerd ~]#
27[root@containerd ~]#rm -rf nginx.tar.gz
28[root@containerd ~]#ll -h
29total 122M
30-rw-r--r-- 1 root root 122M Jul 30 01:16 cri-containerd-cni-1.5.5-linux-amd64.tar.gz
31[root@containerd ~]#ctr i export --platform=linux/amd64 nginx.tar.gz docker.io/library/nginx:alpine
32[root@containerd ~]#ll -h
33total 131M
34-rw-r--r-- 1 root root 122M Jul 30 01:16 cri-containerd-cni-1.5.5-linux-amd64.tar.gz
35-rw-r--r-- 1 root root 9.6M Oct 24 11:47 nginx.tar.gz
36[root@containerd ~]#
37[root@containerd ~]#ctr i import nginx.tar.gz
38ctr: content digest sha256:c8ca916e00dd0c56c91a81100ca79b668196642492153498e5d77619ccb55f9a: not found
39[root@containerd ~]#ctr i import --platform=linux/amd64 nginx.tar.gz
40Incorrect Usage: flag provided but not defined: -platform
41
42NAME:
43   ctr images import - import images
44
45USAGE:
46   ctr images import [command options] [flags] <in>
47
48DESCRIPTION:
49   Import images from a tar stream.
50Implemented formats:
51- oci.v1
52- docker.v1.1
53- docker.v1.2
54
55
56For OCI v1, you may need to specify --base-name because an OCI archive may
57contain only partial image references (tags without the base image name).
58If no base image name is provided, a name will be generated as "import-%{yyyy-MM-dd}".
59
60e.g.
61  $ ctr images import --base-name foo/bar foobar.tar
62
63If foobar.tar contains an OCI ref named "latest" and anonymous ref "sha256:deadbeef", the command will create
64"foo/bar:latest" and "foo/bar@sha256:deadbeef" images in the containerd store.
65
66
67OPTIONS:
68   --base-name value    base image name for added images, when provided only images with this name prefix are imported
69   --digests            whether to create digest images (default: false)
70   --index-name value   image name to keep index as, by default index is discarded
71   --all-platforms      imports content for all platforms, false by default
72   --no-unpack          skip unpacking the images, false by default
73   --compress-blobs     compress uncompressed blobs when creating manifest (Docker format only)
74   --snapshotter value  snapshotter name. Empty value stands for the default value. [$CONTAINERD_SNAPSHOTTER]
75
76ctr: flag provided but not defined: -platform
77[root@containerd ~]#ctr i import --all-platforms nginx.tar.gz
78ctr: content digest sha256:826624c15f5e49e591d80f3e0c696f92a2d5967b989017572fe241edac294a2a: not found
79[root@containerd ~]#

结论如下。

总结

1经测试:
201、在拉取镜像、导出镜像时,都加上--all-platforms 时,最后在用ctr i import  nginx.tar.gz就不会报错了;
302、在拉取镜像、导出镜像时,都加上--platform=linux/amd64时,最后在用ctr i import  nginx.tar.gz时依然报错;
403、在拉起镜像时不添加任何--platform参数,最后在用ctr i import  nginx.tar.gz也会报错;
5
6很无语,那么最后再拉取任何镜像时都要加上--all-platforms参数了吗,那就加上呗,要不以后再使用import时会报错;

实践:k8s集群里ctr命令导出与导入测试(测试成功)-2022.4.29

💘 实践:k8s集群里ctr命令导出与导入测试(测试成功)-2022.4.29

  • 当前环境

node1上有docker.io/prom/prometheus:v2.34.0镜像,但k8s-master上没有这个镜像,此时想把node1上的这个镜像直接导出到本地,然后再导入到k8s-master1上。

1[root@node1 ~]#ctr -n k8s.io i ls |grep prometheus
2docker.io/prom/prometheus:v2.34.0                                                                                                application/vnd.docker.distribution.manifest.list.v2+json sha256:b37103e03399e90c9b7b1b2940894d3634915cf9df4aa2e5402bd85b4377808c 74.4 MiB  linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x                                                                        io.cri-containerd.image=managed 
3docker.io/prom/prometheus@sha256:b37103e03399e90c9b7b1b2940894d3634915cf9df4aa2e5402bd85b4377808c                                application/vnd.docker.distribution.manifest.list.v2+json sha256:b37103e03399e90c9b7b1b2940894d3634915cf9df4aa2e5402bd85b4377808c 74.4 MiB  linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x                                                                        io.cri-containerd.image=managed 
4
5[root@master1 ~]#ctr -n k8s.io i ls |grep prometheus
6[root@master1 ~]#

1、导出镜像

1[root@node1 ~]#ctr -n k8s.io i export  prometheus.v2.34.0.tar.gz docker.io/prom/prometheus:v2.34.0

2、导入镜像

1[root@master1 ~]#ctr -n k8s.io i import prometheus.v2.34.0.tar.gz

🍀 结论

在k8s集群,运行时是containerd时,完全可以使用containerd自带的ctr命令进行操作容器及镜像!

注意:以上使用ctr命令在导出镜像时,可以看到没添加–all-platforms选项,后面也是可以正常导入的。这是因为所使用的那个镜像当时拉取时默认就是带了–all-paltforms参数的。

案例:推送到harbor时也需要加上–platform参数才好

2022年7月19日

image-20230910165624722

3、容器操作

容器相关操作可以通过 ctr container 获取。

1.创建容器

1[root@containerd ~]#ctr c create docker.io/library/nginx:alpine nginx

2.列出容器

1[root@containerd ~]#ctr c ls
2CONTAINER    IMAGE                             RUNTIME
3nginx        docker.io/library/nginx:alpine    io.containerd.runc.v2
4
5[root@containerd ~]#ctr c ls -q #同样可以加上 `-q` 选项精简列表内容:
6nginx
7[root@containerd ~]#

3.查看容器详细配置

类似于 docker inspect 功能。

 1[root@containerd ~]#ctr c info nginx
 2{
 3    "ID": "nginx",
 4    "Labels": {
 5        "io.containerd.image.config.stop-signal": "SIGQUIT"
 6    },
 7    "Image": "docker.io/library/nginx:alpine",
 8    "Runtime": {
 9        "Name": "io.containerd.runc.v2",
10        "Options": {
11            "type_url": "containerd.runc.v1.Options"
12        }
13    },
14    "SnapshotKey": "nginx",
15……

4.删除容器

1[root@containerd ~]#ctr c ls
2CONTAINER    IMAGE                             RUNTIME
3nginx        docker.io/library/nginx:alpine    io.containerd.runc.v2
4[root@containerd ~]#ctr c rm nginx 
5[root@containerd ~]#ctr c ls
6CONTAINER    IMAGE    RUNTIME
7[root@containerd ~]#

除了使用 rm 子命令之外也可以使用 delete 或者 del 删除容器。

 1[root@containerd ~]#ctr c
 2NAME:
 3   ctr containers - manage containers
 4
 5USAGE:
 6   ctr containers command [command options] [arguments...]
 7
 8COMMANDS:
 9   create           create container
10   delete, del, rm  delete one or more existing containers #注意
11   info             get info about a container
12   list, ls         list containers
13   label            set and clear labels for a container
14   checkpoint       checkpoint a container
15   restore          restore a container from checkpoint
16
17OPTIONS:
18   --help, -h  show help
19
20[root@containerd ~]#

4、任务

上面我们通过 **container create** 命令创建的容器,并没有处于运行状态,只是一个静态的容器(仅仅只是一个创建容器的声明)。一个 container 对象只是包含了运行一个容器所需的资源及相关配置数据,表示 namespaces、rootfs 和容器的配置都已经初始化成功了,只是用户进程还没有启动。

一个容器真正运行起来是由 Task 任务实现的,Task 可以为容器设置网卡,还可以配置工具来对容器进行监控等。

1.启动一个容器

Task 相关操作可以通过 ctr task 获取,如下我们通过 Task 来启动容器:

1[root@containerd ~]#ctr task start -d nginx
2/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
3/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
4/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
5[root@containerd ~]#

2.查看正在运行的容器

启动容器后可以通过 task ls 查看正在运行的容器:

1[root@containerd ~]#ctr task ls
2TASK     PID      STATUS
3nginx    24458    RUNNING
4[root@containerd ~]#ctr task ls -q
5nginx
6[root@containerd ~]#

3.进入到容器里面

同样也可以使用 exec 命令进入容器进行操作:

 1[root@containerd ~]#ctr task exec --exec-id 0 -t nginx sh
 2/ # ls
 3bin                   media                 srv
 4dev                   mnt                   sys
 5docker-entrypoint.d   opt                   tmp
 6docker-entrypoint.sh  proc                  usr
 7etc                   root                  var
 8home                  run
 9lib                   sbin
10/ # ps
11PID   USER     TIME  COMMAND
12    1 root      0:00 nginx: master process nginx -g daemon off;
13   32 nginx     0:00 nginx: worker process
14   33 nginx     0:00 nginx: worker process
15   34 root      0:00 sh
16   41 root      0:00 ps
17/ #

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

4.暂停容器

暂停容器,和 docker pause 类似的功能:

1[root@containerd ~]#ctr task pause nginx

暂停后容器状态变成了 PAUSED

1[root@containerd ~]#ctr task ls
2TASK     PID      STATUS
3nginx    24458    PAUSED
4[root@containerd ~]#

5.恢复容器

同样也可以使用 resume 命令来恢复容器:

1[root@containerd ~]#ctr t resume nginx #resume 继续,重新开始
2[root@containerd ~]#ctr task ls
3TASK     PID      STATUS
4nginx    24458    RUNNING
5[root@containerd ~]#

6.杀死容器

**不过需要注意 ctr 没有 stop 容器的功能,只能暂停或者杀死容器。**杀死容器可以使用 task kill 命令:

1[root@containerd ~]#ctr t kill nginx
2[root@containerd ~]#ctr task ls
3TASK     PID      STATUS
4nginx    24458    STOPPED
5[root@containerd ~]#

7.删除task

杀掉容器后可以看到容器的状态变成了 STOPPED。同样也可以通过 task rm 命令删除 Task:

1[root@containerd ~]#ctr t rm nginx
2[root@containerd ~]#ctr task ls
3TASK    PID    STATUS
4[root@containerd ~]#
  • 问题:处于正在runnning的Task可以被删除吗?

测试过程:

 1[root@containerd ~]#ctr c ls
 2CONTAINER    IMAGE                             RUNTIME
 3nginx        docker.io/library/nginx:alpine    io.containerd.runc.v2
 4[root@containerd ~]#ctr t start -d nginx
 5[root@containerd ~]#ctr t ls
 6TASK     PID      STATUS
 7nginx    24713    RUNNING
 8[root@containerd ~]#ctr t rm nginx
 9ERRO[0000] unable to delete nginx                        error="task must be stopped before deletion: running: failed precondition"
10ctr: task must be stopped before deletion: running: failed precondition
11[root@containerd ~]#
12[root@containerd ~]## 由以上测试可以知道,要想删除一个正在运行的Task,必须先kill掉这个task,然后才能删除task,否则会报错;
13[root@containerd ~]#ctr t kill nginx
14[root@containerd ~]#ctr t rm nginx
15[root@containerd ~]#ctr t ls
16TASK    PID    STATUS
17[root@containerd ~]#

结论:由以上测试可以知道,要想删除一个正在运行的Task,必须先kill掉这个task,然后才能删除。

8.取容器的内存、CPU 和 PID 的限额与使用量

除此之外我们还可以获取容器的 cgroup 相关信息,可以使用 task metrics 命令用来获取容器的内存、CPU 和 PID 的限额与使用量。

 1[root@containerd ~]#ctr t metrics nginx
 2ID       TIMESTAMP
 3nginx    2021-10-24 05:54:38.74392351 +0000 UTC
 4
 5METRIC                   VALUE
 6memory.usage_in_bytes    1986560
 7memory.limit_in_bytes    9223372036854771712
 8memory.stat.cache        16384
 9cpuacct.usage            63033641
10cpuacct.usage_percpu     [17342796 45690845]
11pids.current             3
12pids.limit               0
13[root@containerd ~]#

9.查看容器中所有进程在宿主机中的 PID:

还可以使用 task ps 命令查看容器中所有进程在宿主机中的 PID:

 1[root@containerd ~]#ctr t ls
 2TASK     PID      STATUS
 3nginx    24841    RUNNING
 4[root@containerd ~]#ctr t ps nginx
 5PID      INFO
 624841    -
 724873    -
 824874    -
 9[root@containerd ~]#ps -ef|grep nginx
10root      24822      1  0 13:54 ?        00:00:00 /usr/local/bin/containerd-shim-runc-v2 -namespace default -id nginx -address /run/containerd/containerd.sock
11root      24841  24822  0 13:54 ?        00:00:00 nginx: master process nginx -g daemon off;
12101       24873  24841  0 13:54 ?        00:00:00 nginx: worker process
13101       24874  24841  0 13:54 ?        00:00:00 nginx: worker process
14root      24917  24303  0 13:56 pts/0    00:00:00 grep --color=auto nginx
15[root@containerd ~]#

其中第一个 PID 24841 就是我们容器中的1号进程。

5、命名空间

1.查看命名空间

另外 Containerd 中也支持命名空间的概念,比如查看命名空间:

1[root@containerd ~]#ctr ns ls
2NAME    LABELS
3default
4[root@containerd ~]#

2.创建命名空间

如果不指定,ctr 默认使用的是 default 空间。同样也可以使用 ns create 命令创建一个命名空间:

1[root@containerd ~]#ctr ns create test
2[root@containerd ~]#ctr ns ls
3NAME    LABELS
4default
5test
6[root@containerd ~]#

3.删除命名空间

使用 remove 或者 rm 可以删除 namespace:

 1[root@containerd ~]#ctr ns ls
 2NAME    LABELS
 3default
 4test
 5[root@containerd ~]#ctr ns rm test #删除命名空间
 6test
 7[root@containerd ~]#ctr ns ls
 8NAME    LABELS
 9default
10[root@containerd ~]#

4.指定命名空间选项

有了命名空间后就可以在操作资源的时候指定 namespace,比如查看 test 命名空间的镜像,可以在操作命令后面加上 -n test 选项:

1[root@containerd ~]#ctr i ls -q
2docker.io/library/nginx:alpine
3[root@containerd ~]#ctr -n test i ls -q
4[root@containerd ~]#

注意:

我们知道 Docker 其实也是默认调用的 containerd,事实上 Docker 使用的 containerd 下面的命名空间默认是 moby,而不是 default,所以假如我们有用 docker 启动容器,那么我们也可以通过 ctr -n moby 来定位下面的容器:

1[root@containerd ~]#ctr -n moby c ls
2CONTAINER    IMAGE    RUNTIME
3[root@containerd ~]#

同样 Kubernetes 下使用的 containerd 默认命名空间是 k8s.io,所以我们可以使用 ctr -n k8s.io 来查看 Kubernetes 下面创建的容器。

1[root@containerd ~]#ctr -n k8s.io c ls
2CONTAINER    IMAGE    RUNTIME
3[root@containerd ~]#

注意:这3者之间的ns是不同的,要区分开。

FAQ

注意:在导入镜像时遇到的报错问题处理方法

直接导入可能会出现类似于 ctr: content digest sha256:xxxxxx not found 的错误,要解决这个办法需要 pull 所有平台镜像:

解决办法如下:

1  ~ ctr i pull --all-platforms docker.io/library/nginx:alpine
2  ~ ctr i export --all-platforms nginx.tar.gz docker.io/library/nginx:alpine
3  ~ ctr i rm docker.io/library/nginx:alpine
4  ~ ctr i import nginx.tar.gz

结论:

经测试: 01、在拉取镜像、导出镜像时,都加上–all-platforms 时,最后在用ctr i import  nginx.tar.gz就不会报错了; 02、在拉取镜像、导出镜像时,都加上–platform=linux/amd64时,最后在用ctr i import  nginx.tar.gz时依然报错; 03、在拉起镜像时不添加任何–platform参数,最后在用ctr i import  nginx.tar.gz也会报错;

很无语,那么最后再拉取任何镜像时都要加上–all-platforms参数了吗,那就加上呗,要不以后再使用import时会报错;

ctr命令、crictl命令、nerctl命令

containerd也有 ctr 管理工具,但功能比较简单,一般使用crictl工具检查和调试容器。

项目地址:https://github.com/kubernetes-sigs/cri-tools/

准备crictl连接containerd配置文件:

1cat > /etc/crictl.yaml << EOF
2runtime-endpoint: unix:///run/containerd/containerd.sock
3EOF

下面是docker与crictl命令对照表:

image-20230604073825989

 1[root@containerd ~]#crictl version #这个crictl命令可以在k8s里查看一些pod信息
 2Version:  0.1.0
 3RuntimeName:  containerd
 4RuntimeVersion:  v1.5.7
 5RuntimeApiVersion:  v1alpha2
 6[root@containerd ~]#
 7
 8containerd客户端CLI:
 9ctr:这个很难用; #目前就是用ctr命令就可以可,相当于docker,但比docker难用的很多。
10nerctl:这个很高级的;
  • crictl命令
1crictl pods #查看当前节点pod信息
2crictl ps #查看当前节点容器信息

  • 查看下主容器的信息:
 1➜  ~ crictl inspect bcbbf88a9ac29
 2  "status": {
 3    "id": "bcbbf88a9ac29d84700525b4c898171889510b372b45a77f1c9757fdef3793a2",
 4    "metadata": {
 5      "attempt": 0,
 6      "name": "resource-demo1"
 7    },
 8    "state": "CONTAINER_RUNNING",
 9    "createdAt": "2021-11-07T16:46:37.069325484+08:00",
10    "startedAt": "2021-11-07T16:46:37.412557847+08:00",
11    "finishedAt": "0001-01-01T00:00:00Z",
12    "exitCode": 0,
13    "image": {
14      "annotations": {},
15      "image": "docker.io/library/nginx:latest"
16    },
17......
18      "linux": {
19        "resources": {
20          "devices": [
21            {
22              "allow": false,
23              "access": "rwm"
24            }
25          ],
26          "memory": {
27            "limit": 104857600
28          },
29          "cpu": {
30            "shares": 51,
31            "quota": 10000,
32            "period": 100000
33          }
34        },
35        "cgroupsPath": "kubepods-burstable-pod7e80487d_24d7_44af_bf38_c43b6dfe4045.slice:cri-containerd:bcbbf88a9ac29d84700525b4c898171889510b372b45a77f1c9757fdef3793a2",
36
37     ......

关于我

我的博客主旨:我希望每一个人拿着我的博客都可以做出实验现象,先把实验做出来,然后再结合理论知识更深层次去理解技术点,这样学习起来才有乐趣和动力。并且,我的博客内容步骤是很完整的,也分享源码和实验用到的软件,希望能和大家一起共同进步!

各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人免费帮您解决问题:

  1. 个人微信二维码:x2675263825 (舍得), qq:2675263825。
  2. 个人博客地址:www.onlyonexl.cn
  3. 个人微信公众号:云原生架构师实战
  4. 个人csdn https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

最后

好了,关于containerd的本地CLI工具ctr使用实验就到这里了,感谢大家阅读,最后贴上我的美圆photo一张,祝大家生活快乐,每天都过的有意义哦,我们下期见!

推荐使用微信支付
微信支付二维码
推荐使用支付宝
支付宝二维码
最新文章

文档导航