ctr 使用

ctr 目前很多功能做的还没有 docker 那么完善,但基本功能已经具备了。下面将围绕镜像容器这两个方面来介绍其使用方法。

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

镜像

镜像下载
  1. # ctr i pull docker.io/library/nginx:alpine
  2. docker.io/library/nginx:alpine: resolved |++++++++++++++++++++++++++++++++++++++|
  3. index-sha256:e20c21e530f914fb6a95a755924b1cbf71f039372e94ac5ddcf8c3b386a44615: done |++++++++++++++++++++++++++++++++++++++|
  4. manifest-sha256:96419b83f29b198ae9f63670d5a28325a8bc9ebaf76c1260cf15eca3a521ebd0: done |++++++++++++++++++++++++++++++++++++++|
  5. layer-sha256:5b4dcb4d3646b218b442697b56990ca56997efa87f6861388164cc46d353659a: done |++++++++++++++++++++++++++++++++++++++|
  6. config-sha256:5fd75c905b52a175660818ab9f318cfab375da0b90d23690e00871c0db1ed3a4: done |++++++++++++++++++++++++++++++++++++++|
  7. layer-sha256:ba3557a56b150f9b813f9d02274d62914fd8fce120dd374d9ee17b87cf1d277d: done |++++++++++++++++++++++++++++++++++++++|
  8. layer-sha256:468d8ccebf7a1512bde09f06975206a7f474c714f96020dabb6e3437a3bc426b: done |++++++++++++++++++++++++++++++++++++++|
  9. layer-sha256:b7f67c5d6ce97f864346b65ed55571f7d191c0f9518ac59bb1b7291fbae0f716: done |++++++++++++++++++++++++++++++++++++++|
  10. layer-sha256:ed91f01a4fcb8de36c14f0048c15971b7a2d8eaf4740c9d2855de94e19467cd7: done |++++++++++++++++++++++++++++++++++++++|
  11. layer-sha256:8051568c89ac729bba391cc909f7eb97ad3e0bc6991db52ad3b5a7bb4cc6c000: done |++++++++++++++++++++++++++++++++++++++|
  12. elapsed: 15.5s total: 8.7 Mi (574.3 KiB/s)
  13. unpacking linux/amd64 sha256:e20c21e530f914fb6a95a755924b1cbf71f039372e94ac5ddcf8c3b386a44615...
  14. done

本地镜像列表查询
  1. root@i-gqqsb62d:/etc/containerd# ctr i ls
  2. REF TYPE DIGEST SIZE PLATFORMS
  3. LABELS
  4. docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:e20c21e530f914fb6a95a755924b1cbf71f039372e94ac5ddcf8c3b386a44615 9.4 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -

这里需要注意PLATFORMS,它是镜像的能够运行的平台标识。

将镜像挂载到主机目录:
  1. ctr i mount docker.io/library/nginx:alpine /mnt/nginx_tmp/
  2. sha256:22dd1c631d282d9c89a77fb4592d8f32dcc4e946228cf0b671a2d37c2511e1dc
  3. /mnt/nginx_tmp/
  1. # tree /mnt/nginx_tmp/ -L 1
  2. /mnt/nginx_tmp/
  3. ├── bin
  4. ├── dev
  5. ├── docker-entrypoint.d
  6. ├── docker-entrypoint.sh
  7. ├── etc
  8. ├── home
  9. ├── lib
  10. ├── media
  11. ├── mnt
  12. ├── opt
  13. ├── proc
  14. ├── root
  15. ├── run
  16. ├── sbin
  17. ├── srv
  18. ├── sys
  19. ├── tmp
  20. ├── usr
  21. └── var

讲镜像从主机卸载
  1. # ctr i unmount /mnt/nginx_tmp/
  2. /mnt/nginx_tmp/

镜像包导出为压缩包
  1. root@i-gqqsb62d:~# ctr i export nginx.tar.gz docker.io/library/nginx:alpine
  2. root@i-gqqsb62d:~# ls nginx.tar.gz
  3. nginx.tar.gz

删除
  1. root@i-gqqsb62d:~# ctr i remove docker.io/library/nginx:alpine
  2. docker.io/library/nginx:alpine
  3. root@i-gqqsb62d:~# ctr i ls
  4. REF TYPE DIGEST SIZE PLATFORMS LABELS

