Skip to content

✍️ 필사 모드: Kubernetes 내부 구조 완벽 가이드 — etcd, API Server, Controller, Scheduler, kubelet, CRI/CNI/CSI 모든 것 (2025)

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

들어가며 — Kubernetes는 단순한 도구가 아니다

kubectl apply -f deployment.yaml. 한 줄의 명령어로 컨테이너가 클러스터 어딘가에 배포되고, 죽으면 자동으로 다시 시작되고, 트래픽이 분산되고, 업데이트가 rolling으로 진행된다. 이것이 Kubernetes의 약속이다.

그 약속 뒤에는 etcd의 분산 합의, API Server의 watch 프로토콜, Scheduler의 빈 패킹 알고리즘, Controller의 reconciliation 루프, kubelet의 Pod lifecycle 관리, 그리고 CRI/CNI/CSI의 플러그인 인터페이스가 있다. 이 모든 컴포넌트가 정교하게 협력해 "선언적 인프라"라는 추상화를 만든다.

이 글은 Kubernetes 내부 구조의 모든 것을 다룬다. Google Borg의 역사에서 시작해 2025년의 sidecar-less service mesh와 eBPF 기반 네트워킹까지. 1,400줄에 달하지만 모든 절은 독립적으로 읽을 수 있다.

이 글은 Linux 인프라 시리즈의 마지막 단계이다. 이전 글들:

일곱 글이 모이면 "내 코드가 부팅된 Linux 위에서, 컨테이너 안에서, 클러스터의 한 노드 위에서 어떻게 살아가는가"의 풍경 전체가 그려진다.


1. Kubernetes가 무엇인가 — 정의와 약속

1.1 한 줄 정의

Kubernetes는 컨테이너 오케스트레이션 시스템이다.

이 한 줄은 옳지만 너무 얕다. 더 정확한 정의:

Kubernetes는 "원하는 상태를 선언하면, 그 상태로 자동으로 수렴하는 분산 시스템"이다.

핵심 키워드는 선언적, 수렴, 분산.

1.2 선언적 (Declarative)

사용자는 "무엇이 되어야 하는가"를 선언한다. "어떻게"는 Kubernetes가 결정.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25

이 YAML은 "nginx 1.25 이미지로 3개의 복제본"이라고 선언한다. 어디 노드에 띄울지, 어떻게 IP를 줄지, 죽으면 어떻게 다시 시작할지는 Kubernetes가 결정.

1.3 수렴 (Convergence)

선언된 desired state와 실제 actual state가 다르면, controller가 차이를 줄이는 작업을 한다. 이것이 reconciliation loop.

  • 누군가 nginx pod를 삭제 → controller가 새로 만듦
  • 노드가 죽음 → 그 노드의 pod가 다른 노드로 옮겨짐
  • 이미지 버전을 1.25에서 1.26으로 변경 → rolling update

Kubernetes는 이 수렴을 영원히 한다. 사용자가 새 desired state를 선언할 때까지.

1.4 분산 (Distributed)

control plane 자체가 분산되어 있다 (etcd가 Raft로 고가용성). data plane (노드들)도 분산. 한 노드가 죽어도 클러스터는 계속 동작.

1.5 한 줄 요약

Kubernetes는 사용자가 desired state를 선언하면 control plane이 그 상태로 클러스터를 영원히 수렴시키는 분산 시스템이다.

이 정의를 머리에 새기면 모든 Kubernetes 컴포넌트가 이 한 가지 목표를 위한 도구임을 알 수 있다.


2. 역사 — Borg에서 Kubernetes 1.30까지

2.1 Google Borg (2003+)

Google이 2003년부터 사용한 내부 클러스터 관리 시스템. 모든 Google 서비스 (검색, Gmail, YouTube)가 Borg 위에서 돌아간다. 핵심 개념:

  • Job: 한 종류의 워크로드 (지금의 Deployment).
  • Task: 한 인스턴스 (지금의 Pod).
  • Cell: 클러스터 (지금의 Cluster).
  • Borgmaster: 중앙 control plane.
  • Borglet: 노드 에이전트.

Borg의 통계:

  • 매분 수백만 개 task 처리
  • 90%+ utilization
  • 거의 0에 가까운 다운타임

이 모든 운영 노하우가 결국 Kubernetes에 들어간다.

2.2 Omega (2013)

Google의 차세대 Borg 시도. shared state model로 multiple scheduler를 지원. 산업적 성공은 없었지만, Kubernetes의 architectural 영감.

2.3 Kubernetes 발표 (2014)

Joe Beda, Brendan Burns, Craig McLuckie가 주도. 처음에는 "Project Seven of Nine"이라는 코드명. 2014년 6월 공개. 2015년 1.0 릴리스.

핵심 결정:

  • Borg의 lessons learned를 담음
  • Go로 작성 (Borg는 C++)
  • 처음부터 오픈소스
  • 모든 객체를 REST 리소스로

2.4 CNCF (2015)

Linux Foundation의 자회사. Kubernetes를 첫 졸업 프로젝트로. 이 결정이 "Kubernetes는 Google만의 것이 아니라 산업 표준"임을 못박았다.

2.5 1.0 → 1.30 (2015-2024)

매 릴리스마다 새 기능. 주요 이정표:

  • 1.2 (2016): 로컬 storage volumes, ConfigMap.
  • 1.5 (2016): StatefulSet (옛 PetSet), CRI 도입.
  • 1.7 (2017): RBAC stable, CustomResourceDefinitions.
  • 1.10 (2018): CRI 안정화.
  • 1.14 (2019): kubectl wait, durable local volumes.
  • 1.20 (2020): Docker shim deprecation 발표.
  • 1.24 (2022): Docker shim 제거.
  • 1.27 (2023): SeccompDefault stable.
  • 1.30 (2024): Pod scheduling readiness, AppArmor stable.

2.6 산업 채택

거의 모든 메이저 클라우드가 managed Kubernetes 제공:

  • AWS EKS
  • Google GKE (Kubernetes 발상지)
  • Azure AKS
  • DigitalOcean DOKS
  • Linode LKE
  • Civo

또한 self-hosted을 위한 distribution:

  • Red Hat OpenShift
  • Rancher
  • Tanzu (VMware)
  • k3s (가벼운 edge용)
  • kubeadm (수동 설치)

