Kubernetes 심층 탐구: Kubelet
Source: Dev.to
위 링크에 있는 글을 번역하려면 실제 텍스트를 제공해 주셔야 합니다.
본문을 복사해서 붙여 주시면, 원본 서식과 코드 블록, URL은 그대로 유지하면서 한국어로 번역해 드리겠습니다.
Introduction
Kubernetes 클러스터에서 Kubelet은 컨테이너를 시작·중지하고 노드의 상태를 관리하는 역할을 담당합니다. 이는 노드의 운영체제에서 직접 실행되는 독립 실행 파일이며, 일반적으로 systemd 서비스로 시작됩니다. kind와 같은 개발 환경에서는 노드 자체가 Docker 컨테이너 안에서 실행되며, kubelet은 해당 컨테이너의 init 시스템의 자식 프로세스로 실행됩니다.
kubelet이 중지되면, 컨트롤 플레인은 노드를 NotReady 상태로 표시하여 새로운 워크로드가 해당 노드에 스케줄링되는 것을 방지합니다.
Kubelet 책임
Kubelet은 노드에서 실제로 실행 중인 컨테이너와 API 서버에서 가져온 PodSpec에 정의된 원하는 상태를 지속적으로 조정합니다. 이를 위해 자율적으로 동작하는 여러 특수 관리자를 사용합니다:
- Pod 수명 주기 관리 –
SyncPod로직을 통해 pod 생성, 업데이트 및 삭제를 처리합니다. - 스토리지 브리지 –
VolumeManager가 호스트에 외부 스토리지를 마운트하고 컨테이너에서 사용할 수 있게 합니다. - 시크릿 전달 –
TokenManager와SecretManager가 ServiceAccount 토큰과 시크릿을 가져와 적절한 위치에 주입합니다. - 상태 보고 – 주기적으로 노드 자원 사용량 및 pod 상태를 API 서버에 전송합니다.
- 헬스 체크 – Liveness와 Readiness 프로브를 실행하고 필요 시 컨테이너를 재시작합니다.
- 노드 자체 방어 – 자원 한계에 다다르면 pod를 퇴출시켜 노드가 완전히 다운되는 것을 방지합니다.
이러한 모든 구성 요소는 SyncLoop 라는 중앙 이벤트 루프를 중심으로 조정됩니다.
런타임 스택: CRI → containerd → runc
kubelet이 “컨테이너 생성” 명령을 내릴 때, 요청은 다음과 같은 계층형 스택을 통해 흐릅니다:
- CRI (Container Runtime Interface) – kubelet이 컨테이너 런타임과 통신하기 위해 사용하는 프로토콜.
- containerd (CRI Runtime) – CRI 명령을 수신하고, 이미지 풀을 처리하며, 상위 수준의 컨테이너 라이프사이클 작업을 관리합니다.
- runc (OCI Runtime) – 커널과 직접 상호 작용하여 컨테이너 프로세스를 생성하고 실행합니다.
kubelet은 containerd에 지시하고, containerd는 다시 runc를 호출하여 저수준 작업을 수행합니다.
Eviction vs. OOM Killer
| 기능 | 퇴거 (Node‑pressure) | OOM 킬러 (Cgroup / Global) |
|---|---|---|
| 실행자 | Kubelet (관리자) | Linux 커널 (경찰) |
| 시점 | 리소스 사용량이 정의된 임계값을 초과할 때 | cgroup 또는 시스템이 하드 제한을 초과할 때 |
| 동작 | 리소스를 확보하기 위해 파드를 정상적으로 종료함 | 해당 프로세스에 즉시 SIGKILL을 보냄 |
| 목적 | 노드를 유지하기 위한 예방 조치 | OS 또는 cgroup 제한을 보호하기 위한 강제 조치 |
파드는 메모리 부족으로 다음 두 가지 이유 중 하나로 종료될 수 있습니다:
- 자신의 제한 위반 – 파드가 요청한 리소스를 초과함.
- 노드 전체 위기 – 전체 노드가 압박을 받음.
Kubelet은 커널의 OOM 킬러가 개입하기 전에 조직적인 퇴거를 수행하려고 합니다.
SyncPod 흐름 (Pod 시작)
- 컨텍스트 준비 – API 서버에서 최신 pod 정의를 가져옵니다.
- 볼륨 마운트 –
VolumeManager에 호스트에 필요한 스토리지를 마운트하도록 지시합니다. - Secret/ConfigMap 준비 –
TokenManager가 서비스 계정 토큰을 가져와 호스트에 파일로 배치합니다. - 샌드박스 생성 – pod의 네트워크와 네임스페이스 프레임을 제공하는 “pause” 컨테이너(
RunPodSandbox)를 생성합니다. - 컨테이너 시작 –
- 준비된 토큰이나 볼륨을 컨테이너 파일시스템에 바인드 마운트합니다(예:
/var/run/secrets/...). - 애플리케이션 컨테이너를 실행합니다.
- 준비된 토큰이나 볼륨을 컨테이너 파일시스템에 바인드 마운트합니다(예:
요약
Kubelet은 단순한 에이전트를 넘어서는 자율 제어 시스템으로, 다음과 같은 역할을 수행합니다:
- 호스트(또는 kind 노드 컨테이너)에서 프로세스로 실행됩니다.
- 고수준 Pod 사양을 CRI → containerd → runc 스택을 이용해 구체적인 컨테이너로 변환합니다.
- 커널의 OOM Killer가 갑작스러운 실패를 일으키기 전에 Pod를 퇴출시켜 노드 상태를 보호합니다.
노드의 이 “두뇌”를 이해하는 것은 Pod 종료 원인(OOMKilled vs. Evicted)이나 볼륨 마운트 문제를 해결할 때 필수적입니다.