This quick note is mainly about CLI ctr
, please note that ctr
tool is made for
debugging containerd. It doesn’t support all the features you may be used to
from docker such as port publishing, automatic container restart on failure, or
browsing container logs.
Recommended containerd course: link.
Containerd Daemon
Assume you have containerd installed:
1 | sudo systemctl status containerd |
Namespace
You can have both docker and containerd containers running in the same server, docker
is also using containerd as the underlying runtime, if you have ctr
available
you would be able to examine the relationship:
1 | $ ctr ns ls |
Container and Task
The separation of containers and tasks in ctr
(and in containerd’s architecture)
might seem a bit different from Docker’s more unified view of a running container.
A container in containerd is primarily an isolated metadata and configuration entity. It doesn’t have a running process (task) associated with it yet. So you can have a container in containerd without anyone live task(the init process) running, it is just empty.
Please note that in containerd, one container has only one task (init process), one task can have more than one processes!
Commands
Image Pull
Let’s see an example to demonstrate the container vs task in containerd, I have
the ctr
alias setup like below for target namespace:
1 | alias ctr='sudo ctr -n ns1' |
Please note that even the image is also associated with namespace! Also You have
to pull it first, ctr
won’t do it auto for you when you create a container:
1 | $ ctr image pull docker.io/library/alpine:latest |
List the local images:
1 | # -q: only show image path |
Inspect Image Internals
Instead of running a container with task and exec into it, one way to check the image internal (e.g the built-in files) is to mount a local folder to image and go to check the local folder:
1 | $ mkdir /tmp/agent_rootfs |
Create Container
Then, create a container named as test
and give it a default process /bin/sh
,
if you don’t specify a command, it might use the default command from the image’s
configuration (which might just exit immediately if it’s not designed to run
indefinitely).
1 | ctr c create docker.io/library/alpine:latest test /bin/sh |
Check the container is created:
1 | $ ctr c ls |
You can view the arg bin/sh
we specified in args
field:
1 | ctr c info test | grep -A3 args |
Sometimes you want to check the container start timestamp:
1 | ctr c info test | jq -r '.UpdatedAt' |
Please note that no task is running from test
container so far:
1 | # you should see empty result |
Start Container
Now start the container in detached mode, this command starts the initial task
associated with the container test
. By default, the init task ID will be the
same as the container ID, the /bin/sh
is the init process of the task
1 | $ ctr t start -d test |
Create Children Process
Let’s create 3 processes for task test
:
1 | ctr t exec -d --exec-id pro1 test /bin/sh |
Now check the processes in container test
, please note we still have only one
task ctr t ls | grep test
:
1 | $ ctr t ps test |
The PID here like 125191
, 125221
, 125250
is the host PID of the process,
so you kill them from host, also ps -aux | grep
can be used to find the process
in host VM, to kill the process pro1
:
1 | sudo kill -9 125191 |
Exec into Container
To exec into the container, you need to specify a process name:
1 | # foo ps name |
Or using a random ps name:
1 | ctr t exec -t --exec-id ${RANDOM} test sh |
Remove
Finally, kill the task test
:
1 | ctr t kill -s 9 test |
Clean up the task test
:
1 | ctr t rm -f test |
Clean up the container test
:
1 | ctr c rm test |
Containerd Container Lifecycle Management
As we mentioned containerd or ctr does not have a restart on failure config like docker, one way to restart on failure is to set up systemd service, for example:
1 | $ systemctl status example.service |
1 | $ cat /etc/systemd/system/example.service |