★ Insight ─────────────────────────────────────

  • Borg → Kubernetes의 흥미로운 비대칭: Borg는 Google 내부에서만 쓰인다. Kubernetes는 외부 표준이 되었다. 같은 팀이 두 시스템을 나란히 운영. 그러나 Google은 Borg를 Kubernetes로 마이그레이션하지 않는다 — Borg가 자기 워크로드에 더 잘 맞기 때문. 이는 "오픈소스화"가 같은 코드의 공개를 의미하지 않음을 보여주는 좋은 사례.
  • Kubernetes의 디자인은 Omega의 교훈: Omega는 shared-state model을 시도했다. 모든 컴포넌트가 같은 store를 본다. 이는 multiple scheduler를 가능하게 했지만 복잡했다. Kubernetes는 이 모델을 단순화해 받아들였다 — etcd를 single source of truth로, 모든 컴포넌트가 watch.
  • 기능 안정화의 속도: Kubernetes는 alpha → beta → stable 세 단계를 거친다. 이 과정이 보통 수년이 걸린다. 그래서 새 기능을 production에 쓸 때 항상 stability level을 확인해야 한다. ─────────────────────────────────────────────────

3. 아키텍처 — Control Plane과 Data Plane

3.1 두 평면

Kubernetes는 두 부분으로 나뉜다:

  • Control Plane: 클러스터의 "두뇌". 결정과 상태 관리.
  • Data Plane: 클러스터의 "근육". 실제 워크로드 실행.

3.2 Control Plane 컴포넌트

  • etcd: 분산 key-value store. 클러스터의 모든 상태가 여기 저장.
  • API Server (kube-apiserver): REST 인터페이스. 모든 컴포넌트와 사용자가 etcd에 접근하는 유일한 길.
  • Controller Manager (kube-controller-manager): 다양한 controller를 실행. reconciliation loop의 중심.
  • Scheduler (kube-scheduler): 어떤 Pod을 어떤 노드에 둘지 결정.
  • Cloud Controller Manager: 클라우드 제공자 (AWS, GCP 등)와의 통합.

3.3 Data Plane 컴포넌트

  • kubelet: 각 노드의 에이전트. Pod lifecycle 관리.
  • kube-proxy: 노드 단위 네트워크 프록시. Service의 구현.
  • 컨테이너 런타임: containerd, CRI-O 등. 실제 컨테이너 실행.

3.4 흐름의 예 — Pod 생성

사용자가 kubectl apply를 했을 때 일어나는 일:

  1. kubectl이 YAML을 파싱해 API Server에 POST.
  2. API Server가 인증/인가 후 admission controller 실행, etcd에 저장.
  3. Scheduler가 새 Pod을 발견 (watch). 적절한 노드 선택. API Server에 noticeBound 알림.
  4. API Server가 Pod의 nodeName 필드 갱신, etcd에 저장.
  5. kubelet (해당 노드의)이 새 Pod을 발견 (watch). 컨테이너 런타임에 컨테이너 생성 요청.
  6. CRI (containerd)가 컨테이너를 실행.
  7. CNI가 네트워크를 설정.
  8. kubelet이 Pod 상태를 API Server에 보고.
  9. API Server가 Pod 상태를 etcd에 저장.

이 전체가 보통 수 초 안에 끝난다. 모든 컴포넌트가 etcd를 통해 간접적으로 통신한다.

3.5 모든 것이 etcd와 API Server를 거친다

핵심 디자인 원칙: 컴포넌트 간 직접 통신 없음. 모두 API Server를 통해 etcd의 상태를 읽고 쓰고 watch한다.

이 모델의 장점:

  • 단일 source of truth
  • 컴포넌트 분리 (loose coupling)
  • 새 컴포넌트 추가가 쉬움 (그냥 watch 시작)
  • audit log가 한 곳에

단점:

  • API Server가 bottleneck이 될 수 있음
  • etcd 부하가 큼

대규모 클러스터에서는 이 부하를 다루는 것이 큰 도전.


4. etcd — 분산 KV의 토대

4.1 etcd가 무엇인가

etcd는 분산 key-value store. CoreOS가 만들고 (이름이 /etc + d, "Linux 설정의 분산 버전"), 지금은 CNCF 프로젝트.

핵심 특징:

  • 분산: 여러 노드에서 Raft로 합의
  • 일관성: linearizable reads/writes
  • watch: key 변경 알림
  • transaction: compare-and-swap
  • lease: TTL 기반 키 만료

4.2 Raft Consensus

etcd는 Raft consensus 알고리즘을 사용한다. 핵심 아이디어:

  • 한 명의 leader가 모든 쓰기를 처리
  • leader가 follower에게 log entry를 복제
  • 과반이 ack하면 commit
  • leader가 죽으면 새 leader 선출

이 모델로 (n/2)+1개의 노드가 살아있으면 클러스터가 동작한다. 3노드 클러스터는 1개 실패 견딤, 5노드는 2개 실패 견딤.

4.3 Kubernetes에서의 etcd

Kubernetes는 모든 객체 (Pod, Service, ConfigMap, Secret 등)를 etcd에 저장한다. 키 형식:

/registry/pods/default/my-pod
/registry/services/default/my-service
/registry/secrets/default/my-secret

객체는 protobuf로 인코딩 (옛날 JSON에서 이전).

4.4 watch 메커니즘

etcd의 핵심 기능. 클라이언트가 한 prefix를 watch하면, 그 아래 키가 변경될 때마다 알림을 받는다.

GET /v3/watch
{ "create_request": { "key": "/registry/pods/" } }

이는 API Server의 watch 인터페이스의 토대. Scheduler, Controller, kubelet 모두 etcd를 (API Server를 통해) watch한다.

4.5 etcd의 한계

etcd는 매우 잘 만들어진 KV이지만, Kubernetes의 desired state store로서 한계가 있다:

  • size 제한: 객체당 최대 1.5MB. ConfigMap, Secret이 이 한도에 가까워질 수 있음.
  • 성능 한계: 약 10K writes/sec. 큰 클러스터에서 bottleneck.
  • 메모리 사용: 모든 데이터가 메모리에 (mmap된 b+tree). 큰 클러스터에서 RAM 압박.
  • rotation: secret rotation이 비싼 작업.

대규모 클러스터에서는 etcd를 신중히 운영해야 한다. CoreDNS 사용량, 자주 변하는 ConfigMap 등이 etcd를 압박할 수 있다.