导入
  1. root@i-gqqsb62d:~# ctr i import nginx.tar.gz
  2. unpacking docker.io/library/nginx:alpine (sha256:e20c21e530f914fb6a95a755924b1cbf71f039372e94ac5ddcf8c3b386a44615)...done
  3. root@i-gqqsb62d:~# ctr i ls
  4. REF TYPE DIGEST SIZE PLATFORMS
  5. LABELS
  6. docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:e20c21e530f914fb6a95a755924b1cbf71f039372e94ac5ddcf8c3b386a44615 9.4 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -

其他
  1. root@i-gqqsb62d:~# ctr i -h
  2. NAME:
  3. ctr images - manage images
  4. USAGE:
  5. ctr images command [command options] [arguments...]
  6. COMMANDS:
  7. check check that an image has all content available locally
  8. export export images
  9. import import images
  10. list, ls list images known to containerd
  11. mount mount an image to a target path
  12. unmount unmount the image from the target
  13. pull pull an image from a remote
  14. push push an image to a remote
  15. remove, rm remove one or more images by reference
  16. tag tag an image
  17. label set and clear labels for an image
  18. OPTIONS:
  19. --help, -h show help

容器

创建容器
  1. root@i-gqqsb62d:~# ctr c create docker.io/library/nginx:alpine
  2. ctr: container id must be provided: invalid argument
  3. root@i-gqqsb62d:~# ctr c create docker.io/library/nginx:alpine nginx
  4. root@i-gqqsb62d:~# ctr c ls
  5. CONTAINER IMAGE RUNTIME
  6. nginx docker.io/library/nginx:alpine io.containerd.runc.v2

