Hoofungson's Tech Blog
Search
Switch languageEnglish
Open menu

Installing Containerd: the Binary Way

Installing containerd 1.7 and runC from the cri-containerd-cni tarball: where each unpacked file goes, how the systemd unit is installed, and how to adjust the default config.toml and registry mirrors.

On this page17 sections

1. Environment

1.1 Host specification

Name OS CPU Memory Private IP Public IP
ECS openEuler 22.03 LTS SP3 2 cores 2GB 192.0.2.18 203.0.113.222

1.2 Versions

Name Version Notes
Containerd 1.7.11 –
RunC 1.1.11 –

1.3 Download

Containerd ships in two kinds of package:

  • containerd-xxx — fine for single-machine testing, but it does not include runC, which you have to install separately.
  • cri-containerd-cni-xxxx — bundles runC together with the files K8s needs. This is the one to use for a K8s cluster. Even though runC is bundled, it depends on the system’s seccomp support (secure computing mode — a mode that restricts which system resources a container may call).

Download the package:

[root@localhost]# wget https://github.com/containerd/containerd/releases/download/v1.7.11/cri-containerd-cni-1.7.11-linux-amd64.tar.gz

2. Installing containerd

2.1 Unpack

[root@localhost]# tar xf cri-containerd-cni-1.7.11-linux-amd64.tar.gz

2.2 Look at what came out

# list the unpacked directories
[root@localhost]# ls
etc opt  usr


# etc holds the containerd service config and the CNI network config
[root@localhost]# ls etc
cni  crictl.yaml  systemd

[root@localhost]# ls etc/systemd/
system

[root@localhost]# ls etc/systemd/system/
containerd.service

# opt holds the containerd config and CNI plugins used in a GCE environment
[root@localhost]# ls opt
cni  containerd

[root@localhost]# ls opt/containerd/
cluster

[root@localhost]# ls opt/containerd/cluster/
gce  version

[root@localhost]# ls opt/containerd/cluster/gce
cloud-init  cni.template  configure.sh  env

# usr holds the containerd runtime files, including runc
[root@localhost]# ls usr
local

[root@localhost]# ls usr/local/
bin  sbin

[root@localhost]# ls usr/local/bin
containerd  containerd-shim  containerd-shim-runc-v1  containerd-shim-runc-v2  containerd-stress  crictl  critest  ctd-decoder  ctr

[root@localhost]# ls usr/local/sbin
runc

2.3 See where containerd expects to live

# read containerd.service to find out where containerd is expected
[root@localhost]# cat etc/systemd/system/containerd.service

# Copyright The containerd Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target