4.6 etcd 운영

  • 백업: etcdctl snapshot save로 정기 스냅샷.
  • 복원: 스냅샷으로 새 클러스터 부트스트랩.
  • defrag: etcdctl defrag로 디스크 공간 회수.
  • 모니터링: leader 변경 빈도, 디스크 fsync latency, watch latency.

운영 미숙으로 etcd가 깨지면 클러스터가 통째로 망가진다. Kubernetes 운영의 가장 위험한 부분.


5. API Server — 모든 길의 중심

5.1 API Server의 책임

  • REST API 제공 (/api/v1/..., /apis/apps/v1/... 등)
  • 인증 (authentication)
  • 인가 (authorization)
  • admission control
  • watch 분배
  • etcd 접근

거의 모든 Kubernetes 작업이 API Server를 거친다.

5.2 REST 모델

모든 객체가 REST 리소스. 예시:

GET    /api/v1/namespaces/default/pods         # 목록
GET    /api/v1/namespaces/default/pods/my-pod  # 단일 객체
POST   /api/v1/namespaces/default/pods         # 생성
PUT    /api/v1/namespaces/default/pods/my-pod  # 갱신
DELETE /api/v1/namespaces/default/pods/my-pod  # 삭제

이 단순한 모델이 모든 Kubernetes 객체에 적용된다.

5.3 API Group과 versioning

객체는 group과 version으로 분류:

  • core/v1: Pod, Service, Node, ConfigMap, Secret 등
  • apps/v1: Deployment, ReplicaSet, StatefulSet, DaemonSet
  • batch/v1: Job, CronJob
  • networking.k8s.io/v1: Ingress, NetworkPolicy
  • rbac.authorization.k8s.io/v1: Role, RoleBinding

각 group은 자기 versioning을 가진다 (alpha → beta → stable).

5.4 인증 (Authentication)

"누가 요청을 보냈는가"를 결정. 여러 메커니즘:

  • X.509 client certificates: TLS 인증서.
  • ServiceAccount tokens: cluster 안의 워크로드용.
  • Bearer tokens: 외부 OIDC 토큰 (예: Google Workspace, GitHub).
  • Webhook: 외부 인증 서비스에 위임.

API Server는 여러 메커니즘을 동시에 지원. 사용자는 어느 것을 쓸지 결정.

5.5 인가 (Authorization)

"이 사용자가 이 작업을 할 수 있는가"를 결정. 모드:

  • RBAC (가장 일반적): Role-Based Access Control.
  • ABAC: Attribute-Based. 옛날.
  • Webhook: 외부 정책 엔진.
  • Node: kubelet 전용 권한.

RBAC 예시:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

이 Role이 있으면 default namespace의 pod을 read할 수 있다.

5.6 Admission Control

인가 후, 객체가 etcd에 저장되기 전에 실행되는 plugin들. 두 종류:

  • Mutating: 객체를 수정 (예: defaults 채우기).
  • Validating: 객체가 유효한지 검사 (거부 가능).

내장 admission controllers:

  • LimitRanger: namespace의 limit 적용
  • ResourceQuota: namespace의 자원 한도
  • PodSecurityStandard: Pod 보안 정책 (PSA replacement)
  • ServiceAccount: ServiceAccount 자동 마운트

또한 Dynamic Admission Webhook: 사용자가 자기 admission 로직을 webhook으로 등록 가능. cert-manager, Istio injector 등이 이렇게 동작.

5.7 Watch 메커니즘

Kubernetes의 핵심 추상화. 클라이언트가 "이 prefix의 변경을 알려줘"라고 요청하면, API Server가 변경을 stream으로 보낸다.

GET /api/v1/pods?watch=true
< event: ADDED, pod: ...
< event: MODIFIED, pod: ...
< event: DELETED, pod: ...

내부적으로 etcd의 watch를 구독. API Server가 객체를 deserialize하고 list/watch에 맞는 형태로 변환.

5.8 List + Watch 패턴

Kubernetes 클라이언트의 표준 패턴:

  1. List로 현재 상태 받음
  2. 그 시점부터 watch 시작
  3. 변경 이벤트로 로컬 캐시 갱신

이 패턴을 informer라 한다. controller-runtime 라이브러리가 캡슐화.

informer := factory.Core().V1().Pods().Informer()
informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
    AddFunc: func(obj interface{}) { /* ... */ },
    UpdateFunc: func(old, new interface{}) { /* ... */ },
    DeleteFunc: func(obj interface{}) { /* ... */ },
})
informer.Run(stopCh)

5.9 API Aggregation

API Server에 새 API를 추가하는 두 방법:

  • CRD (Custom Resource Definition): API Server가 직접 처리. 가장 일반적.
  • API aggregation: 별도의 API 서버를 띄우고 API Server가 프록시. metrics-server가 이렇게 동작.

CRD가 훨씬 단순. 거의 모든 새 리소스는 CRD로.


6. Scheduler — Pod을 노드에 매칭

6.1 Scheduler의 책임

새 Pod이 만들어졌을 때 (spec.nodeName이 비어 있을 때) 어떤 노드에 둘지 결정.

흐름:

  1. 새 Pod을 watch
  2. 후보 노드 필터링 (Filter)
  3. 후보 점수 매기기 (Score)
  4. 최고 점수 노드 선택
  5. API Server에 Pod.spec.nodeName 갱신 요청

6.2 Filter 단계

각 노드에 대해 "이 Pod이 여기 갈 수 있는가?"를 검사. 거부되면 후보에서 제외.

내장 filter들:

  • NodeResourcesFit: 노드에 충분한 CPU/메모리가 있는가?
  • NodeAffinity: Pod의 affinity 규칙을 만족하는가?
  • PodAffinity / PodAntiAffinity: 다른 Pod과의 관계
  • TaintToleration: 노드의 taint를 견디는가?
  • VolumeBinding: 필요한 volume을 마운트할 수 있는가?
  • PodTopologySpread: topology 분산 규칙

6.3 Score 단계

남은 후보들에 점수를 매김. 가장 높은 점수 노드 선택.

내장 scorer들:

  • NodeResourcesBalancedAllocation: CPU와 메모리 사용 비율이 균형
  • NodeResourcesLeastAllocated: 자원이 가장 많이 남은 노드 선호
  • NodePreferAvoidPods: avoid 어노테이션 회피
  • InterPodAffinity: 같은 라벨의 Pod과 가까이/멀리