查看容器详细配置
  1. # 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. "Snapshotter": "overlayfs",
  16. "CreatedAt": "2021-03-23T06:00:08.021700023Z",
  17. "UpdatedAt": "2021-03-23T06:00:08.021700023Z",
  18. "Extensions": null,
  19. "Spec": {
  20. "ociVersion": "1.0.2-dev",
  21. "process": {
  22. "user": {
  23. "uid": 0,
  24. "gid": 0,
  25. "additionalGids": [
  26. 1,
  27. 2,
  28. 3,
  29. 4,
  30. 6,
  31. 10,
  32. 11,
  33. 20,
  34. 26,
  35. 27
  36. ]
  37. },
  38. "args": [
  39. "/docker-entrypoint.sh",
  40. "nginx",
  41. "-g",
  42. "daemon off;"
  43. ],
  44. "env": [
  45. "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
  46. "NGINX_VERSION=1.19.8",
  47. "NJS_VERSION=0.5.2",
  48. "PKG_RELEASE=1"
  49. ],
  50. "cwd": "/",
  51. "capabilities": {
  52. "bounding": [
  53. "CAP_CHOWN",
  54. "CAP_DAC_OVERRIDE",
  55. "CAP_FSETID",
  56. "CAP_FOWNER",
  57. "CAP_MKNOD",
  58. "CAP_NET_RAW",
  59. "CAP_SETGID",
  60. "CAP_SETUID",
  61. "CAP_SETFCAP",
  62. "CAP_SETPCAP",
  63. "CAP_NET_BIND_SERVICE",
  64. "CAP_SYS_CHROOT",
  65. "CAP_KILL",
  66. "CAP_AUDIT_WRITE"
  67. ],
  68. "effective": [
  69. "CAP_CHOWN",
  70. "CAP_DAC_OVERRIDE",
  71. "CAP_FSETID",
  72. "CAP_FOWNER",
  73. "CAP_MKNOD",
  74. "CAP_NET_RAW",
  75. "CAP_SETGID",
  76. "CAP_SETUID",
  77. "CAP_SETFCAP",
  78. "CAP_SETPCAP",
  79. "CAP_NET_BIND_SERVICE",
  80. "CAP_SYS_CHROOT",
  81. "CAP_KILL",
  82. "CAP_AUDIT_WRITE"
  83. ],
  84. "inheritable": [
  85. "CAP_CHOWN",
  86. "CAP_DAC_OVERRIDE",
  87. "CAP_FSETID",
  88. "CAP_FOWNER",
  89. "CAP_MKNOD",
  90. "CAP_NET_RAW",
  91. "CAP_SETGID",
  92. "CAP_SETUID",
  93. "CAP_SETFCAP",
  94. "CAP_SETPCAP",
  95. "CAP_NET_BIND_SERVICE",
  96. "CAP_SYS_CHROOT",
  97. "CAP_KILL",
  98. "CAP_AUDIT_WRITE"
  99. ],
  100. "permitted": [
  101. "CAP_CHOWN",
  102. "CAP_DAC_OVERRIDE",
  103. "CAP_FSETID",
  104. "CAP_FOWNER",
  105. "CAP_MKNOD",
  106. "CAP_NET_RAW",
  107. "CAP_SETGID",
  108. "CAP_SETUID",
  109. "CAP_SETFCAP",
  110. "CAP_SETPCAP",
  111. "CAP_NET_BIND_SERVICE",
  112. "CAP_SYS_CHROOT",
  113. "CAP_KILL",
  114. "CAP_AUDIT_WRITE"
  115. ]
  116. },
  117. "rlimits": [
  118. {
  119. "type": "RLIMIT_NOFILE",
  120. "hard": 1024,
  121. "soft": 1024
  122. }
  123. ],
  124. "noNewPrivileges": true
  125. },
  126. "root": {
  127. "path": "rootfs"
  128. },
  129. "mounts": [
  130. {
  131. "destination": "/proc",
  132. "type": "proc",
  133. "source": "proc",
  134. "options": [
  135. "nosuid",
  136. "noexec",
  137. "nodev"
  138. ]
  139. },
  140. {
  141. "destination": "/dev",
  142. "type": "tmpfs",
  143. "source": "tmpfs",
  144. "options": [
  145. "nosuid",
  146. "strictatime",
  147. "mode=755",
  148. "size=65536k"
  149. ]
  150. },
  151. {
  152. "destination": "/dev/pts",
  153. "type": "devpts",
  154. "source": "devpts",
  155. "options": [
  156. "nosuid",
  157. "noexec",
  158. "newinstance",
  159. "ptmxmode=0666",
  160. "mode=0620",
  161. "gid=5"
  162. ]
  163. },
  164. {
  165. "destination": "/dev/shm",
  166. "type": "tmpfs",
  167. "source": "shm",
  168. "options": [
  169. "nosuid",
  170. "noexec",
  171. "nodev",
  172. "mode=1777",
  173. "size=65536k"
  174. ]
  175. },
  176. {
  177. "destination": "/dev/mqueue",
  178. "type": "mqueue",
  179. "source": "mqueue",
  180. "options": [
  181. "nosuid",
  182. "noexec",
  183. "nodev"
  184. ]
  185. },
  186. {
  187. "destination": "/sys",
  188. "type": "sysfs",
  189. "source": "sysfs",
  190. "options": [
  191. "nosuid",
  192. "noexec",
  193. "nodev",
  194. "ro"
  195. ]
  196. },
  197. {
  198. "destination": "/run",
  199. "type": "tmpfs",
  200. "source": "tmpfs",
  201. "options": [
  202. "nosuid",
  203. "strictatime",
  204. "mode=755",
  205. "size=65536k"
  206. ]
  207. }
  208. ],
  209. "linux": {
  210. "resources": {
  211. "devices": [
  212. {
  213. "allow": false,
  214. "access": "rwm"
  215. },
  216. {
  217. "allow": true,
  218. "type": "c",
  219. "major": 1,
  220. "minor": 3,
  221. "access": "rwm"
  222. },
  223. {
  224. "allow": true,
  225. "type": "c",
  226. "major": 1,
  227. "minor": 8,
  228. "access": "rwm"
  229. },
  230. {
  231. "allow": true,
  232. "type": "c",
  233. "major": 1,
  234. "minor": 7,
  235. "access": "rwm"
  236. },
  237. {
  238. "allow": true,
  239. "type": "c",
  240. "major": 5,
  241. "minor": 0,
  242. "access": "rwm"
  243. },
  244. {
  245. "allow": true,
  246. "type": "c",
  247. "major": 1,
  248. "minor": 5,
  249. "access": "rwm"
  250. },
  251. {
  252. "allow": true,
  253. "type": "c",
  254. "major": 1,
  255. "minor": 9,
  256. "access": "rwm"
  257. },
  258. {
  259. "allow": true,
  260. "type": "c",
  261. "major": 5,
  262. "minor": 1,
  263. "access": "rwm"
  264. },
  265. {
  266. "allow": true,
  267. "type": "c",
  268. "major": 136,
  269. "access": "rwm"
  270. },
  271. {
  272. "allow": true,
  273. "type": "c",
  274. "major": 5,
  275. "minor": 2,
  276. "access": "rwm"
  277. },
  278. {
  279. "allow": true,
  280. "type": "c",
  281. "major": 10,
  282. "minor": 200,
  283. "access": "rwm"
  284. }
  285. ]
  286. },
  287. "cgroupsPath": "/default/nginx",
  288. "namespaces": [
  289. {
  290. "type": "pid"
  291. },
  292. {
  293. "type": "ipc"
  294. },
  295. {
  296. "type": "uts"
  297. },
  298. {
  299. "type": "mount"
  300. },
  301. {
  302. "type": "network"
  303. }
  304. ],
  305. "maskedPaths": [
  306. "/proc/acpi",
  307. "/proc/asound",
  308. "/proc/kcore",
  309. "/proc/keys",
  310. "/proc/latency_stats",
  311. "/proc/timer_list",
  312. "/proc/timer_stats",
  313. "/proc/sched_debug",
  314. "/sys/firmware",
  315. "/proc/scsi"
  316. ],
  317. "readonlyPaths": [
  318. "/proc/bus",
  319. "/proc/fs",
  320. "/proc/irq",
  321. "/proc/sys",
  322. "/proc/sysrq-trigger"
  323. ]
  324. }
  325. }
  326. }

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