[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd # look here: dropping the containerd binary at this path completes the install.

Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999

[Install]
WantedBy=multi-user.target

2.4 Copy the runtime files into the system

# the host's /usr/local/bin is empty
[root@localhost]# ls /usr/local/bin/

# the unpacked usr/local/bin holds the containerd runtime files
[root@localhost]# ls usr/
local

[root@localhost]# ls usr/local/
bin  sbin

[root@localhost]# ls usr/local/bin/
containerd  containerd-shim  containerd-shim-runc-v1  containerd-shim-runc-v2  containerd-stress  crictl  critest  ctd-decoder  ctr

# copy containerd into /usr/local/bin — copying just the one file is enough, or copy them all
[root@localhost]# cp usr/local/bin/containerd /usr/local/bin/

[root@localhost]# ls /usr/local/bin/
containerd

2.5 Install the containerd.service unit

# look at the unpacked etc/system tree
[root@localhost]# ls etc
cni  crictl.yaml  systemd

[root@localhost]# ls etc/systemd/
system

[root@localhost]# ls etc/systemd/system/
containerd.service

# copy the unit file into /usr/lib/systemd/system/
[root@localhost]# cp etc/systemd/system/containerd.service /usr/lib/systemd/system/containerd.service

# confirm the copy
[root@localhost]# ls /usr/lib/systemd/system/containerd.service
/usr/lib/systemd/system/containerd.service

2.6 Check the help output

[root@localhost]# containerd --help

2.7 Generate the configuration file

Create the config directory

[root@localhost]# mkdir /etc/containerd

Generate the default config

[root@localhost]# containerd config default > /etc/containerd/config.toml

Read it back

[root@centos]# cat /etc/containerd/config.toml

The file looks like this:

root = "/var/lib/containerd"
state = "/run/containerd"
oom_score = -999
 
[grpc]
  address = "/run/containerd/containerd.sock"
  uid = 0
  gid = 0
  max_recv_message_size = 16777216
  max_send_message_size = 16777216
 
[debug]
  address = ""
  uid = 0
  gid = 0
  level = ""
 
[metrics]
  address = ""
  grpc_histogram = false
 
[cgroup]
  path = ""
 
[plugins]
  [plugins.cgroups]
    no_prometheus = false
  [plugins.cri]
    stream_server_address = "127.0.0.1"
    stream_server_port = "0"
    enable_selinux = false
    sandbox_image = "easzlab/pause-amd64:3.2"
    stats_collect_period = 10
    systemd_cgroup = false
    enable_tls_streaming = false
    max_container_log_line_size = 16384
    [plugins.cri.containerd]
      snapshotter = "overlayfs"
      no_pivot = false
      [plugins.cri.containerd.default_runtime]
        runtime_type = "io.containerd.runtime.v1.linux"
        runtime_engine = ""
        runtime_root = ""
      [plugins.cri.containerd.untrusted_workload_runtime]
        runtime_type = ""
        runtime_engine = ""
        runtime_root = ""
    [plugins.cri.cni]
      bin_dir = "/opt/kube/bin"
      conf_dir = "/etc/cni/net.d"
      conf_template = "/etc/cni/net.d/10-default.conf"
    [plugins.cri.registry]
      [plugins.cri.registry.mirrors]
        [plugins.cri.registry.mirrors."docker.io"]
          endpoint = [
            "https://docker.mirrors.ustc.edu.cn",
            "http://hub-mirror.c.163.com"
          ]
        [plugins.cri.registry.mirrors."gcr.io"]
          endpoint = [
            "https://gcr.mirrors.ustc.edu.cn"
          ]
        [plugins.cri.registry.mirrors."k8s.gcr.io"]
          endpoint = [
            "https://gcr.mirrors.ustc.edu.cn/google-containers/"
          ]
        [plugins.cri.registry.mirrors."quay.io"]
          endpoint = [
            "https://quay.mirrors.ustc.edu.cn"
          ]
        [plugins.cri.registry.mirrors."harbor.example.com"] # a local Harbor registry added here as the local image registry
          endpoint = [
            "http://harbor.example.com"
          ]
    [plugins.cri.x509_key_pair_streaming]
      tls_cert_file = ""
      tls_key_file = ""
  [plugins.diff-service]
    default = ["walking"]
  [plugins.linux]
    shim = "containerd-shim"
    runtime = "runc"
    runtime_root = ""
    no_shim = false
    shim_debug = false
  [plugins.opt]
    path = "/opt/containerd"
  [plugins.restart]
    interval = "10s"
  [plugins.scheduler]
    pause_threshold = 0.02
    deletion_threshold = 0
    mutation_threshold = 100
    schedule_delay = "0s"
    startup_delay = "100ms"

2.8 Copy the ctr command into the system

[root@localhost]# ls usr/local/bin/
containerd  containerd-shim  containerd-shim-runc-v1  containerd-shim-runc-v2  containerd-stress  crictl  critest  ctd-decoder  ctr

[root@localhost]# cp usr/local/bin/ctr /usr/bin/

2.9 Enable at boot and start

Enable at boot

[root@localhost]# systemctl enable containerd

Start

[root@localhost]# systemctl start containerd

3. Installing runC

The bundled runC expects seccomp to be available on the system, which means installing it separately — and because different runC versions expect matching versions of seccomp, the practical route is to download the runC binary on its own, since it carries the seccomp support it needs.

3.1 Download

[root@localhost]# wget https://github.com/opencontainers/runc/releases/download/v1.1.11/runc.amd64

3.2 Install and verify

[root@localhost]# mv runc.amd64 /usr/sbin/runc

# make runC executable
[root@localhost]# chmod +x /usr/sbin/runc

# verify the install
[root@localhost]# runc -v

runc version 1.1.11
commit: v1.1.11-0-g4bccb38c
spec: 1.0.2-dev
go: go1.20.12
libseccomp: 2.5.4

Further reading on the same topic.

Installing Containerd: the YUM Way

Installing containerd on openEuler from Docker's official YUM repository, enabling it at boot, and verifying the version afterwards.

1 min readOperations

Setting Up Containerd + K8S (v1.26.15)

Building a K8S v1.26.15 cluster from scratch with containerd on Alibaba Cloud Linux: host and kernel preparation, ipvs and bridge parameters, kubeadm initialization and node join, plus offline image handling for the Calico network.

3 min readOperations

Comments