6.4 알고리즘의 우아함

Filter + Score 모델은 매우 일반적이다. 새 정책을 추가하려면 새 plugin을 작성하면 된다. Scheduler Framework가 이 plugin model을 지원.

type FilterPlugin interface {
    Filter(ctx context.Context, state *CycleState, pod *Pod, nodeInfo *NodeInfo) *Status
}

type ScorePlugin interface {
    Score(ctx context.Context, state *CycleState, pod *Pod, nodeName string) (int64, *Status)
}

6.5 Bin Packing

Kubernetes의 scheduling은 본질적으로 bin packing 문제 — N개의 노드와 M개의 Pod, 어떻게 최적으로 배치하나. Greedy 알고리즘으로 풀지만, 최적은 아니다.

문제: 한 번 배치하면 거의 옮기지 않는다. 시간이 지나면서 단편화가 일어남. Descheduler라는 옵션 컴포넌트가 일부 Pod을 evict해서 더 좋은 배치를 유도.

6.6 Custom Scheduler

여러 scheduler를 동시에 띄울 수 있다. Pod의 spec.schedulerName으로 선택.

spec:
  schedulerName: my-custom-scheduler

ML 워크로드용, 게임 서버용, batch 잡용 등 워크로드별 scheduler가 존재.

6.7 Scheduler의 한계

  • Greedy: 최적이 아님
  • Single decision point: 큰 클러스터에서 bottleneck 가능
  • No preemption by default: 우선순위 낮은 Pod이 자원을 차지하면 새 Pod이 못 들어옴 (PriorityClass로 해결)

7. Controller Manager — 수렴의 엔진

7.1 Controller 패턴

Kubernetes의 핵심 디자인 패턴. 각 controller는:

  1. desired state를 watch (etcd via API Server)
  2. actual state를 관찰
  3. 차이를 줄이는 작업 수행
  4. 영원히 반복
for {
    desired := getDesiredState()
    actual := getActualState()
    if desired != actual {
        reconcile(desired, actual)
    }
}

이 단순한 모델이 Kubernetes의 모든 자동화의 토대.

7.2 핵심 controllers

  • Deployment Controller: Deployment의 desired replica → ReplicaSet 생성/갱신.
  • ReplicaSet Controller: ReplicaSet의 desired replica → Pod 생성/삭제.
  • StatefulSet Controller: 순서 있는 Pod 관리.
  • DaemonSet Controller: 모든 노드에 한 Pod 보장.
  • Job Controller: 일회성 Pod 실행 + 완료 추적.
  • Node Controller: 노드 health 추적 + 죽은 노드의 Pod evict.
  • Service Controller: Service에 endpoint 관리.
  • Endpoint Controller: Service ↔ Pod 매핑.
  • Namespace Controller: namespace 삭제 시 정리.
  • PersistentVolume Controller: PV ↔ PVC 바인딩.

7.3 Reconciliation Loop의 우아함

각 controller는 단순한 함수: "현재 상태 + 원하는 상태 → 액션." 이 함수가 계속 호출된다.

이 모델의 장점:

  • Idempotent: 같은 입력 → 같은 액션. 안전하게 재실행 가능.
  • Self-healing: 실패해도 다음 iteration이 다시 시도.
  • Observable: 모든 변경이 API Server를 거침. 감사 가능.

단점:

  • Eventual consistency: 즉시 반영 안 됨. 보통 수 초.
  • Watch lag: watch가 늦어지면 결정도 늦어짐.

7.4 Custom Controller (Operator)

사용자가 자기 controller를 작성할 수 있다. 이를 Operator라 한다.

흐름:

  1. CRD 정의 (MyApp 같은 새 객체)
  2. Controller 작성 (MyApp 변경 시 무엇을 할지)
  3. 클러스터에 배포

이 패턴이 Kubernetes의 확장성의 핵심이다. PostgreSQL, Cassandra, Kafka 등 모든 stateful 워크로드가 자기 operator를 가진다.

★ Insight ─────────────────────────────────────

  • Reconciliation loop는 Borg에서 가져온 핵심 패턴: Borg 팀의 깨달음 — "RPC 기반 명령형 시스템은 부분 실패에 약하다." 모든 상태를 declarative하게 두고, controller가 영원히 수렴시키면 부분 실패가 자동 복구된다. 이 패턴이 Kubernetes의 모든 자동화의 토대.
  • Operator 패턴은 Kubernetes의 진짜 확장성: CRD + Controller만으로 새로운 리소스 타입을 추가할 수 있다는 사실이 Kubernetes를 단순한 컨테이너 오케스트레이터에서 일반적인 분산 시스템 플랫폼으로 만들었다. PostgreSQL, Kafka, Cassandra 모두 자기 Operator로 자동 운영된다.
  • Eventual consistency의 트레이드오프: Kubernetes는 strong consistency를 약속하지 않는다. 변경이 적용되는 데 수 초가 걸릴 수 있다. 이는 의도된 디자인 — strong consistency를 약속하면 시스템이 훨씬 복잡하고 느려진다. 사용자는 이 모델에 적응해야 한다. ─────────────────────────────────────────────────

8. kubelet — 노드의 에이전트

8.1 kubelet의 책임

각 노드에서 도는 데몬. 책임:

  1. API Server를 watch해서 자기 노드에 할당된 Pod을 발견
  2. CRI를 통해 컨테이너 시작/중지
  3. CNI를 통해 네트워크 설정
  4. CSI를 통해 볼륨 마운트
  5. Pod 상태를 API Server에 보고
  6. liveness/readiness probe 실행
  7. 노드 상태 보고

8.2 Pod Lifecycle

새 Pod의 생애:

  1. Pending: 노드에 할당되었지만 아직 시작 안 됨
  2. ContainerCreating: 이미지 pull 중, 컨테이너 생성 중
  3. Running: 컨테이너가 실행 중
  4. Succeeded / Failed: 종료
  5. Unknown: kubelet과 통신 못 함

kubelet이 이 모든 단계를 관리.

8.3 Probe — Liveness, Readiness, Startup

각 컨테이너는 세 종류의 probe를 가질 수 있다:

  • Liveness Probe: "아직 살아있는가?" 실패하면 컨테이너 재시작.
  • Readiness Probe: "트래픽 받을 준비가 되었는가?" 실패하면 Service에서 제외.
  • Startup Probe: 초기화 중. 통과하면 liveness/readiness 시작.
livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 5

probe 종류: HTTP, TCP, exec. 정기적으로 (periodSeconds) 호출되고, 실패가 (failureThreshold)번 이상이면 액션.

8.4 Resource Limits

Pod의 spec에 있는 resources.limits를 cgroup으로 강제.

resources:
  requests:
    cpu: "100m"        # 0.1 코어 보장
    memory: "128Mi"    # 128MB 보장
  limits:
    cpu: "500m"        # 0.5 코어 hard cap
    memory: "256Mi"    # 256MB hard cap

requests는 scheduler가 사용 (보장된 양). limits는 kubelet이 cgroup에 적용 (hard cap). 컨테이너 글에서 봤다.

8.5 Node Status

kubelet이 주기적으로 노드 상태를 API Server에 보고. 30초마다.

status:
  conditions:
  - type: Ready
    status: "True"
  - type: MemoryPressure
    status: "False"
  - type: DiskPressure
    status: "False"
  - type: PIDPressure
    status: "False"
  capacity:
    cpu: "8"
    memory: "32Gi"
    pods: "110"

Node Controller가 이를 보고 죽은 노드를 감지 (5분 동안 ready=False면 그 노드의 Pod evict).

8.6 Eviction

노드의 자원 압박이 심해지면 kubelet이 Pod을 evict한다:

  • Soft eviction: grace period 후 evict
  • Hard eviction: 즉시 evict

eviction 우선순위:

  1. BestEffort (limits 없음) — 가장 먼저
  2. Burstable (limit < request)
  3. Guaranteed (limit == request) — 마지막

이 우선순위 때문에 Guaranteed Pod이 가장 안정적.

8.7 Static Pod

kubelet이 직접 관리하는 Pod (API Server 거치지 않음). /etc/kubernetes/manifests/에 YAML 파일을 두면 자동 실행.

용도: control plane 자체를 부트스트랩. kube-apiserver가 죽으면 다른 Pod도 못 만드는데, static pod은 동작 가능.


9. kube-proxy — Service의 구현

9.1 Service가 무엇인가

Service는 Pod 그룹에 대한 안정적인 endpoint. Pod은 죽고 다시 만들어지므로 IP가 바뀌지만, Service의 IP는 유지된다.

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 8080

이 Service는 라벨 app=nginx인 모든 Pod의 8080 포트를 ClusterIP의 80 포트로 노출.

9.2 ClusterIP

Service의 기본 타입. 클러스터 내부에서만 접근 가능한 가상 IP.

$ kubectl get svc
NAME         TYPE        CLUSTER-IP      PORT(S)
my-service   ClusterIP   10.96.123.456   80/TCP

이 IP는 어디에도 실제로 존재하지 않는다. kube-proxy가 마법으로 만들어낸다.

9.3 kube-proxy의 동작

kube-proxy는 각 노드에서 도는 데몬. Service와 Endpoint를 watch하고, 노드의 네트워크 규칙을 갱신한다.

세 가지 모드:

9.3.1 iptables 모드

기본. Service IP로 가는 패킷을 iptables 규칙으로 가로채서 random한 백엔드 Pod으로 DNAT.

-A KUBE-SERVICES -d 10.96.123.456/32 -p tcp --dport 80 -j KUBE-SVC-XXX
-A KUBE-SVC-XXX -m statistic --mode random --probability 0.5 -j KUBE-SEP-AAA
-A KUBE-SVC-XXX -j KUBE-SEP-BBB
-A KUBE-SEP-AAA -p tcp -j DNAT --to-destination 10.0.1.10:8080
-A KUBE-SEP-BBB -p tcp -j DNAT --to-destination 10.0.2.20:8080

장점: 단순. 네이티브 Linux 기능. 단점: 큰 클러스터에서 규칙 수 폭증 (Service × Endpoint). iptables 갱신이 느려짐.

9.3.2 IPVS 모드

L4 로드 밸런서 (ip_vs 커널 모듈) 사용. iptables보다 효율적.

장점: 큰 클러스터에서 더 빠름. round-robin, least-conn 같은 알고리즘 지원. 단점: 더 복잡. 일부 환경에서 호환성 문제.

9.3.3 eBPF 모드 (Cilium)

Cilium이 kube-proxy를 완전히 대체. BPF map을 사용. iptables 없음.

장점: 가장 빠름. 일관된 성능. 더 풍부한 기능. 단점: Cilium 자체가 복잡.

eBPF 글에서 봤다.

9.4 Service 타입들

  • ClusterIP: 클러스터 내부.
  • NodePort: 각 노드의 특정 포트로 노출.
  • LoadBalancer: 클라우드 LB로 노출 (EKS는 ELB, GKE는 GCLB).
  • ExternalName: DNS CNAME.

9.5 Endpoint Controller

Service의 selector에 매칭되는 Pod의 IP를 모은다. Endpoints (또는 v1.21+에서 EndpointSlice) 객체에 저장.

kube-proxy가 이를 보고 네트워크 규칙을 갱신.

9.6 EndpointSlice

Endpoints는 한 객체에 모든 endpoint를 담았다. 큰 Service에서는 객체 크기가 폭증. EndpointSlice는 작은 그룹으로 분할.

이는 etcd 부담을 줄이고 watch 효율을 높인다.


10. CRI, CNI, CSI — 플러그인 인터페이스

10.1 CRI (Container Runtime Interface)

kubelet과 컨테이너 런타임 사이의 인터페이스. gRPC.

service RuntimeService {
    rpc CreatePodSandbox(CreatePodSandboxRequest) returns (CreatePodSandboxResponse);
    rpc StartContainer(StartContainerRequest) returns (StartContainerResponse);
    rpc StopContainer(StopContainerRequest) returns (StopContainerResponse);
    rpc RemoveContainer(RemoveContainerRequest) returns (RemoveContainerResponse);
    // ...
}

구현체:

  • containerd (가장 일반적)
  • CRI-O (Red Hat)
  • Docker shim (deprecated, 1.24에서 제거)
  • runc는 CRI를 직접 구현하지 않음 (containerd가 위층)

10.2 CNI (Container Network Interface)

컨테이너 네트워킹의 표준. 매우 단순한 모델:

