쿠버네티스 학습 노트 목차

쿠버네티스는 무엇을 대신해 주나 — 구조부터

컨테이너를 만들 줄 알게 되면 다음 질문이 온다. "이걸 서버 30대에 어떻게 띄우고, 죽으면 누가 다시 띄우나?" 그 일을 대신하는 것이 오케스트레이터다.


1. 손으로 하면 무엇이 문제인가

서버 30대에 컨테이너를 띄운다고 하자

  • 어느 서버에 띄울지 누가 정하나 (자원이 남는 곳을 찾아야 한다)
  • 컨테이너가 죽으면 누가 다시 띄우나
  • 서버가 죽으면 그 위의 것들을 어디로 옮기나
  • 새 버전을 어떻게 무중단으로 바꾸나
  • 주소가 계속 바뀌는데 서로를 어떻게 찾나
  • 설정과 비밀은 어떻게 배포하나

전부 사람이 하면 서버 3대까지는 되고, 30대부터는 안 된다

2. 선언적 모델 — "이렇게 되어 있어라"

이것이 쿠버네티스의 핵심 발상이다.

  • 명령형 — "컨테이너를 3개 띄워라"

    • 하나 죽으면 누군가 알아채고 다시 명령해야 한다
  • 선언형 — "항상 3개가 떠 있는 상태여야 한다"

    • 시스템이 계속 비교하고 스스로 맞춘다
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3          # ← 원하는 상태(desired state)
  selector:
    matchLabels: { app: web }
  template:
    metadata:
      labels: { app: web }
    spec:
      containers:
        - name: web
          image: myapp:1.4.2

조정 루프(reconciliation loop)

컨트롤러가 무한히 반복한다

  • 현재 상태를 관찰한다 — → 파드가 2개 떠 있다 원하는 상태와 비교한다 → 3개여야 한다 차이를 줄이는 동작을 한다 → 1개를 더 만든다

이 루프가 쿠버네티스의 거의 모든 기능을 설명한다 Deployment · Service · Job · 오토스케일러 · 인그레스 컨트롤러 — 전부 자기 종류의 리소스를 보고 같은 루프를 돈다

그래서 kubectl apply 는 "실행" 이 아니라 "선언" 이다. 원하는 상태를 저장할 뿐이고, 실제로 맞추는 것은 컨트롤러다. 명령이 성공했다고 파드가 떴다는 뜻이 아니다.

3. 클러스터 구조

다이어그램 로딩 중…

컨트롤 플레인

  • kube-apiserver — 모든 요청의 단일 진입점. REST API

    • 인증 → 인가 → 어드미션 → etcd 기록
    • 유일하게 etcd 와 직접 말한다
  • etcd — 클러스터의 모든 상태를 담은 키-값 저장소

    • 여기가 곧 '진실' 이다. 백업 대상 1순위
    • Raft 합의를 쓰므로 홀수(3·5)로 구성한다
  • kube-scheduler — 새 파드를 '어느 노드에 둘지' 정한다

    • 정하기만 하고 실행은 안 한다 (노드 이름을 기록할 뿐)
  • controller-manager 여러 컨트롤러를 한 프로세스에 모아 돌린다

    • Deployment · ReplicaSet · Node · Job · 엔드포인트 …
  • cloud-controller-manager

    • 클라우드 연동 (로드밸런서 생성 · 노드 등록 · 볼륨)

워커 노드

  • kubelet — 노드의 대리인. "내 노드에 배정된 파드" 를 API 서버에서 받아

    • 런타임에게 실행을 시킨다. 상태를 계속 보고한다
    • kubelet 이 죽으면 그 노드의 파드는 계속 돌지만
      • 새 배포·상태 보고가 멈춘다 (NotReady)
  • kube-proxy서비스 가상 IP 로 온 트래픽을 실제 파드로 보낸다

    • iptables 또는 IPVS 규칙을 관리한다
  • 컨테이너 런타임 — containerd · CRI-O — 실제로 컨테이너를 만든다

4. 파드가 뜨기까지 — 요청 하나의 여정

  • ① kubectl apply

    • API 서버에 요청
  • ② 인증 → 인가(RBAC) → 어드미션 웹훅

    • 통과하면 etcd 에 기록. 이 시점의 파드는 nodeName 이 비어 있다
  • ③ 스케줄러가 '노드가 안 정해진 파드' 를 발견

    • 필터링(둘 수 있는 노드) → 스코어링(가장 좋은 노드)
    • 파드에 nodeName 을 적는다 (바인딩)
  • ④ 그 노드의 kubelet 이 자기 파드가 생긴 것을 발견

  • ⑤ kubelet 이 상태를 API 서버에 보고 (Pending → Running)

    • 프로브가 통과하면 Ready
  • ⑥ 엔드포인트 컨트롤러가 Ready 파드를 서비스 엔드포인트에 추가

    • 그제야 트래픽이 온다