任务

上面 create 的命令创建了容器后,并没有处于运行状态,只是一个静态的容器。所以还需要启动容器,task 代表任务的意思:

  1. root@i-gqqsb62d:~# ctr task ls
  2. TASK PID STATUS
  3. root@i-gqqsb62d:~# ctr task start -d nginx
  4. /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
  5. /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
  6. /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
  7. root@i-gqqsb62d:~# ctr task ls
  8. TASK PID STATUS
  9. nginx 7931 RUNNING

当然,也可以一步到位直接创建并运行容器:

  1. root@i-gqqsb62d:~# ctr run -d docker.io/library/nginx:alpine nginx1
  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@i-gqqsb62d:~# ctr task ls
  6. TASK PID STATUS
  7. nginx1 8075 RUNNING
  8. nginx 7931 RUNNING

进入容器

和 docker 的操作类似,但必须要指定 —exec-id,这个 id 可以随便写,只要唯一就行

  1. root@i-gqqsb62d:~# ctr task exec --exec-id 0 -t nginx sh
  2. / #
  3. / # ls
  4. bin media srv
  5. dev mnt sys
  6. docker-entrypoint.d opt tmp
  7. docker-entrypoint.sh proc usr
  8. etc root var
  9. home run
  10. lib sbin

暂停容器
  1. root@i-gqqsb62d:~# ctr task ls
  2. TASK PID STATUS
  3. nginx 7931 RUNNING
  4. nginx1 8075 RUNNING
  5. root@i-gqqsb62d:~# ctr task pause nginx
  6. root@i-gqqsb62d:~# ctr task ls
  7. TASK PID STATUS
  8. nginx 7931 PAUSED
  9. nginx1 8075 RUNNING

恢复
  1. root@i-gqqsb62d:~# ctr task resume nginx
  2. root@i-gqqsb62d:~# ctr task ls
  3. TASK PID STATUS
  4. nginx 7931 RUNNING
  5. nginx1 8075 RUNNING

杀死容器
  1. root@i-gqqsb62d:~# ctr task kill nginx
  2. root@i-gqqsb62d:~# ctr task ls
  3. TASK PID STATUS
  4. nginx 7931 STOPPED
  5. nginx1 8075 RUNNING

获取cgroup信息
  1. root@i-gqqsb62d:~# ctr task metrics nginx
  2. ID TIMESTAMP
  3. nginx 2021-03-23 06:08:00.601588973 +0000 UTC
  4. METRIC VALUE
  5. memory.usage_in_bytes 716800
  6. memory.limit_in_bytes 9223372036854771712
  7. memory.stat.cache 61440
  8. cpuacct.usage 61135700
  9. cpuacct.usage_percpu [61135700]
  10. pids.current 0
  11. pids.limit 0
  12. root@i-gqqsb62d:~# ctr task metrics nginx1
  13. ID TIMESTAMP
  14. nginx1 2021-03-23 06:08:07.026595123 +0000 UTC
  15. METRIC VALUE
  16. memory.usage_in_bytes 2162688
  17. memory.limit_in_bytes 9223372036854771712
  18. memory.stat.cache 57344
  19. cpuacct.usage 46920481
  20. cpuacct.usage_percpu [46920481]
  21. pids.current 2
  22. pids.limit 0
  23. root@i-gqqsb62d:~#

查看容器中所有进程的 PID

  1. root@i-gqqsb62d:~# ctr task ps nginx
  2. PID INFO
  3. root@i-gqqsb62d:~# ctr task ps nginx1
  4. PID INFO
  5. 8075 -
  6. 8112 -

注意:这里的 PID 是宿主机看到的 PID,不是容器中看到的 PID。

命名空间

除了 k8s 有命名空间以外,Containerd 也支持命名空间。

  1. root@i-gqqsb62d:~# ctr ns ls
  2. NAME LABELS
  3. default