ADD <network> <container>   # 컨테이너에 네트워크 추가
DEL <network> <container>   # 제거
CHECK <network> <container> # 검증

CNI plugin은 binary. config가 /etc/cni/net.d/. kubelet이 컨테이너 시작 시 호출.

컨테이너 글에서 봤다.

주요 plugin들:

  • bridge: 단순 bridge
  • calico: BGP 기반
  • flannel: VXLAN 기반
  • cilium: eBPF 기반
  • weave: 메시

10.3 CSI (Container Storage Interface)

스토리지 플러그인의 표준. gRPC 인터페이스.

service Identity { /* ... */ }
service Controller {
    rpc CreateVolume(CreateVolumeRequest) returns (CreateVolumeResponse);
    rpc DeleteVolume(DeleteVolumeRequest) returns (DeleteVolumeResponse);
    rpc ControllerPublishVolume(...);  // attach
    // ...
}
service Node {
    rpc NodeStageVolume(...);    // mount on node
    rpc NodePublishVolume(...);  // bind mount to pod
    // ...
}

구현체:

  • AWS EBS CSI Driver
  • GCE PD CSI Driver
  • Azure Disk CSI Driver
  • Ceph CSI
  • Longhorn

CSI 덕분에 Kubernetes가 어떤 스토리지 시스템과도 통합 가능.

10.4 Plugin 모델의 우아함

세 인터페이스가 같은 패턴: 표준 API + 다양한 구현. 사용자는 자기 환경에 맞는 구현을 고른다.

이 모델 덕분에 Kubernetes는:

  • 어떤 컨테이너 런타임에도 작동
  • 어떤 네트워크에도 작동
  • 어떤 스토리지에도 작동

벤더 락인이 없다 — Kubernetes 자체가 표준이고, 구현체는 갈아끼울 수 있다.


11. 핵심 객체들

11.1 Pod

가장 작은 배포 단위. 한 개 이상의 컨테이너 그룹.

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: main
    image: nginx
  - name: sidecar
    image: log-forwarder

같은 Pod의 컨테이너는 namespace를 공유 (컨테이너 글 참고).

11.2 ReplicaSet

같은 Pod template으로 N개의 복제본 보장.

apiVersion: apps/v1
kind: ReplicaSet
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx

직접 사용 안 함. Deployment의 backend.

11.3 Deployment

ReplicaSet 위의 더 똑똑한 추상화. rolling update, rollback 지원.

apiVersion: apps/v1
kind: Deployment
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    # ...

이미지를 바꾸면 새 ReplicaSet을 만들고, 옛 RS를 점진적으로 줄임. 잘못되면 kubectl rollout undo로 롤백.

11.4 StatefulSet

순서가 있는 Pod 관리. 데이터베이스, message queue 같은 stateful 워크로드용.

특징:

  • 순서 있는 시작/종료 (my-db-0, my-db-1, ...)
  • 안정적인 hostname
  • PV 자동 매칭
  • 한 번에 하나만 업데이트 (기본)

11.5 DaemonSet

각 노드에 정확히 하나의 Pod 보장. 노드 단위 데몬용 (로그 수집기, 모니터링 에이전트).

apiVersion: apps/v1
kind: DaemonSet
spec:
  selector:
    matchLabels:
      app: fluentd
  template:
    # ...

새 노드가 추가되면 자동으로 Pod 추가.

11.6 Job / CronJob

  • Job: 한 번 실행되고 끝나는 워크로드. 배치 처리.
  • CronJob: cron schedule로 Job을 주기적 실행.

11.7 ConfigMap / Secret

  • ConfigMap: 설정 데이터.
  • Secret: 민감 데이터 (base64 인코딩, 일부 환경에서 암호화).

Pod에 환경 변수 또는 볼륨으로 마운트.


12. Networking — Service, Ingress, NetworkPolicy

12.1 Pod 네트워킹의 기본

Kubernetes 네트워킹의 4가지 약속:

  1. 모든 Pod이 unique IP
  2. 모든 Pod이 NAT 없이 서로 통신 가능
  3. 모든 노드가 NAT 없이 모든 Pod과 통신 가능
  4. Pod이 자기 IP로 서로를 본다

CNI plugin이 이를 구현한다. flannel, calico, cilium 등.

12.2 Service Discovery

Kubernetes는 DNS를 통해 service discovery 제공. CoreDNS가 클러스터의 DNS 서버.

my-service.my-namespace.svc.cluster.local → ClusterIP

Pod 안에서 curl my-service로 접근 가능 (/etc/resolv.conf가 자동 설정됨).

12.3 Headless Service

clusterIP: None인 Service. ClusterIP 대신 DNS가 직접 Pod IP 목록을 반환.

용도: StatefulSet의 각 Pod에 직접 접근. 데이터베이스 클라이언트가 특정 replica를 선택할 때.

12.4 Ingress

L7 진입점. HTTP 라우팅. 외부에서 클러스터 안으로의 트래픽.

apiVersion: networking.k8s.io/v1
kind: Ingress
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

Ingress controller가 이 리소스를 구현. Nginx Ingress, Traefik, HAProxy, Contour 등.

12.5 Gateway API

Ingress의 차세대. 더 표현력 있고 확장 가능. 2023년 stable.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
spec:
  parentRefs:
  - name: my-gateway
  hostnames: ["api.example.com"]
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: api-service
      port: 80

향후 Ingress를 대체할 가능성.

12.6 NetworkPolicy

Pod 간 통신 제한. 기본은 모든 Pod이 서로 통신 가능. NetworkPolicy로 차단.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-from-other-namespace
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {}

이 정책은 같은 namespace의 Pod만 들어오는 것을 허용.

CNI plugin이 NetworkPolicy를 구현해야 한다 (모든 plugin이 지원하는 건 아님). Calico, Cilium은 잘 지원.


13. Storage — PV, PVC, StorageClass

13.1 추상화 모델

  • PersistentVolume (PV): 클러스터의 스토리지 자원. 관리자가 만들거나 동적 프로비저닝.
  • PersistentVolumeClaim (PVC): 사용자의 스토리지 요청.
  • StorageClass: PV의 type. 동적 프로비저닝.

13.2 흐름

  1. 사용자가 PVC 생성 ("100GB SSD가 필요해")
  2. PV Controller가 매칭되는 PV 찾음 (또는 동적으로 생성)
  3. 바인딩
  4. Pod이 PVC 마운트
  5. kubelet이 CSI를 통해 볼륨 attach + mount
  6. 컨테이너에 바인드 마운트

13.3 동적 프로비저닝

PVC가 만들어지면 StorageClass가 자동으로 PV를 만든다. 클라우드의 EBS, GCE PD가 이렇게 동작.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  storageClassName: gp3
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi

이 PVC가 만들어지면 EBS gp3 100GB 볼륨이 자동 생성.

13.4 Access Mode

  • ReadWriteOnce (RWO): 한 노드만 read+write. 대부분의 블록 스토리지.
  • ReadOnlyMany (ROX): 여러 노드가 read-only.
  • ReadWriteMany (RWX): 여러 노드가 read+write. NFS, CephFS 같은 공유 파일시스템.

13.5 StatefulSet과 Volume

StatefulSet은 각 Pod에 고유한 PVC를 만든다.

volumeClaimTemplates:
- metadata:
    name: data
  spec:
    accessModes: [ "ReadWriteOnce" ]
    storageClassName: gp3
    resources:
      requests:
        storage: 100Gi

my-db-0, my-db-1, my-db-2 각자 자기 100GB PV를 가진다. Pod이 죽고 다시 만들어져도 같은 PV에 다시 마운트.


14. 보안 — RBAC, NetworkPolicy, Pod Security

14.1 RBAC

Role-Based Access Control. 누가 무엇을 할 수 있는지.

핵심 객체:

  • Role / ClusterRole: 권한 정의
  • RoleBinding / ClusterRoleBinding: Role을 사용자/ServiceAccount에 할당
# Role: pod 읽기
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
---
# RoleBinding: pod-reader를 사용자 alice에게
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: default
  name: alice-can-read-pods
subjects:
- kind: User
  name: alice
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

14.2 ServiceAccount

Pod 안의 워크로드가 API Server를 호출할 때 사용하는 identity.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-app
---
apiVersion: v1
kind: Pod
spec:
  serviceAccountName: my-app
  # ...

ServiceAccount의 token이 Pod 안에 자동 마운트 (/var/run/secrets/kubernetes.io/serviceaccount/token). 이 토큰으로 API Server를 호출.

14.3 Pod Security Standards (PSS)

Pod의 보안 수준을 정의:

  • privileged: 제한 없음
  • baseline: 일반적인 보안 (host namespace 사용 금지 등)
  • restricted: 매우 엄격 (root 금지, capability 제한 등)

namespace 단위 enforce 가능:

metadata:
  labels:
    pod-security.kubernetes.io/enforce: restricted

옛날 PodSecurityPolicy를 대체. 1.25에서 PSP 제거, PSS가 표준.

14.4 NetworkPolicy

위에서 봤다. Pod 간 트래픽 제한.

14.5 Secrets 관리

Kubernetes Secret은 base64 인코딩일 뿐 (암호화 아님). 진짜 보안을 위해:

  • etcd encryption at rest: etcd 데이터를 디스크에서 암호화.
  • External secret managers: HashiCorp Vault, AWS Secrets Manager 등을 외부에서 사용.
  • Sealed Secrets: 클러스터에서만 복호화 가능한 암호화 secret.

15. Kubernetes의 한계와 문제점

15.1 복잡함

학습 곡선이 가파르다. 단순한 앱을 띄우는 데도 여러 객체가 필요. "Kubernetes는 너무 복잡하다"는 흔한 불평.

15.2 etcd 부담

큰 클러스터에서 etcd가 bottleneck. 5000+ 노드면 신중한 운영 필요.

15.3 네트워킹 복잡

CNI, Service, Ingress, NetworkPolicy, ServiceMesh가 모두 함께. 디버깅이 어려움.

15.4 비용

control plane 자체가 자원을 많이 쓴다. 작은 워크로드에는 over-engineering일 수 있다.

15.5 멀티테넌시 약함

namespace는 약한 격리. 진짜 멀티테넌시가 필요하면 별도 클러스터.


16. 대안과 비교

16.1 Nomad (HashiCorp)

더 단순. Kubernetes보다 가벼움. 컨테이너뿐 아니라 일반 프로세스, JVM 앱도 관리. 작은-중간 규모에 적합.

16.2 Docker Swarm

Docker의 내장 오케스트레이션. 매우 단순. Docker만 알면 사용 가능. 그러나 거의 deprecated 상태.

16.3 Mesos

옛날 클러스터 매니저. Twitter, Apple 등이 사용했다. 지금은 거의 사라짐. Kubernetes에 패배.

16.4 ECS (AWS)

AWS 전용 컨테이너 오케스트레이션. Kubernetes보다 단순하지만 AWS lock-in.

16.5 Cloud Run, Lambda

서버리스. 컨테이너지만 오케스트레이션을 사용자가 안 함. 단순한 워크로드에 적합.

16.6 어떤 것을 쓸 것인가

  • 표준이 중요, 대규모, 멀티 클라우드 → Kubernetes
  • 간단함이 중요, 작은 규모 → Nomad 또는 ECS
  • stateless, 단순 HTTP → Cloud Run, Lambda
  • AWS 전용 → ECS
  • edge / 작은 노드 → k3s

17. 미래 — Kubernetes의 다음 단계

17.1 Sidecar-less Service Mesh

Istio, Linkerd 같은 service mesh가 sidecar 없이 동작하는 방향. eBPF 기반. Cilium이 선두. (eBPF 글)

17.2 Gateway API

Ingress를 대체하는 새 API. 더 풍부하고 표현력 있음.

17.3 WebAssembly Workloads

WASM을 컨테이너의 보완 또는 대안으로. krustlet, wasmCloud. 더 가벼운 unit of deployment.

17.4 Confidential Computing

SGX, SEV로 컨테이너의 데이터를 호스트로부터도 보호. 멀티테넌트 환경.

17.5 KubeVirt

Kubernetes로 VM도 관리. 컨테이너와 VM을 한 플랫폼에서.

17.6 sched_ext와 Pod Scheduling

Linux 스케줄러 글에서 본 sched_ext가 Kubernetes 워크로드별 스케줄링을 가능하게 할 수 있다.


18. 결론 — Kubernetes는 분산 시스템의 표준이 되었다