이 순서를 알면 트러블슈팅이 쉬워진다. 파드가 Pending 이면 ③에서 막힌 것이고, ImagePullBackOff 면 ④, Running 인데 트래픽이 안 오면 ⑥이다.

5. 모든 것이 API 리소스다

apiVersion   어느 API 그룹·버전인가   apps/v1 · v1 · networking.k8s.io/v1
kind         무엇인가                 Deployment · Service · Pod
metadata     이름 · 네임스페이스 · 라벨 · 애너테이션
spec         원하는 상태 (우리가 쓴다)
status       현재 상태 (시스템이 쓴다)
kubectl api-resources          # 이 클러스터가 아는 리소스 종류 전부
kubectl explain deployment.spec.strategy   # 필드 문서를 CLI 에서

kubectl explain 은 시험에서도 실무에서도 가장 쓸모 있는 명령이다 문서를 찾지 않고 필드 구조를 확인할 수 있다

확장도 같은 방식이다

CRD (CustomResourceDefinition)

  • 새 kind 를 등록한다. 그 순간부터 kubectl 로 다룰 수 있다

오퍼레이터

즉 '쿠버네티스를 확장한다' 는 것은

  • ① 새 리소스 종류를 정의하고
  • ② 그것을 보는 컨트롤러를 만드는 것 이 둘뿐이다. 내부 구조와 완전히 같은 모양이다

6. 네임스페이스 — 논리적 구분

같은 클러스터를 논리적으로 나눈다

네임스페이스에 속하지 않는 것도 있다

  • Node · PersistentVolume · StorageClass · ClusterRole · CRD
  • 클러스터 전체 자원이기 때문이다

kubectl api-resources --namespaced=false 로 확인한다

주의 — 네임스페이스는 '보안 경계' 가 아니다

  • 기본적으로 네임스페이스 간 네트워크 통신이 막히지 않는다
  • 격리가 필요하면 NetworkPolicy 를 별도로 건다

7. 버전과 수명

  • 릴리스 — 약 3~4개월마다 마이너 버전 (1.34 · 1.35 · 1.36 …)

  • 지원 — 최근 3개 마이너 버전. 패치 지원은 약 1년

  • 문서도 현재 + 이전 4개 버전이 제공된다

  • 검색으로 들어간 문서가 어느 버전인지 항상 확인한다

    • 기능 상태(alpha/beta/GA)가 버전마다 다르다

업그레이드는 한 마이너씩 올린다 (1.33 → 1.35 로 건너뛰지 않는다)

  • API 폐기가 마이너 단위로 진행되기 때문이다
  • kubectl 은 API 서버와 ±1 마이너까지 호환된다

최근 흐름 몇 가지

  • 1.34 (2025-08) — DRA(동적 자원 할당) GA — GPU 같은 특수 자원 배분

  • 1.35 (2025-12) — In-Place Pod Resize GA — 재시작 없이 리소스 조정

  • 1.36 (2026-04) — User Namespaces GA — hostUsers: false 로 컨테이너 root 격리

    • Pod 수준 리소스 In-Place 조정 베타
  • 방향이 읽힌다 — AI/ML 워크로드 지원과 보안 기본값 강화다


한눈에 정리

  • 선언적 모델 — "이렇게 되어 있어라" + 조정 루프. apply 는 실행이 아니라 선언
  • 컨트롤 플레인 — apiserver(단일 진입점) · etcd(진실) · scheduler(배치 결정)
    • controller-manager(조정 루프들) · cloud-controller-manager
  • 워커 노드kubelet(대리인) · kube-proxy(서비스 라우팅) · 런타임
  • 파드 생성 — apply → 인가·어드미션 → etcd → 스케줄러 바인딩
    • kubelet 실행 → Ready → 엔드포인트 등록
    • 어디서 막혔는지가 곧 증상이 된다
  • API 리소스 — apiVersion/kind/metadata/spec/status. CRD+오퍼레이터도 같은 모양
  • 네임스페이스 — 논리적 구분이지 보안 경계가 아니다
  • 버전 — 3~4개월 주기 · 최근 3개 지원 · 한 마이너씩 업그레이드

출처 — Kubernetes Docs: "Kubernetes Components" · "Kubernetes API" · "Controllers" · "Namespaces" · "Version Skew Policy" · Releases 페이지 · CNCF CKA Curriculum v1.35 (Cluster Architecture 25%)

워크로드 — 파드부터 Deployment까지