The kubelet asks containerd to run containers through the Container Runtime Interface, or CRI. This part prepares the runtime and Kubernetes packages on all three nodes, then checks the CRI response and installed patch versions before cluster initialization.
Table of Contents
1. Install containerd 2.x
Run the following commands on all three nodes. They install containerd.io from Docker’s CentOS RPM repository, a compatibility path used here for Rocky Linux. This does not establish official Docker support for every Rocky configuration. This lab does not install Docker Engine or Compose.
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf list --showduplicates containerd.io
sudo dnf install containerd.io
containerd --version
Check the key fingerprint displayed during installation against the official documentation. The confirmation standard is 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35, and if the key has changed, check the new instructions first. Check that the containerd major is 2. If 1.x is selected, you must specify and install the 2.x package. Kubernetes 1.36 requires a RuntimeConfig CRI-enabled runtime.
2. systemd cgroup settings
sudo mkdir -p /etc/containerd
sudo sh -c 'containerd config default > /etc/containerd/config.toml'
sudo sed -ri 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
sudo systemctl enable --now containerd
sudo systemctl restart containerd
sudo systemctl --no-pager --full status containerd
sudo ctr plugins ls | grep -E 'cri|runtime'
Creating default settings only happens on new lab VMs. config.toml of the existing production node will not be overwritten. The runc options for containerd 2.x are under plugins."io.containerd.cri.v1.runtime".containerd.runtimes.runc.options. Do not mix with the 1.x plugin path, and also make sure there is no CRI plugin in disabled_plugins.
The reason for aligning the kubelet and runtime cgroup managers is to ensure that resource status is read by the same standards. Interpretation may be incorrect if systemd and a separate cgroup layer are used together. 1.36 also uses a path to check the driver with a runtime function, so it will not be determined that it was correct by just copying the old config.yaml.
3. Kubernetes 1.36 repository and patches
sudo tee /etc/yum.repos.d/kubernetes.repo > /dev/null <<'EOF'
[kubernetes]
name=Kubernetes 1.36
baseurl=https://pkgs.k8s.io/core:/stable:/v1.36/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.36/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
sudo dnf --disableexcludes=kubernetes list --showduplicates kubeadm
v1.36 in the repository URL identifies the minor release series. Do not use the old yum.kubernetes.io repository. Set K8S_PATCH to an actual 1.36 patch version listed by the repository, and use the same value on all three nodes. Set the variable again after opening a new shell.
# 예: 저장소에 1.36.5가 보일 때. 더 최신 패치를 골라도 세 노드는 동일하게.
K8S_PATCH=1.36.5
sudo dnf install -y \
"kubelet-${K8S_PATCH}" "kubeadm-${K8S_PATCH}" "kubectl-${K8S_PATCH}" \
cri-tools --disableexcludes=kubernetes
sudo systemctl enable --now kubelet
rpm -q kubelet kubeadm kubectl containerd.io cri-tools
Because it is not yet init or join, the kubelet may not be able to find the configuration file and may restart. On the other hand, containerd service failure must be checked separately. Read runtime errors from journalctl -u containerd -b and distinguish them from the kubelet’s initial wait state.
4. CRI response of crictl
sudo tee /etc/crictl.yaml > /dev/null <<'EOF'
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
sudo crictl info
sudo crictl images
Check RuntimeReady=true in the CRI response. NetworkReady=false or network plugin not initialized before CNI installation is covered in the next step. ctr is a low-level containerd tool and crictl is a CRI perspective tool like kubelet. If the image is only visible from one side, also check the containerd namespace.
5. Record and fix package version
sudo dnf install -y python3-dnf-plugin-versionlock
sudo dnf versionlock add containerd.io
sudo dnf versionlock list
mkdir -p ~/k8s-lab
rpm -q kubelet kubeadm kubectl containerd.io cri-tools > ~/k8s-lab/packages.txt
containerd --version >> ~/k8s-lab/packages.txt
kubeadm version -o short >> ~/k8s-lab/packages.txt
Change timing is managed with exclude in the Kubernetes package and runtime versionlock. Our intention is not to keep putting off updates. Part 10 covers the procedure for intentional replacement after backup. Compare packages.txt of the three nodes as well to ensure there are no installation differences.
Once you confirm that containerd 2.x is running, crictl’s CRI connection, and kubeadm·kubelet·kubectl patches match, you can move on to the next article. If the Pod network is not yet ready, this is addressed later in the CNI installation.
reference material
- containerd CRI settings
- Kubernetes container runtime/cgroup information
- Docker CentOS repository with GPG key
- crictl usage guide
official documents and distribution files confirmed: October 18, 2026. The output is an example to determine completion and may vary depending on the environment.