이 글을 다 읽으면 다음 질문에 답할 수 있을 것이다:

  • Kubernetes의 control plane은 어떤 컴포넌트로 이루어져 있나?
  • etcd가 어떻게 일관성을 보장하나?
  • API Server의 watch 메커니즘은 무엇인가?
  • Scheduler의 filter/score 모델은?
  • Controller의 reconciliation loop는?
  • kubelet이 노드에서 무엇을 하나?
  • CRI/CNI/CSI는 무엇을 표준화하나?
  • Service가 어떻게 구현되나?
  • RBAC와 NetworkPolicy의 차이는?

Kubernetes는 단순한 도구가 아니다. Borg에서 출발해 10년 동안 진화한, 분산 시스템 디자인의 정점이다. 모든 메이저 클라우드의 관리형 서비스, 거의 모든 새 인프라 프로젝트의 토대, 그리고 모든 cloud-native 아키텍처의 가정. 이를 깊이 이해하는 것은 모던 인프라 엔지니어의 필수 교양이다.

이 글로 Linux 인프라 시리즈가 완성되었다. 일곱 글:

  1. Linux 부팅 — 부팅
  2. Linux 스케줄러 — CPU
  3. io_uring — I/O
  4. Linux 메모리 관리 — Memory
  5. eBPF — 커널 확장
  6. 컨테이너 — 격리 단위
  7. 이 글 — 클러스터 오케스트레이션

이 일곱 글이 모이면 "내 코드가 어떻게 살아가는가"의 풍경 전체가 그려진다. 부팅된 Linux 위에서, 격리된 컨테이너 안에서, 클러스터의 한 노드 위에서, 전체 시스템의 한 부분으로 — 이것이 모던 cloud-native 인프라이다.

다음 글에서는 [Service Mesh와 Cilium 내부 구조] 또는 [Observability — Prometheus, OpenTelemetry, Jaeger]를 다룰 예정이다. Kubernetes 위에 쌓인 layer들이 아직 많다.


부록 A — 참고 자료

부록 B — 자주 묻는 질문

Q: Kubernetes를 처음 배우려면 어디서 시작해야 하나? A: minikube로 로컬 클러스터 만들고, 공식 tutorial 따라하기. 기본 객체 (Pod, Service, Deployment) 익숙해진 후 더 복잡한 것으로.

Q: 작은 앱에도 Kubernetes가 필요한가? A: 보통 아니다. Docker Compose, systemd, 또는 PaaS (Render, Fly.io)가 더 단순. Kubernetes는 복잡성과 운영 비용이 큰 가치를 줄 때만.

Q: Kubernetes는 self-hosted vs managed, 어떤 것이 좋나? A: 작은 팀이면 항상 managed (EKS, GKE, AKS). 큰 회사에 전담 인프라 팀이 있으면 self-hosted도 가능.

Q: etcd 운영이 정말 위험한가? A: 그렇다. backup, monitoring, defrag, version upgrade 모두 신중해야. managed Kubernetes는 이 모든 것을 자동화.

Q: Kubernetes를 deprecate하려는 움직임이 있나? A: 없다. 오히려 표준이 더 굳어지고 있다. 대안 (Nomad, ECS)도 있지만 Kubernetes가 사실상 표준.

Q: Kubernetes 운영의 가장 큰 도전은? A: 네트워킹, 스토리지, etcd 운영, 그리고 사람 (학습 곡선). 도구는 좋지만 사람이 따라가야.

Q: Kubernetes에서 데이터베이스를 돌려도 되나? A: 가능. operator (PostgreSQL Operator, MySQL Operator)가 잘 만들어져 있음. 그러나 managed RDS도 매력적.

Q: kubectl 외에 어떤 도구를 알아야 하나? A: helm (패키지), kustomize (오버레이), k9s (TUI), stern (로그), kubectx/kubens (컨텍스트), lens (GUI).


부록 C — 미니 용어집

  • Cluster: 전체 Kubernetes 환경.
  • Node: 클러스터의 한 머신 (VM 또는 물리).
  • Control Plane: API server, etcd, scheduler, controller manager.
  • Data Plane: 노드들 (kubelet + 컨테이너 런타임).
  • Pod: 가장 작은 배포 단위, 컨테이너 그룹.
  • ReplicaSet: N개의 Pod replicas 보장.
  • Deployment: ReplicaSet + rolling update.
  • StatefulSet: 순서 있는 Pod (DB용).
  • DaemonSet: 모든 노드에 한 Pod.
  • Job: 일회성 배치.
  • CronJob: 주기적 Job.
  • Service: Pod 그룹의 안정적 endpoint.
  • Ingress: HTTP 진입점.
  • Gateway API: 차세대 Ingress.
  • NetworkPolicy: Pod 간 네트워크 정책.
  • PV / PVC / StorageClass: 스토리지 추상화.
  • ConfigMap / Secret: 설정과 secret.
  • Namespace: 논리적 격리.
  • RBAC: 권한 모델.
  • ServiceAccount: 워크로드의 identity.
  • CRD: Custom Resource Definition.
  • Operator: CRD + Controller.
  • etcd: 분산 KV store.
  • API Server: 중심 API.
  • Scheduler: Pod → Node 할당.
  • Controller Manager: reconciliation loop들.
  • kubelet: 노드 에이전트.
  • kube-proxy: 노드 네트워크 프록시.
  • CRI: Container Runtime Interface.
  • CNI: Container Network Interface.
  • CSI: Container Storage Interface.
  • Reconciliation loop: desired vs actual 수렴.
  • Watch: 변경 알림 메커니즘.
  • Informer: list+watch 패턴.
  • Helm: 패키지 매니저.
  • Kustomize: 오버레이 도구.

이 글로 Linux 인프라 시리즈가 일곱 글로 완성되었다. 부팅, 스케줄러, io_uring, 메모리, eBPF, 컨테이너, 그리고 이 글까지 — 일곱 글이 모이면 모던 cloud-native 인프라의 풍경 전체가 그려진다. 다음에는 그 위에 쌓인 layer들 (service mesh, observability, GitOps, …)을 차례로 다뤄볼 차례이다.

현재 단락 (1/767)

`kubectl apply -f deployment.yaml`. 한 줄의 명령어로 컨테이너가 클러스터 어딘가에 배포되고, 죽으면 자동으로 다시 시작되고, 트래픽이 분산되고, 업데이...

작성 글자: 0원문 글자: 28,886작성 단락: 0/767