07 Container Engine Containerd Practical Implementation

07 Container Engine containerd Practical Implementation #

Since Docker released its container engine Docker in 2013, it has been used by developers worldwide and continuously improved its functionality. With the establishment of container standards, the Docker engine architecture has also transitioned from a monolithic structure to a microservices structure, resulting in the extraction of the containerd engine. Its position in the entire container technology architecture is as follows:

containerd-arch

Figure 6-1 containerd architecture diagram, copyright from https://containerd.io/

Initial Experience with containerd #

The latest containerd executable can be downloaded from the official repository. Since it depends on runc, it needs to be downloaded together to work properly:

# Download containerd binary
wget -q --show-progress --https-only --timestamping \
  https://github.com/opencontainers/runc/releases/download/v1.0.0-rc10/runc.amd64 \
  https://github.com/containerd/containerd/releases/download/v1.3.4/containerd-1.3.4.linux-amd64.tar.gz \
  https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.18.0/crictl-v1.18.0-linux-amd64.tar.gz
sudo mv runc.amd64 runc

# Install binary
tar -xvf crictl-v1.18.0-linux-amd64.tar.gz
chmod +x crictl runc
sudo cp crictl runc /usr/local/bin/
mkdir containerd
tar -xvf containerd-1.3.4.linux-amd64.tar.gz -C containerd
sudo cp containerd/bin/* /bin/

containerd provides a default configuration file config.toml, which is usually placed in /etc/containerd/config.toml:

[plugins]
  [plugins.cri.containerd]
    snapshotter = "overlayfs"
    [plugins.cri.containerd.default_runtime]
      runtime_type = "io.containerd.runtime.v1.linux"
      runtime_engine = "/usr/local/bin/runc"
      runtime_root = ""

containerd services are generally run as background daemons, using systemd on Linux:

# Configure containerd.service
sudo cat <<EOF | sudo tee /etc/systemd/system/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target
[Service]
ExecStartPre=/sbin/modprobe overlay
ExecStart=/bin/containerd
Restart=always
RestartSec=5
Delegate=yes
KillMode=process
OOMScoreAdjust=-999
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
EOF

# Start
sudo systemctl daemon-reload
sudo systemctl enable containerd
sudo systemctl start containerd

# Configure crictl client
sudo crictl config runtime-endpoint unix:///var/run/containerd/containerd.sock

At this point, the usage process of containerd is complete.

Understanding containerd in Depth through the Client #

After containerd is started, we need to use the client command-line tools to understand the state of container runtime. At this time, we have 2 tools at hand. One is crictl, which is a client tool provided by the Kubernetes community for operating the container standard interface. The other is ctr, which is a client tool that comes with containerd. ctr is a testing tool, and it is recommended to use crictl in daily work for managing containers.

ctr tool runs as follows:

ctr -
        __
  _____/ /______
 / ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/

containerd CLI

USAGE:
   ctr [global options] command [command options] [arguments...]

VERSION:
   v1.3.4

DESCRIPTION:
ctr is an unsupported debug and administrative client for interacting
with the containerd daemon. Because it is unsupported, the commands,
options, and operations are not guaranteed to be backward compatible or
stable from release to release of the containerd project.

COMMANDS:
   plugins, plugin            provides information about containerd plugins
   version                    print the client and server versions
   containers, c, container   manage containers
   content                    manage content
   events, event              display containerd events
   images, image, i           manage images
   leases                     manage leases
   namespaces, namespace, ns  manage namespaces
   pprof                      provide golang pprof outputs for containerd
   run                        run a container
   snapshots, snapshot        manage snapshots
   tasks, t, task             manage tasks
   install                    install a new package
   shim                       interact with a shim directly
   help, h                    Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug                      enable debug output in logs
   --address value, -a value    address for containerd's GRPC server (default: "/run/contai
nerd/containerd.sock")
   --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") [$CONTA
INERD_NAMESPACE]
   --help, -h                   show help
   --version, -v                print the version

The crictl command is used to manage container runtime interface (CRI) and has more functionality compared to the ctr command. Below is a comparison of crictl and Docker commands for easy reference:

Image-related functionality:

Docker crictl
docker images crictl images
docker pull crictl pull
docker push Not available
docker rmi crictl rmi
docker inspect IMAGE-ID crictl inspecti IMAGE-ID

Container-related functionality:

Docker crictl
docker ps crictl ps
docker create crictl create
docker start crictl start
docker stop crictl stop
docker rm crictl rm
docker inspect crictl inspect
docker attach crictl attach
docker exec crictl exec
docker logs crictl logs
docker stats crictl stats

Containerd and Docker have similar functionality, and using containerd in production environments can reduce dependencies.

In a Kubernetes environment, the calling hierarchy for Docker as a container runtime is: kubelet –> docker shim (within kubelet process) –> dockerd –> containerd

The calling hierarchy for containerd as a container runtime is: kubelet –> cri plugin (within containerd process) –> containerd

Note that dockerd is a native Docker container application engine that provides additional features such as swarm clusters, docker build, docker push, and docker API. However, in production environments, Kubernetes clusters are used by default, so these features can be excluded.

Regarding Docker container logs and network configuration:

Log comparison:

Docker containerd
Log storage location If Docker is used as a Kubernetes container runtime, container logs are stored in directories similar to /var/lib/docker/containers/$CONTAINERID. Kubelet creates symbolic links in /var/log/pods and /var/log/containers that point to the container log files in /var/lib/docker/containers/$CONTAINERID.

CNI network comparison:

Docker containerd
CNI calling responsibility docker-shim within Kubelet
CNI configuration Kubelet parameters --cni-bin-dir and --cni-conf-dir

In summary, containerd is the standardized container engine that emerged from the Docker container deployment process. It has been refined through countless global enterprise application scenarios, making it a reliable tool. Despite the industry’s avoidance of Docker’s products, containerd is the best container engine for production environments and deserves continued attention and support.