이번 편에서는 실제 파드가 실행되는 Worker Node의 컴포넌트와, 컨테이너 런타임이 Docker에서 containerd로 전환된 흐름을 함께 정리합니다.
이 글은 “[Udemy] CKA with Practice Tests” 강의를 수강하며 정리한 내용을 바탕으로 작성한 내용입니다.
kubelet
kubelet은 각 쿠버네티스 노드에서 실행되는 에이전트입니다.
kube-apiserver로부터 명령을 받아 실제 컨테이너를 실행하고 관리하며, 클러스터에서 파드가 Running 상태가 되기까지의 마지막 실행 단계를 담당합니다.

동작 흐름은 아래와 같습니다.
- kube-apiserver가 특정 파드를 노드에 바인딩 (.spec.nodeName 기록)
- 해당 노드의 kubelet이 새로운 파드 정보를 감지
- 파드 스펙(spec)을 기반으로 컨테이너 런타임에 실행 요청
- 컨테이너 런타임이 이미지 pull 후 컨테이너 기동
- 이후에도 주기적으로 파드와 컨테이너 상태를 API Server에 보고
주요 역할
역할 설명
| 역할 | 설명 |
| 파드 생성/삭제 | API Server로부터 명령을 받아 컨테이너 생성/삭제 |
| 상태 보고 | 파드, 노드, 컨테이너 상태를 주기적으로 API Server에 보고 |
| Static Pod 관리 | /etc/kubernetes/manifests/ 디렉터리의 YAML을 감시하고 자동 실행 |
| CNI, CSI 연동 | 네트워크(CNI), 스토리지(CSI) 플러그인과 통합 |
| Probe 체크 | Liveness/Readiness Probe로 애플리케이션 상태를 주기적으로 점검 |
주요 실행 옵션
ExecStart=/usr/bin/kubelet \\\\
--kubeconfig=/etc/kubernetes/kubelet.conf \\\\ # API 서버 인증 정보
--pod-manifest-path=/etc/kubernetes/manifests \\\\ # Static Pod 파일 위치
--container-runtime=remote \\\\
--container-runtime-endpoint=unix:///run/containerd/containerd.sock \\\\ # 런타임 소켓
--network-plugin=cni \\\\ # 네트워크 플러그인
--cni-conf-dir=/etc/cni/net.d \\\\
--cni-bin-dir=/opt/cni/bin \\\\
--register-node=true \\\\ # 노드를 API 서버에 자동 등록
--v=2 #로그 verbosity 수준
설치 및 상태 확인
kubeadm은 기본적으로 kubelet을 자동 배포하지 않기 때문에, 바이너리를 직접 다운로드해 워커 노드에 설치해야 합니다.
# 바이너리 설치
wget <https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kubelet>
# 실행 중인 프로세스와 옵션 확인
ps -aux | grep kubelet
kube-proxy
kube-proxy는 쿠버네티스 노드에서 실행되는 네트워크 프록시 에이전트입니다.
클러스터 내부의 파드와 서비스 간의 통신을 연결하고, 트래픽 라우팅 규칙을 생성하는 역할을 합니다.
Service 리소스가 생성되면, 실제로 해당 트래픽이 어느 파드로 전달되어야 할지를 각 노드의 kube-proxy가 iptables 또는 IPVS 규칙으로 설정합니다.
주요 역할
| 역할 | 설명 |
| ClusterIP 라우팅 | Service를 기반으로 가상의 ClusterIP를 실제 파드 IP로 라우팅 |
| 로드밸런싱 | 여러 파드 중 하나로 트래픽을 분산 (Round-Robin 등) |
| NAT & 포트포워딩 | NodePort, ExternalIP, ClusterIP 등의 네트워크 변환 처리 |
| iptables / IPVS 설정 | 커널 네트워크 스택에 라우팅 규칙을 직접 설정 |
작동 방식은 아래와 같습니다.
- 사용자가 ClusterIP 또는 NodePort 서비스 생성
- kube-proxy가 API Server에서 변경 사항 감지
- 해당 서비스와 연결된 Endpoint(파드 목록) 정보 수신
- iptables / IPVS 규칙 설정
- 클러스터 내외부에서 들어오는 요청을 올바른 파드로 전달
설치 및 상태 확인
kube-proxy는 DaemonSet으로 배포되어 모든 노드에서 실행됩니다.
# 바이너리 설치
wget <https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kube-proxy>
# DaemonSet 확인
kubectl get daemonset -n kube-system
# 로그 확인
journalctl -u kube-proxy
# 마스터 노드에서 프로세스 옵션 확인
ps -aux | grep kube-proxy
Docker vs containerd
등장 배경
초창기에는 Docker가 먼저 등장했고, 쿠버네티스는 Docker를 기본 컨테이너 런타임으로 지원했습니다.
이후 쿠버네티스는 다양한 컨테이너 런타임을 지원하기 위해 CRI(Container Runtime Interface)를 도입했습니다.
CRI는 OCI(Open Container Initiative) 표준을 준수하는 모든 런타임이 쿠버네티스의 컨테이너 런타임으로 동작할 수 있도록 만든 인터페이스입니다.
그런데 Docker는 CRI 표준을 지원하도록 설계되지 않았습니다. 쿠버네티스는 Docker를 계속 지원하기 위해 dockershim이라는 임시 방법을 도입했지만, 유지보수 부담이 크고 구조적으로도 비효율적이었습니다.
그 사이 containerd, CRI-O 같은 CRI 표준을 준수하는 런타임이 등장했고, 결국 쿠버네티스는 v1.24 릴리스에서 dockershim을 완전히 제거하고 Docker에 대한 직접 지원을 종료했습니다.
containerd
containerd는 Docker의 일부이기도 하지만, 현재는 독립적인 프로젝트로 분리되어 있습니다. CRI와 호환되기 때문에 Docker 없이도 쿠버네티스의 컨테이너 런타임으로 단독 사용할 수 있습니다. Docker의 다른 기능이 필요하지 않다면 containerd만 설치해도 충분합니다.
컨테이너 런타임 관련 CLI 도구
containerd를 사용하면 기존에 익숙하던 docker 명령어를 그대로 사용할 수 없습니다. 대신 아래 세 가지 CLI 도구를 상황에 따라 구분해서 사용합니다.
도구 제공 주체 용도
| 도구 | 제공 주체 | 용도 |
| ctr | containerd | 디버깅 목적, 기능이 제한적 |
| nerdctl | containerd 커뮤니티 | Docker CLI와 유사한 사용법, 일반 목적 |
| crictl | 쿠버네티스 커뮤니티 | CRI 호환 런타임 디버깅, 파드 단위 명령 지원 |
# ctr 사용 예시
ctr images pull docker.io/library/redis:alpine
# nerdctl 사용 예시
nerdctl run --name redis redis:alpine
# crictl 사용 예시
crictl pull busybox
crictl images
crictl logs <container-id>
crictl pods # 파드 단위 명령어도 지원
docker cli와 crictl의 주요 명령어를 비교하면 아래와 같습니다.
| docker cli | crictl | 설명 |
| attach | attach | 실행 중인 컨테이너에 연결 |
| exec | exec | 실행 중인 컨테이너에서 명령 실행 |
| images | images | 이미지 목록 조회 |
| logs | logs | 컨테이너 로그 조회 |
| ps | ps | 컨테이너 목록 조회 |
| stats | stats | 컨테이너 리소스 사용량 조회 |
| inspect | inspect / inspecti | 컨테이너 또는 이미지 상세 정보 조회 |
| version | version | 런타임 버전 정보 조회 |
crictl은 파드 단위 명령어를 추가로 지원한다는 점에서 docker cli와 차이가 있습니다.
쿠버네티스 환경에서 컨테이너 디버깅이 필요할 때 주로 활용됩니다.
마치며
이번 편까지 쿠버네티스 클러스터를 구성하는 컴포넌트를 정리했습니다.
처음에는 etcd, API Server, Scheduler, Controller Manager, kubelet, kube-proxy라는 이름들이 각각 무슨 역할을 하는지 구분조차 되지 않았는데, 각 컴포넌트가 서로 어떻게 협력하는지 흐름을 따라가다 보니 왜 이 구성 요소들이 필요한지 자연스럽게 이해되기 시작했습니다.
또 Docker에서 containerd로 런타임이 전환된 흐름을 공부하면서, 쿠버네티스 생태계가 특정 도구에 종속되지 않고 표준화를 추구해온 방향성도 이해할 수 있었습니다.
'DevOps > kubernetes' 카테고리의 다른 글
| 1-2. Control Plane 컴포넌트 (etcd, API Server, Controller Manager, Scheduler) (0) | 2026.05.09 |
|---|---|
| 1-1. 쿠버네티스란? (0) | 2026.04.25 |
| [kubernetes] 파드, 컨테이너, 도커, 쿠버네티스의 관계 (0) | 2023.06.24 |