containerd的本地CLI工具ctr使用
containerd的本地CLI工具ctr使用
目录
[toc]
1、帮助命令
我们知道 Docker CLI 工具提供了需要增强用户体验的功能,containerd 同样也提供一个对应的 CLI 工具:ctr
,不过 ctr 的功能没有 docker 完善,但是关于镜像和容器的基本功能都是有的。接下来我们就先简单介绍下 ctr
的使用。
直接输入 ctr
命令即可获得所有相关的操作命令使用方式:
[root@containerd ~]#ctrNAME:ctr-_______//______/___/__/___///__//_//\___/\__/_/containerdCLIUSAGE:ctr[global options]command[command options][arguments...] #注意这个用法!VERSION:v1.5.5DESCRIPTION:ctrisanunsupporteddebugandadministrativeclientforinteractingwiththecontainerddaemon.Becauseitisunsupported,thecommands,options,andoperationsarenotguaranteedtobebackwardcompatibleorstablefromreleasetoreleaseofthecontainerdproject.COMMANDS:plugins,pluginprovidesinformationaboutcontainerdpluginsversionprinttheclientandserverversionscontainers,c,containermanagecontainerscontentmanagecontentevents,eventdisplaycontainerdeventsimages,image,imanageimagesleasesmanageleasesnamespaces,namespace,nsmanagenamespacespprofprovidegolangpprofoutputsforcontainerdrunrunacontainersnapshots,snapshotmanagesnapshotstasks,t,taskmanagetasksinstallinstallanewpackageociOCItoolsshiminteractwithashimdirectlyhelp,hShowsalistofcommandsorhelpforonecommandGLOBALOPTIONS:--debugenabledebugoutputinlogs--addressvalue,-avalueaddressforcontainerd's GRPC server (default:"/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]--timeout value total timeout for ctr commands (default:0s)--connect-timeout value timeout for connecting to containerd (default:0s)--namespace value,-n value namespace to use with commands (default:"default") [$CONTAINERD_NAMESPACE]--help,-h show help--version,-v print the version[root@containerd ~]#
注意:如何查看command的命令选项呢?(直接回车或者加上-h都行)
[root@containerd ~]#ctr pluginNAME:ctrplugins-providesinformationaboutcontainerdpluginsUSAGE:ctrpluginscommand[command options][arguments...]COMMANDS:list,lslistscontainerdpluginsOPTIONS:--help,-hshowhelp[root@containerd ~]#ctr plugin ls
2、镜像操作
1.拉取镜像
拉取镜像可以使用 ctr image pull
来完成,比如拉取 Docker Hub 官方镜像 nginx:alpine
,需要注意的是镜像地址需要加上 docker.io
Host 地址:(这个需要注意下)
ctripulldocker.io/library/nginx:alpinectripull--all-platformsdocker.io/library/nginx:alpine#建议使用这个命令,否则后面import会报错
[root@containerd ~]#ctr i pull docker.io/library/nginx:alpinedocker.io/library/nginx:alpine:resolved|++++++++++++++++++++++++++++++++++++++|index-sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3:done|++++++++++++++++++++++++++++++++++++++|manifest-sha256:af466e4f12e3abe41fcfb59ca0573a3a5c640573b389d5287207a49d1324abd8:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:61074acc7dd227cfbeaf719f9b5cdfb64711bc6b60b3865c7b886b7099c15d15:done|++++++++++++++++++++++++++++++++++++++|config-sha256:513f9a9d8748b25cdb0ec6f16b4523af7bba216a6bf0f43f70af75b4cf7cb780:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:a0d0a0d46f8b52473982a3c466318f479767577551a53ffc9074c9fa7035982e:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:4dd4efe90939ab5711aaf5fcd9fd8feb34307bab48ba93030e8b845f8312ed8e:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:c1368e94e1ec563b31c3fb1fea02c9fbdc4c79a95e9ad0cac6df29c228ee2df3:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:3e72c40d0ff43c52c5cc37713b75053e8cb5baea8e137a784d480123814982a2:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:969825a5ca61c8320c63ff9ce0e8b24b83442503d79c5940ba4e2f0bd9e34df8:done|++++++++++++++++++++++++++++++++++++++|elapsed:13.9stotal:8.7Mi(640.7 KiB/s)unpackinglinux/amd64sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...done:839.71453ms#查看拉取到的镜像[root@containerd ~]#ctr i lsREFTYPEDIGESTSIZEPLATFORMSLABELSdocker.io/library/nginx:alpineapplication/vnd.docker.distribution.manifest.list.v2+jsonsha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c39.5MiBlinux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x-[root@containerd ~]#ctr i ls -qdocker.io/library/nginx:alpine[root@containerd ~]#
也可以使用 --platform
选项指定对应平台的镜像。当然对应的也有推送镜像的命令 ctr image push
,如果是私有镜像则在推送的时候可以通过 --user
来自定义仓库的用户名和密码。
2.列出本地镜像
#查看拉取到的镜像[root@containerd ~]#ctr i lsREFTYPEDIGESTSIZEPLATFORMSLABELSdocker.io/library/nginx:alpineapplication/vnd.docker.distribution.manifest.list.v2+jsonsha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c39.5MiBlinux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x-#使用 `-q(--quiet)` 选项可以只打印镜像名称。[root@containerd ~]#ctr i ls -q docker.io/library/nginx:alpine[root@containerd ~]#
3.检测本地镜像
[root@containerd ~]#ctr i check #主要查看其中的 `STATUS`,`complete` 表示镜像是完整可用的状态。REFTYPEDIGESTSTATUSSIZEUNPACKEDdocker.io/library/nginx:alpineapplication/vnd.docker.distribution.manifest.list.v2+jsonsha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3complete(7/7) 9.5 MiB/9.5 MiB true[root@containerd ~]#ctr i check -qdocker.io/library/nginx:alpine[root@containerd ~]#
4.重新打标签
同样的我们也可以重新给指定的镜像打一个 Tag:
[root@containerd ~]#ctr i tag docker.io/library/nginx:alpine harbor.k8s.local/course/nginx:alpineharbor.k8s.local/course/nginx:alpine[root@containerd ~]#ctr i ls -qdocker.io/library/nginx:alpineharbor.k8s.local/course/nginx:alpine[root@containerd ~]#
5.删除镜像
不需要使用的镜像也可以使用 ctr image rm
进行删除:
[root@containerd ~]#ctr i ls -qdocker.io/library/nginx:alpineharbor.k8s.local/course/nginx:alpine[root@containerd ~]#ctr i rm harbor.k8s.local/course/nginx:alpineharbor.k8s.local/course/nginx:alpine[root@containerd ~]#ctr i ls -qdocker.io/library/nginx:alpine[root@containerd ~]#
加上 --sync
选项可以同步删除镜像和所有相关的资源。 (疑问:这里所有相关的资源指的是什么??)
6.将镜像挂载到主机目录
[root@containerd ~]#ctr i mount docker.io/library/nginx:alpine /mntsha256:5da2ba1075ada2783aada4fa30ec8cdd56a072759ea7c283de1c505b56ed0e70/mnt[root@containerd ~]#tree -L 1 /mnt//mnt/├──bin├──dev├──docker-entrypoint.d├──docker-entrypoint.sh├──etc├──home├──lib├──media├──mnt├──opt├──proc├──root├──run├──sbin├──srv├──sys├──tmp├──usr└──var18directories,1file[root@containerd ~]#
7.将镜像从主机目录上卸载
[root@containerd ~]#ctr i unmount /mnt/mnt[root@containerd ~]#
8.将镜像导出为压缩包 &从压缩包导入镜像
1、将镜像导出为压缩包
ctrimageexport--all-platformsnginx.tar.gzimage或者ctrimageexport--platform=linux/amd64nginx.tar.gzimage#添加什么参数区别于当时在拉取的时候添加的是什么参数;(这里要特别注意下)
这里需要注意下:在使用export命令是需要添加--platform参数,否则会报错。
🍀 如下测试过程:
#查看export命令参数[root@containerd ~]#ctr i export-hNAME:ctrimagesexport-exportimagesUSAGE:ctrimagesexport[command options][flags] <out><image>...DESCRIPTION:ExportimagestoanOCItararchive.TaroutputisformattedasanOCIarchive,aDockermanifestisprovidedfortheplatform.Use'--skip-manifest-json'toavoidincludingtheDockermanifest.jsonfile.Use'--platform'todefinetheoutputplatform.When'--all-platforms'isgivenallimagesinamanifestlistmustbeavailable.OPTIONS:--skip-manifest-jsondonotaddDockercompatiblemanifest.jsontoarchive--skip-non-distributabledonotaddnon-distributableblobssuchasWindowslayerstoarchive--platformvaluePullcontentfromaspecificplatform--all-platformsexportscontentfromallplatforms[root@containerd ~]#(1)[root@containerd ~]#ctr i ls -qdocker.io/library/nginx:alpine[root@containerd ~]#ctr i exportnginx.tar.gz docker.io/library/nginx:alpine #注意这里一定要加上--platform字段才可以,否则会报错ctr:contentdigestsha256:c8ca916e00dd0c56c91a81100ca79b668196642492153498e5d77619ccb55f9a:notfound[root@containerd ~]#ctr image export--all-platforms nginx.tar.gz docker.io/library/nginx:alpine #加上--all-platforms参数也会报错的ctr:contentdigestsha256:826624c15f5e49e591d80f3e0c696f92a2d5967b989017572fe241edac294a2a:notfound[root@containerd ~]#ctr image export--platform=linux/amd64 nginx.tar.gz #加上--platform=linux/amd64就没有报错了……docker.io/library/nginx:alpine[root@containerd ~]#ll -htotal131M-rw-r--r--1rootroot122MJul3001:16cri-containerd-cni-1.5.5-linux-amd64.tar.gz-rw-r--r--1rootroot9.6MOct2411:29nginx.tar.gz[root@containerd ~]#
2、从压缩包导入镜像
[root@containerd ~]#ctr i import nginx.tar.gzctr:contentdigestsha256:c8ca916e00dd0c56c91a81100ca79b668196642492153498e5d77619ccb55f9a:notfound[root@containerd ~]#
🍀 注意:
直接导入可能会出现类似于 ctr:content digest sha256:xxxxxx not found
的错误,要解决这个办法需要 pull 所有平台镜像:
解决办法如下:
➜ ~ctr i pull --all-platforms docker.io/library/nginx:alpine➜ ~ctr i export --all-platforms nginx.tar.gz docker.io/library/nginx:alpine➜ ~ctr i rm docker.io/library/nginx:alpine➜ ~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 -all-platforms参数 =>测试成功![root@containerd ~]#ctr i ls -q[root@containerd ~]#ctr i pull --all-platforms docker.io/library/nginx:alpinedocker.io/library/nginx:alpine:resolved|++++++++++++++++++++++++++++++++++++++|index-sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3:done|++++++++++++++++++++++++++++++++++++++|manifest-sha256:9a5737495f65a20ba47a51777a8a62e6624b80718f2dc3fae474204e13a7e84d:done|++++++++++++++++++++++++++++++++++++++|manifest-sha256:1eae607e3ae6e25635d84d9d77477d175c760a04b6a14bc959a6e5681ee8d9e3:done|++++++++++++++++++++++++++++++++++++++|manifest-sha256:fa27d916cd6d3f1af3059dfb02cc5ce2a148728c7834f0ca16f5cca72851ba3e:done|++++++++++++++++++++++++++++++++++++++|manifest-sha256:af466e4f12e3abe41fcfb59ca0573a3a5c640573b389d5287207a49d1324abd8:done|++++++++++++++++++++++++++++++++++++++|……layer-sha256:51e249e97c0f2774e0cddc52b690c7ba43e390c6435b5a9f9720ecd322475f89:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:d054f694df8acb81d335f71957611be009908c6f82c698ab0202b847452b8d3d:done|++++++++++++++++++++++++++++++++++++++|config-sha256:cae4aab78dd0f7d3bf32ccf5bee5fcc68eaadc9dc6b3c638dc150a592753464e:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:31b7e7ccca9e17fd08b39c9a4ffd3ded380b62816c489d6c3758c9bb5a632430:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:78dc23c8e094badc973f6de7a898c92e45402fbede9c0c6f5d0ad093431d54e5:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:92558b0d876a60f4d90ba21b551071c84d03dbb3b534ffd73f9c86842814dc7e:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:f7f841035be926c8de3cbd1a5c5734f5e15ff7606e9d995cfa246a95fef5b0ca:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:ffc8cae1e0f917be25d70d24fe1eb2172515c29385af29d993551f2af4dbd59c:done|++++++++++++++++++++++++++++++++++++++|elapsed:38.7stotal:65.2M(1.7 MiB/s) unpackinglinux/amd64sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...unpackinglinux/arm/v6sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...unpackinglinux/arm/v7sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...unpackinglinux/arm64/v8sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...unpackinglinux/386sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...unpackinglinux/ppc64lesha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...unpackinglinux/s390xsha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...done:5.731487623s[root@containerd ~]#ctr i export--all-platforms nginx.tar.gz docker.io/library/nginx:alpine[root@containerd ~]#ll -htotal187M-rw-r--r--1rootroot122MJul3001:16cri-containerd-cni-1.5.5-linux-amd64.tar.gz-rw-r--r--1rootroot66MOct2411:39nginx.tar.gz[root@containerd ~]#ctr i import nginx.tar.gzunpackingdocker.io/library/nginx:alpine(sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3)...done[root@containerd ~]#ctr i ls -qdocker.io/library/nginx:alpine[root@containerd ~]#
#测试2:--platform=linux/amd64参数 =>测试失败[root@containerd ~]#ctr i ls -qdocker.io/library/nginx:alpine[root@containerd ~]#ctr i rm docker.io/library/nginx:alpinedocker.io/library/nginx:alpine[root@containerd ~]#ctr i ls -q[root@containerd ~]#[root@containerd ~]#[root@containerd ~]#ctr i pull --platform=linux/amd64docker.io/library/nginx:alpinedocker.io/library/nginx:alpine:resolved|++++++++++++++++++++++++++++++++++++++|index-sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3:done|++++++++++++++++++++++++++++++++++++++|manifest-sha256:af466e4f12e3abe41fcfb59ca0573a3a5c640573b389d5287207a49d1324abd8:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:61074acc7dd227cfbeaf719f9b5cdfb64711bc6b60b3865c7b886b7099c15d15:done|++++++++++++++++++++++++++++++++++++++|config-sha256:513f9a9d8748b25cdb0ec6f16b4523af7bba216a6bf0f43f70af75b4cf7cb780:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:a0d0a0d46f8b52473982a3c466318f479767577551a53ffc9074c9fa7035982e:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:4dd4efe90939ab5711aaf5fcd9fd8feb34307bab48ba93030e8b845f8312ed8e:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:c1368e94e1ec563b31c3fb1fea02c9fbdc4c79a95e9ad0cac6df29c228ee2df3:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:3e72c40d0ff43c52c5cc37713b75053e8cb5baea8e137a784d480123814982a2:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:969825a5ca61c8320c63ff9ce0e8b24b83442503d79c5940ba4e2f0bd9e34df8:done|++++++++++++++++++++++++++++++++++++++|elapsed:20.3stotal:8.8Mi(445.4 KiB/s)unpackinglinux/amd64sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3...done:17.093491ms[root@containerd ~]#ctr i ls -qdocker.io/library/nginx:alpine[root@containerd ~]#[root@containerd ~]#[root@containerd ~]#rm -rf nginx.tar.gz[root@containerd ~]#ll -htotal122M-rw-r--r--1rootroot122MJul3001:16cri-containerd-cni-1.5.5-linux-amd64.tar.gz[root@containerd ~]#ctr i export--platform=linux/amd64 nginx.tar.gz docker.io/library/nginx:alpine[root@containerd ~]#ll -htotal131M-rw-r--r--1rootroot122MJul3001:16cri-containerd-cni-1.5.5-linux-amd64.tar.gz-rw-r--r--1rootroot9.6MOct2411:47nginx.tar.gz[root@containerd ~]#[root@containerd ~]#ctr i import nginx.tar.gzctr:contentdigestsha256:c8ca916e00dd0c56c91a81100ca79b668196642492153498e5d77619ccb55f9a:notfound[root@containerd ~]#ctr i import --platform=linux/amd64nginx.tar.gzIncorrectUsage:flagprovidedbutnotdefined:-platformNAME:ctrimagesimport-importimagesUSAGE:ctrimagesimport[command options][flags] <in>DESCRIPTION:Importimagesfromatarstream.Implementedformats:-oci.v1-docker.v1.1-docker.v1.2ForOCIv1,youmayneedtospecify--base-namebecauseanOCIarchivemaycontainonlypartialimagereferences(tags withoutthebaseimagename).Ifnobaseimagenameisprovided,anamewillbegeneratedas"import-%{yyyy-MM-dd}".e.g.$ctrimagesimport--base-namefoo/barfoobar.tarIffoobar.tarcontainsanOCIrefnamed"latest"andanonymousref"sha256:deadbeef",thecommandwillcreate"foo/bar:latest"and"foo/bar@sha256:deadbeef"imagesinthecontainerdstore.OPTIONS:--base-namevaluebaseimagenameforaddedimages,whenprovidedonlyimageswiththisnameprefixareimported--digestswhethertocreatedigestimages(default:false)--index-namevalueimagenametokeepindexas,bydefaultindexisdiscarded--all-platformsimportscontentforallplatforms,falsebydefault--no-unpackskipunpackingtheimages,falsebydefault--compress-blobscompressuncompressedblobswhencreatingmanifest(Docker formatonly)--snapshottervaluesnapshottername.Emptyvaluestandsforthedefaultvalue.[$CONTAINERD_SNAPSHOTTER]ctr:flagprovidedbutnotdefined:-platform[root@containerd ~]#ctr i import --all-platforms nginx.tar.gzctr:contentdigestsha256:826624c15f5e49e591d80f3e0c696f92a2d5967b989017572fe241edac294a2a:notfound[root@containerd ~]#
结论如下。
总结
经测试:01、在拉取镜像、导出镜像时,都加上--all-platforms时,最后在用ctriimportnginx.tar.gz就不会报错了;02、在拉取镜像、导出镜像时,都加上--platform=linux/amd64时,最后在用ctriimportnginx.tar.gz时依然报错;03、在拉起镜像时不添加任何--platform参数,最后在用ctriimportnginx.tar.gz也会报错;很无语,那么最后再拉取任何镜像时都要加上--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上。
[root@node1 ~]#ctr -n k8s.io i ls |grepprometheusdocker.io/prom/prometheus:v2.34.0application/vnd.docker.distribution.manifest.list.v2+jsonsha256:b37103e03399e90c9b7b1b2940894d3634915cf9df4aa2e5402bd85b4377808c74.4MiBlinux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390xio.cri-containerd.image=manageddocker.io/prom/prometheus@sha256:b37103e03399e90c9b7b1b2940894d3634915cf9df4aa2e5402bd85b4377808capplication/vnd.docker.distribution.manifest.list.v2+jsonsha256:b37103e03399e90c9b7b1b2940894d3634915cf9df4aa2e5402bd85b4377808c74.4MiBlinux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390xio.cri-containerd.image=managed[root@master1 ~]#ctr -n k8s.io i ls |grepprometheus[root@master1 ~]#
1、导出镜像
[root@node1 ~]#ctr -n k8s.io i exportprometheus.v2.34.0.tar.gz docker.io/prom/prometheus:v2.34.0
2、导入镜像
[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日
3、容器操作
容器相关操作可以通过 ctr container
获取。
1.创建容器
[root@containerd ~]#ctr c create docker.io/library/nginx:alpine nginx
2.列出容器
[root@containerd ~]#ctr c lsCONTAINERIMAGERUNTIMEnginxdocker.io/library/nginx:alpineio.containerd.runc.v2[root@containerd ~]#ctr c ls -q #同样可以加上 `-q` 选项精简列表内容:nginx[root@containerd ~]#
3.查看容器详细配置
类似于 docker inspect
功能。
[root@containerd ~]#ctr c info nginx{"ID":"nginx","Labels":{"io.containerd.image.config.stop-signal":"SIGQUIT"},"Image":"docker.io/library/nginx:alpine","Runtime":{"Name":"io.containerd.runc.v2","Options":{"type_url":"containerd.runc.v1.Options"}},"SnapshotKey":"nginx",……
4.删除容器
[root@containerd ~]#ctr c lsCONTAINERIMAGERUNTIMEnginxdocker.io/library/nginx:alpineio.containerd.runc.v2[root@containerd ~]#ctr c rm nginx [root@containerd ~]#ctr c lsCONTAINERIMAGERUNTIME[root@containerd ~]#
除了使用 rm
子命令之外也可以使用 delete
或者 del
删除容器。
[root@containerd ~]#ctr cNAME:ctrcontainers-managecontainersUSAGE:ctrcontainerscommand[command options][arguments...]COMMANDS:createcreatecontainerdelete,del,rmdeleteoneormoreexistingcontainers#注意infogetinfoaboutacontainerlist,lslistcontainerslabelsetandclearlabelsforacontainercheckpointcheckpointacontainerrestorerestoreacontainerfromcheckpointOPTIONS:--help,-hshowhelp[root@containerd ~]#
4、任务
上面我们通过 **container create**
命令创建的容器,并没有处于运行状态,只是一个静态的容器(仅仅只是一个创建容器的声明)。一个 container 对象只是包含了运行一个容器所需的资源及相关配置数据,表示 namespaces、rootfs 和容器的配置都已经初始化成功了,只是用户进程还没有启动。
一个容器真正运行起来是由 Task 任务实现的,Task 可以为容器设置网卡,还可以配置工具来对容器进行监控等。
1.启动一个容器
Task 相关操作可以通过 ctr task
获取,如下我们通过 Task 来启动容器:
[root@containerd ~]#ctr task start -d nginx/docker-entrypoint.sh:/docker-entrypoint.d/isnotempty,willattempttoperformconfiguration/docker-entrypoint.sh:Lookingforshellscriptsin/docker-entrypoint.d//docker-entrypoint.sh:Launching/docker-entrypoint.d/10-listen-on-ipv6-by-default.sh[root@containerd ~]#
2.查看正在运行的容器
启动容器后可以通过 task ls
查看正在运行的容器:
[root@containerd ~]#ctr task lsTASKPIDSTATUSnginx24458RUNNING[root@containerd ~]#ctr task ls -qnginx[root@containerd ~]#
3.进入到容器里面
同样也可以使用 exec
命令进入容器进行操作:
[root@containerd ~]#ctr task exec --exec-id 0 -t nginx sh/# lsbinmediasrvdevmntsysdocker-entrypoint.dopttmpdocker-entrypoint.shprocusretcrootvarhomerunlibsbin/# psPIDUSERTIMECOMMAND1root0:00nginx:masterprocessnginx-gdaemonoff;32nginx0:00nginx:workerprocess33nginx0:00nginx:workerprocess34root0:00sh41root0:00ps/#
不过这里需要注意必须要指定 --exec-id
参数,这个 id 可以随便写,只要唯一就行。
4.暂停容器
暂停容器,和 docker pause
类似的功能:
[root@containerd ~]#ctr task pause nginx
暂停后容器状态变成了 PAUSED
:
[root@containerd ~]#ctr task lsTASKPIDSTATUSnginx24458PAUSED[root@containerd ~]#
5.恢复容器
同样也可以使用 resume
命令来恢复容器:
[root@containerd ~]#ctr t resume nginx #resume 继续,重新开始[root@containerd ~]#ctr task lsTASKPIDSTATUSnginx24458RUNNING[root@containerd ~]#
6.杀死容器
**不过需要注意 ctr 没有 stop 容器的功能,只能暂停或者杀死容器。**杀死容器可以使用 task kill
命令:
[root@containerd ~]#ctr t kill nginx[root@containerd ~]#ctr task lsTASK PID STATUSnginx 24458 STOPPED[root@containerd ~]#
7.删除task
杀掉容器后可以看到容器的状态变成了 STOPPED
。同样也可以通过 task rm
命令删除 Task:
[root@containerd ~]#ctr t rm nginx[root@containerd ~]#ctr task lsTASK PID STATUS[root@containerd ~]#
- 问题:处于正在runnning的Task可以被删除吗?
测试过程:
[root@containerd ~]#ctr c lsCONTAINERIMAGERUNTIMEnginxdocker.io/library/nginx:alpineio.containerd.runc.v2[root@containerd ~]#ctr t start -d nginx[root@containerd ~]#ctr t lsTASKPIDSTATUSnginx24713RUNNING[root@containerd ~]#ctr t rm nginxERRO[0000]unabletodeletenginxerror="task must be stopped before deletion:running:failed precondition"ctr:taskmustbestoppedbeforedeletion:running:failedprecondition[root@containerd ~]#[root@containerd ~]## 由以上测试可以知道,要想删除一个正在运行的Task,必须先kill掉这个task,然后才能删除task,否则会报错;[root@containerd ~]#ctr t kill nginx[root@containerd ~]#ctr t rm nginx[root@containerd ~]#ctr t lsTASKPIDSTATUS[root@containerd ~]#
结论:由以上测试可以知道,要想删除一个正在运行的Task,必须先kill掉这个task,然后才能删除。
8.取容器的内存、CPU 和 PID 的限额与使用量
除此之外我们还可以获取容器的 cgroup 相关信息,可以使用 task metrics
命令用来获取容器的内存、CPU 和 PID 的限额与使用量。
[root@containerd ~]#ctr t metrics nginxIDTIMESTAMPnginx2021-10-2405:54:38.74392351+0000UTCMETRICVALUEmemory.usage_in_bytes1986560memory.limit_in_bytes9223372036854771712memory.stat.cache16384cpuacct.usage63033641cpuacct.usage_percpu[17342796 45690845]pids.current3pids.limit0[root@containerd ~]#
9.查看容器中所有进程在宿主机中的 PID:
还可以使用 task ps
命令查看容器中所有进程在宿主机中的 PID:
[root@containerd ~]#ctr t lsTASKPIDSTATUSnginx24841RUNNING[root@containerd ~]#ctr t ps nginxPIDINFO24841-24873-24874-[root@containerd ~]#ps -ef|grepnginxroot248221013:54?00:00:00/usr/local/bin/containerd-shim-runc-v2-namespacedefault-idnginx-address/run/containerd/containerd.sockroot2484124822013:54?00:00:00nginx:masterprocessnginx-gdaemonoff;1012487324841013:54?00:00:00nginx:workerprocess1012487424841013:54?00:00:00nginx:workerprocessroot2491724303013:56pts/000:00:00grep--color=autonginx[root@containerd ~]#
其中第一个 PID 24841
就是我们容器中的1号进程。
5、命名空间
1.查看命名空间
另外 Containerd 中也支持命名空间的概念,比如查看命名空间:
[root@containerd ~]#ctr ns lsNAME LABELSdefault[root@containerd ~]#
2.创建命名空间
如果不指定,ctr 默认使用的是 default
空间。同样也可以使用 ns create
命令创建一个命名空间:
[root@containerd ~]#ctr ns create test[root@containerd ~]#ctr ns lsNAME LABELSdefaulttest[root@containerd ~]#
3.删除命名空间
使用 remove
或者 rm
可以删除 namespace:
[root@containerd ~]#ctr ns lsNAMELABELSdefaulttest[root@containerd ~]#ctr ns rm test #删除命名空间test[root@containerd ~]#ctr ns lsNAMELABELSdefault[root@containerd ~]#
4.指定命名空间选项
有了命名空间后就可以在操作资源的时候指定 namespace,比如查看 test 命名空间的镜像,可以在操作命令后面加上 -n test
选项:
[root@containerd ~]#ctr i ls -qdocker.io/library/nginx:alpine[root@containerd ~]#ctr -n test i ls -q[root@containerd ~]#
注意:
我们知道 Docker 其实也是默认调用的 containerd,事实上 Docker 使用的 containerd 下面的命名空间默认是 moby
,而不是 default
,所以假如我们有用 docker 启动容器,那么我们也可以通过 ctr -n moby
来定位下面的容器:
[root@containerd ~]#ctr -n moby c lsCONTAINER IMAGE RUNTIME[root@containerd ~]#
同样 Kubernetes 下使用的 containerd 默认命名空间是 k8s.io
,所以我们可以使用 ctr -n k8s.io
来查看 Kubernetes 下面创建的容器。
[root@containerd ~]#ctr -n k8s.io c lsCONTAINERIMAGERUNTIME[root@containerd ~]#
注意:这3者之间的ns是不同的,要区分开。
FAQ
注意:在导入镜像时遇到的报错问题处理方法
直接导入可能会出现类似于 ctr:content digest sha256:xxxxxx not found
的错误,要解决这个办法需要 pull 所有平台镜像:
解决办法如下:
➜ ~ctr i pull --all-platforms docker.io/library/nginx:alpine➜ ~ctr i export --all-platforms nginx.tar.gz docker.io/library/nginx:alpine➜ ~ctr i rm docker.io/library/nginx:alpine➜ ~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工具检查和调试容器。
下面是docker与crictl命令对照表:
[root@containerd ~]#crictl version #这个crictl命令可以在k8s里查看一些pod信息Version:0.1.0RuntimeName:containerdRuntimeVersion:v1.5.7RuntimeApiVersion:v1alpha2[root@containerd ~]#containerd客户端CLI:ctr:这个很难用;#目前就是用ctr命令就可以可,相当于docker,但比docker难用的很多。nerctl:这个很高级的;
- crictl命令
crictlpods#查看当前节点pod信息crictlps#查看当前节点容器信息
- 查看下主容器的信息:
➜~crictlinspectbcbbf88a9ac29"status":{"id":"bcbbf88a9ac29d84700525b4c898171889510b372b45a77f1c9757fdef3793a2","metadata":{"attempt":0,"name":"resource-demo1"},"state":"CONTAINER_RUNNING","createdAt":"2021-11-07T16:46:37.069325484+08:00","startedAt":"2021-11-07T16:46:37.412557847+08:00","finishedAt":"0001-01-01T00:00:00Z","exitCode":0,"image":{"annotations":{},"image":"docker.io/library/nginx:latest"},......"linux":{"resources":{"devices":[{"allow":false,"access":"rwm"}],"memory":{"limit":104857600},"cpu":{"shares":51,"quota":10000,"period":100000}},"cgroupsPath":"kubepods-burstable-pod7e80487d_24d7_44af_bf38_c43b6dfe4045.slice:cri-containerd:bcbbf88a9ac29d84700525b4c898171889510b372b45a77f1c9757fdef3793a2",......
关于我
我的博客主旨:我希望每一个人拿着我的博客都可以做出实验现象,先把实验做出来,然后再结合理论知识更深层次去理解技术点,这样学习起来才有乐趣和动力。并且,我的博客内容步骤是很完整的,也分享源码和实验用到的软件,希望能和大家一起共同进步!
各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人免费帮您解决问题:
- 个人微信二维码:x2675263825 (舍得), qq:2675263825。
- 个人博客地址:www.onlyonexl.cn
- 个人微信公众号:云原生架构师实战
- 个人csdn https: