Controller 플러그인 — Deployment
볼륨 생성·삭제·확장·스냅샷. 클러스터에 하나.
Pod 실행에는 컨테이너 생성, 네트워크 연결, 볼륨 연결이 필요하다. 각 작업을 어느 플러그인이 담당하는지 알면 문제를 진단할 위치도 보인다. 새 API 종류는 CRD에서 다룬다.
핵심 기능 중 상당수가 인터페이스만 정의되어 있고 구현은 밖에 있다.
| 인터페이스 | 무엇을 위임하나 | 구현체 예 |
|---|---|---|
| CRI (Container Runtime Interface) | 컨테이너 실행 | containerd, CRI-O |
| CNI (Container Network Interface) | Pod 네트워크·IP | Calico, Cilium, Flannel |
| CSI (Container Storage Interface) | 볼륨 생성·마운트 | EBS CSI, Ceph, local-path |
| CRD + 컨트롤러 | 새로운 리소스 종류 | cert-manager, Prometheus Operator |
이 구조 덕분에 같은 API로 온프렘과 클라우드가 모두 동작한다. 그리고 “플러그인이 없으면 아무것도 안 된다”는 트러블슈팅 포인트가 생긴다.
kubelet은 컨테이너를 직접 만들지 못한다 — 실행은 전부 런타임에 시킨다. 규약이 없으면 kubelet이 런타임마다 전용 연동 코드를 품어야 하고, 실제로 Docker 전용 코드(dockershim)를 그렇게 품고 있다가 부담이 커져 떼어냈다. 그 규약이 CRI다.
unix:///run/containerd/containerd.sock이 소켓 경로는 kubelet 설정 파일의 containerRuntimeEndpoint 필드에 있다. 노드에서 값을 확인하는
자리가 여기다 — 옛 자료가 가리키는 --container-runtime 플래그는 v1.27에서 제거됐다.
grep containerRuntimeEndpoint /var/lib/kubelet/config.yaml # 이 노드에 설정된 CRI 소켓kubectl get nodes -o wide # CONTAINER-RUNTIME 열로도 확인같은 뜻의 --container-runtime-endpoint 플래그는
설정 파일보다 우선하지만 공식 문서가 deprecated로 표시했다. 설정 파일을 먼저 보고, 값이 다르면
/var/lib/kubelet/kubeadm-flags.env에서 플래그 재정의를 찾는다.
# crictl 설정sudo crictl config --set runtime-endpoint=unix:///run/containerd/containerd.sockcat /etc/crictl.yaml
sudo crictl ps -a # 컨테이너sudo crictl pods # Pod 샌드박스sudo crictl images # 이미지sudo crictl logs <container-id>sudo crictl inspect <container-id>sudo crictl rmi --prune # 안 쓰는 이미지 정리Pod마다 IP를 주고 노드 사이를 잇는 방법은 환경마다 다르다 — 온프렘·클라우드·
베어메탈이 전부 다른 답을 쓴다. 그래서 코어는 “인터페이스를 만들고 IP를 붙여라”는
호출 규약만 정하고, 방법은 플러그인에 맡긴다.
kubelet은 CRI로 런타임에게 Pod 샌드박스(Pod의 컨테이너들이 공유할 네트워크 네임스페이스 껍데기)를
만들라고 시킬 뿐이고, CNI 플러그인을 실제로 실행하는 쪽은 컨테이너 런타임이다.
v1.24에서 kubelet의 cni-bin-dir·network-plugin 플래그가 제거되면서 CNI 관리는
kubelet의 일이 아니게 됐다.
그래서 CNI 설정과 바이너리 경로를 아는 주체도 런타임이다.
② 의 IP 할당은 IPAM(IP Address Management — 주소 할당 관리) 플러그인의 몫이다. 이렇게 깔린 Pod 네트워크 위에서 Service의 가상 IP가 어떻게 Pod IP로 번역되는지는 Service의 분업 절에서 본다.
모든 CNI가 지켜야 하는 규칙
이 규칙은 모든 CNI가 지키지만 그 밖의 기능은 CNI마다 다르다. 여러 후보 중 하나를 골라야 한다면 요구 기능으로 가른다. 대표적인 기준이 NetworkPolicy 적용 여부이고, 지원 여부는 CNI별 표에 있다.
볼륨을 만들고 노드에 붙이는 방법은 스토리지 벤더마다 다르다. CSI가 없던 시절엔 벤더 코드가 Kubernetes 코어 안에 들어 있어서(in-tree 드라이버), 새 스토리지를 지원하려면 Kubernetes 릴리스를 기다려야 했다. CSI는 그 연동을 표준 규약으로 떼어내, 벤더가 드라이버만 따로 배포하면 되게 한다.
kubectl get csidriverskubectl get csinodeskubectl get storageclasskubectl get volumeattachmentsCSI 드라이버는 보통 두 부분으로 배포된다.
Controller 플러그인 — Deployment
볼륨 생성·삭제·확장·스냅샷. 클러스터에 하나.
Node 플러그인 — DaemonSet
노드에서 attach·mount. 노드마다 하나.
두 플러그인 주변에는 sidecar 컨테이너들이 붙는다. 벤더는 “볼륨을 만들어라” 같은 실제 동작만 구현하고, API 서버를 지켜보다가 그 동작을 호출하는 쪽은 Kubernetes 프로젝트가 만든 공용 사이드카가 맡는다 — 벤더마다 같은 watch 코드를 다시 짜지 않게 하려는 분업이다. 각 사이드카가 무엇을 감시하는지만 알면 된다.
| 사이드카 | 무엇을 보고 무엇을 시키나 |
|---|---|
external-provisioner | PVC를 watch → 드라이버에 볼륨 생성·삭제 요청 |
external-attacher | VolumeAttachment를 watch → 노드에 attach·detach 요청 |
external-resizer | PVC의 용량 변경을 watch → 볼륨 확장 요청 |
external-snapshotter | VolumeSnapshot을 watch → 스냅샷 생성 |
node-driver-registrar | 노드의 kubelet에 드라이버를 등록한다 |
이름을 외울 필요는 없다. 다만 PVC가 Pending일 때 어느 로그를 볼지를 이 표가
정해 준다 — 볼륨이 안 만들어지면 external-provisioner, 만들어졌는데 노드에
안 붙으면 external-attacher 쪽이다.
PVC가 Pending인데 StorageClass는 있다면
프로비저너 Pod이 살아 있는지부터 확인한다.
kubectl get pods -n kube-system | grep csikubectl logs -n kube-system <csi-controller-pod> -c csi-provisionerCRI·CNI·CSI는 “코어가 아예 구현을 안 갖고 있는” 자리였다. 여기서 볼 것들은 그와 달리 코어가 동작은 하는데, 그 동작에 끼어들거나 덧붙이는 지점이다. 어디에 끼어드는지만 알아 두면 “왜 이 컴포넌트가 있지”라는 의문이 대부분 풀린다. 다섯 중 CKA에서 실제로 손을 대는 것은 admission(Admission)과 다중 스케줄러(스케줄링) 정도이고, 나머지는 이름과 역할만 알아 두면 충분하다 — 직접 구성하는 문제로 나오지는 않는 편이다.
| 확장 | 무엇 |
|---|---|
| Admission webhook | 요청을 가로채 고치거나 거부 (Admission) |
| API Aggregation | 별도 API 서버를 /apis 아래에 붙인다 (metrics-server가 이 방식) |
| CRI/CNI/CSI | 이 장에서 본 것들 |
| Device Plugin | GPU 등 특수 하드웨어를 노드 리소스로 노출 |
| Scheduler Extender / 다중 스케줄러 | 배치 로직 교체 (스케줄링) |
| Cloud Controller Manager | 클라우드별 노드·LB·라우트 관리 |
kubectl get apiservices | grep -v Local # 집계된 외부 API 서버들# v1beta1.metrics.k8s.io kube-system/metrics-server TrueAPIService가 False면 그 API 전체가 죽는다 —
kubectl top이 안 되는 원인 중 하나다 (오토스케일링).
crictl, CNI는 설정·바이너리, CSI는 Controller·Node 플러그인이 주요 확인 지점이다.