kubelet은 CRI 인터페이스로 containerd에 컨테이너 실행을 요청합니다. containerd는 이미지를 받고 컨테이너를 관리해요. 여기서는 세 노드에 런타임과 Kubernetes 패키지를 준비하고, CRI 응답과 패치 버전까지 확인합니다.
목차
1. containerd 2.x 설치
아래 명령은 세 노드 모두에서 실행합니다. Docker의 CentOS RPM 저장소에서 containerd.io를 설치하는 경로입니다. Rocky에서 사용하는 호환 경로이지만 Docker가 Rocky의 모든 구성을 공식 지원한다는 의미는 아닙니다. 이 실습에는 Docker Engine과 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
설치 중 표시되는 키 지문을 공식 문서와 대조합니다. 확인 기준은 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35이며 키가 변경됐다면 새 안내를 먼저 확인합니다. containerd 메이저는 2인지 확인하세요. 1.x가 선택되면 2.x 패키지를 지정해 설치해야 합니다. Kubernetes 1.36에는 RuntimeConfig CRI 지원 런타임이 필요합니다.
2. systemd cgroup 설정
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'
기본 설정 생성은 새 실습 VM에서만 진행합니다. 기존 운영 노드의 config.toml을 덮어쓰지 않습니다. containerd 2.x의 runc 옵션은 plugins."io.containerd.cri.v1.runtime".containerd.runtimes.runc.options 아래에 있습니다. 1.x의 플러그인 경로와 섞지 않고, disabled_plugins에 CRI 플러그인이 없는지도 확인합니다.
kubelet과 런타임의 cgroup 관리자를 맞추는 이유는 자원 상태를 같은 기준으로 읽도록 하기 위해서입니다. systemd와 별도 cgroup 계층을 혼용하면 해석이 어긋날 수 있어요. 1.36에서는 런타임 기능으로 드라이버를 확인하는 경로도 사용하므로 예전 config.yaml만 복사해 맞았다고 판단하지 않습니다.
3. Kubernetes 1.36 저장소와 패치
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이 마이너 계열입니다. 예전 yum.kubernetes.io는 사용하지 않습니다. K8S_PATCH에는 목록에 실제 있는 1.36 패치를 넣고 세 노드에서 같은 값을 사용합니다. 쉘을 새로 열었다면 변수도 다시 지정합니다.
# 예: 저장소에 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
아직 init이나 join 전이라 kubelet이 설정 파일을 찾지 못하고 재시작할 수 있습니다. 반면 containerd 서비스 실패는 별도로 확인해야 합니다. journalctl -u containerd -b에서 런타임 오류를 읽고, kubelet의 초기 대기 상태와 구분합니다.
4. crictl의 CRI 응답
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
CRI 응답에서 RuntimeReady=true를 확인합니다. CNI 설치 전의 NetworkReady=false 또는 network plugin not initialized는 다음 단계에서 다룹니다. ctr는 저수준 containerd 도구이고 crictl은 kubelet과 같은 CRI 관점의 도구예요. 이미지가 한쪽에서만 보이면 containerd 네임스페이스도 확인합니다.
5. 패키지 버전 기록·고정
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
Kubernetes 패키지의 exclude와 런타임 versionlock으로 변경 시점을 관리합니다. 업데이트를 계속 미루려는 목적은 아닙니다. 10편에서 백업 후 의도적으로 교체하는 절차를 다룹니다. 세 노드의 packages.txt도 비교해 설치 차이가 없는지 확인합니다.
containerd 2.x 실행, crictl의 CRI 연결, kubeadm·kubelet·kubectl 패치 일치까지 확인하면 다음 글로 넘어갑니다. Pod 네트워크가 아직 준비되지 않은 상태는 뒤의 CNI 설치에서 해결합니다.
참고 자료
공식 문서와 배포 파일 확인 기준: 2026년 10월 18일. 출력은 완료 여부를 판단하기 위한 예시이며 환경별로 달라질 수 있습니다.




답글 남기기