Kubernetes 완벽 가이드 | 아키텍처·스케줄링·Service·etcd·컨트롤러·프로덕션

Kubernetes 완벽 가이드 | 아키텍처·스케줄링·Service·etcd·컨트롤러·프로덕션

이 글의 핵심

이 문서는 Kubernetes를 “사용법”만이 아니라 내부 동작까지 이해할 수 있게 구성한 완벽 가이드입니다. Pod·Deployment·Service·Ingress·ConfigMap·Helm 등 실무 객체는 물론, Pod 스케줄링 알고리즘, Service와 kube-proxy 동작, etcd 합의·데이터 모델, 컨트롤러 조정(reconciliation) 루프, 프로덕션 운영 패턴을 같은 깊이로 다룹니다. 클러스터를 설계·트러블슈팅할 때 필요한 “왜 이렇게 동작하는가”를 연결하는 데 초점을 두었습니다.


1. Kubernetes 아키텍처 한눈에

Kubernetes는 선언적(desired state) API제어 루프(control loop)로 구성됩니다. 사용자가 kubectl apply로 원하는 상태를 etcd에 기록하면, 각 컨트롤러가 실제 상태를 그에 맞추며 수렴시킵니다.

컨트롤 플레인(대표 구성):

  • kube-apiserver: 유일한 API 진입점. 인증·인가·검증 후 etcd에 반영하고, 컴포넌트·노드가 여기서 watch/list를 수행합니다.
  • etcd: 클러스터 상태를 저장하는 분산 키-값 저장소. Raft 합의로 복제됩니다(아래 §4).
  • kube-scheduler: 스케줄링되지 않은(unscheduled) Pod에 대해 적합한 노드를 선택합니다(아래 §3).
  • kube-controller-manager: Deployment, ReplicaSet, Node 등 다수의 컨트롤러를 실행합니다(아래 §5).
  • cloud-controller-manager(해당 시): 클라우드 로드밸런서·라우트 등과 연동합니다.

워커 노드:

  • kubelet: 노드에 할당된 Pod의 생명주기를 관리하고, CRI(Container Runtime Interface)로 컨테이너를 기동합니다.
  • kube-proxy: Service에 대한 클러스터 내부 로드밸런싱·NAT 규칙을 구성합니다(아래 §6).
  • 컨테이너 런타임(containerd 등): 실제 컨테이너 실행.

이 구조 위에서 네트워킹(CNI), 스토리지(CSI), DNS(CoreDNS) 가 플러그인 형태로 얹힙니다.


2. 핵심 오브젝트 (실무 요약)

Pod

Pod는 스케줄링·네트워크·스토리지를 공유하는 컨테이너 그룹입니다. 직접 Pod를 늘리기보다 Deployment(또는 StatefulSet 등) 로 관리하는 것이 일반적입니다.

Deployment

원하는 레플리카 수롤링 업데이트 전략을 선언합니다. 실제 Pod 생성·유지는 ReplicaSet 컨트롤러가 담당합니다.

Service

안정적인 가상 IP(ClusterIP)DNS 이름으로 Pod 집합에 트래픽을 보냅니다. 선택은 label selector로 이루어지며, 엔드포인트는 Endpoints(또는 EndpointSlice) 오브젝트에 반영됩니다.

Ingress

클러스터 외부 HTTP(S) 를 호스트·경로 기준으로 Service로 라우팅합니다. Ingress Controller(예: NGINX Ingress)가 별도로 필요합니다.

ConfigMap / Secret

설정과 민감 정보를 Pod에 주입합니다. Secret은 etcd에 암호화 저장(옵션)·RBAC·감사가 중요합니다.


3. Pod 스케줄링 알고리즘

스케줄링은 kube-scheduler(또는 커스텀 스케줄러)가 담당합니다. Kubernetes 스케줄링 프레임워크는 대략 다음 단계로 이해할 수 있습니다.

3.1 필터링(Filtering, Predicates)

스케줄링 가능한 노드 집합을 만듭니다. 한 노드라도 통과하지 못하면 Pod는 Pending 상태로 남고, 이벤트에 원인이 기록됩니다.

대표적인 필터 조건:

  • 리소스: 요청한 CPU·메모리(requests)가 노드에 가용한지, 상한(limits)과 함께 고려되는 정책
  • 호스트 포트 충돌: 동일 호스트 포트 사용 Pod와의 충돌
  • 노드 셀렉터 / 어피니티: nodeSelector, nodeAffinity, podAffinity/podAntiAffinity
  • 테인트·톨러레이션(Taint/Toleration): 특정 워크로드만 특정 노드에 올리기
  • 볼륨 바인딩: PVC가 특정 존/토폴로지에 묶인 경우 등

3.2 점수화(Scoring, Priorities)

필터를 통과한 노드들에 가중 점수를 매깁니다. 점수가 높은 노드가 선택됩니다. 예시:

  • 리소스 균형: 노드 간 CPU·메모리 사용을 고르게
  • 어피니티 가중: 선호 조건을 만족하는 노드에 가산점
  • 지역성: 동일 존(Zone) 선호 등 토폴로지 스프레드와의 트레이드오프

3.3 바인딩

최고 점수 노드가 정해지면 Bind API 호출로 Pod의 spec.nodeName이 확정됩니다. 이후 kubelet이 실제 컨테이너 기동을 담당합니다.

3.4 운영 관점에서 기억할 점

  • Pending이면 kubectl describe pod 로 “0/X nodes are available: …” 메시지를 확인합니다. 리소스 부족, 어피니티, 테인트, PVC 스케줄링 실패가 흔합니다.
  • requests를 비워두면 스케줄러가 자원 압박을 정확히 판단하기 어렵고, 노이즈 이웃(noisy neighbor) 이슈가 커집니다. 프로덕션에서는 일반적으로 requests/limits·프로브를 함께 정의합니다.
  • 스케줄링 프로파일(Scheduling Profiles)과 플러그인으로 필터·점수 로직을 버전별로 조정할 수 있습니다. 멀티 테넌시·GPU·로컬 SSD 같은 요구가 있으면 팀 표준으로 문서화하는 것이 좋습니다.

4. etcd 합의와 데이터 모델

4.1 Raft 합의

etcd는 Raft 알고리즘으로 리더 선출·로그 복제를 수행합니다. 일반적으로 홀수 개(3, 5, …) 의 멤버로 쿼럼을 구성해, 일부 노드 장애 시에도 일관된 순서로 커밋된 쓰기를 보장합니다. 쿼럼이 깨지면 읽기는 될 수 있어도 쓰기 불가 같은 상태가 될 수 있어, 컨트롤 플레인 고가용성 설계의 핵심입니다.

4.2 Kubernetes에서의 역할

  • API Server가 리소스의 진실 공급원(source of truth) 으로 etcd를 사용합니다.
  • watch 기반으로 컨트롤러·스케줄러 등이 변경을 구독합니다. “상태 변화 → 조정 루프” 패턴의 기반이 됩니다.

4.3 키 공간과 오브젝트

Kubernetes 오브젝트는 etcd에 키-값으로 저장되며, 경로는 버전에 따라 세부가 달라질 수 있으나 개념적으로는 API 그룹/리소스/네임스페이스/이름 계층으로 이해하면 됩니다. 리소스는 일반적으로 JSON 직렬화 형태로 저장됩니다.

4.4 운영·보안 포인트

  • etcd 백업·복구는 클러스터 재해 복구의 핵심입니다. 스냅샷 주기와 복구 드릴을 권장합니다.
  • etcd 암호화 at rest(Secret 등)와 네트워크 분리, 강한 인증서 관리는 규모가 커질수록 중요해집니다.
  • API Server 부하가 크면 이벤트·리스트 워치 트래픽, 대규모 리소스가 etcd와 API 지연에 영향을 줄 수 있어, 리소스 설계(오브젝트 수, 라벨 카디널리티)도 성능 요소입니다.

5. 컨트롤러 조정 루프(Reconciliation)

Kubernetes의 “자동 복구·원하는 수 유지”는 컨트롤러현재 상태를 읽고 의도한 상태로 맞추는 과정입니다.

5.1 일반적인 패턴

  1. Informer/SharedInformer가 API에서 리소스 변경을 캐시에 반영합니다.
  2. 변경이 있으면 워크 큐(workqueue) 에 키(예: 네임스페이스/이름)가 들어갑니다.
  3. 워커가 큐에서 꺼내 조정 함수(reconcile) 를 실행합니다.
  4. 부족한 리소스는 생성하고, 불필요한 것은 삭제하거나 스케일을 조정합니다.
  5. 에러 시 재시도(backoff) 합니다.

5.2 Deployment → ReplicaSet → Pod

Deployment 컨트롤러는 ReplicaSet 을 버전별로 관리하고, ReplicaSet 컨트롤러는 실제 Pod 수replicas와 같도록 Pod를 만듭니다. 롤링 업데이트는 새 ReplicaSet을 점진적으로 늘리고 이전 ReplicaSet을 줄이는 방식으로 진행됩니다.

5.3 왜 이해해야 하는가

  • “YAML을 적용했는데 반영이 느리다” → 컨트롤러 큐 적체, API 지연, 웹훅 timeout 등을 의심합니다.
  • “이중으로 생성된다” → 오너 참조, 채널링 필드, 잘못된 label selector 같은 메타데이터 불일치를 점검합니다.

6. Service 네트워킹과 kube-proxy 모드

Service는 가상 IP(ClusterIP) 로 안정적인 접속점을 제공하고, 엔드포인트는 Ready Pod IP:포트 목록으로 유지됩니다. 이 트래픽 전달 방식은 kube-proxy 구현에 따라 달라집니다.

6.1 공통 개념

  • 클러스터 내부에서는 보통 CoreDNSmy-svc.my-ns.svc.cluster.local 형태로 ClusterIP 를 해석합니다.
  • kube-proxy는 Service·EndpointSlice 변경을 watch 하며 노드의 패킷 처리 규칙을 갱신합니다.

6.2 iptables 모드

kube-proxy가 iptables(또는 nftables 백엔드가 있는 환경의 netfilter 규칙) 를 프로그래밍합니다. Service IP로 향하는 트래픽을 DNAT 하여 백엔드 Pod IP로 전달합니다. 구현이 단순하고 널리 쓰이지만, 매우 많은 Service·규칙에서는 규칙 체인 탐색 비용이 커질 수 있습니다.

6.3 IPVS 모드

IP Virtual Server(IPVS) 를 사용해 로드밸런싱을 수행합니다. 대규모 클러스터에서 확장성·균등 분산 알고리즘 선택 이점이 있을 수 있으나, 커널·클러스터 설정에 따라 도입 여부를 검증해야 합니다.

6.4 userspace 모드(역사적)

초기 방식으로, kube-proxy가 사용자 공간에서 프록시했습니다. 성능 한계로 현재는 권장되지 않습니다.

6.5 NodePort / LoadBalancer

  • NodePort: 모든 노드의 특정 포트로 노출. 방화벽·보안 그룹 설계가 필요합니다.
  • LoadBalancer: 클라우드에서 L4 로드밸런서를 프로비저닝하는 경우가 많습니다. 실제 트래픽 경로는 CSP·CNI에 따라 다르며, 헬스 체크·소스 IP 보존 이슈를 별도로 확인합니다.

6.6 트러블슈팅 힌트

  • Service에 연결되지 않으면 selector ↔ Pod labels, Endpoints가 비어 있지 않은지, readiness probe 실패 여부를 확인합니다.
  • 네트워크 정책(NetworkPolicy)을 도입하면 기본 거부 모델에서 DNS·헬스체크 경로가 막히는 경우가 흔합니다.

7. 프로덕션 Kubernetes 패턴

7.1 가용성과 업그레이드

  • 여러 레플리카, PodDisruptionBudget(PDB): 노드 드레인·클러스터 업그레이드 시 동시에 내려가도 되는 최소 가용 수를 보장합니다.
  • 롤링 업데이트 파라미터(maxUnavailable, maxSurge)는 배포 속도와 안정성의 트레이드오프입니다.

7.2 보안·멀티 테넌시

  • RBAC 최소 권한, 네임스페이스 분리, 어드미션 웹훅(OPA/Gatekeeper, Kyverno 등)으로 정책 강제
  • NetworkPolicy로 동·서향 트래픽 제한
  • Secret 관리: 외부 시크릿 스토어(Vault 등)·CSI 드라이버·로테이션 전략

7.3 리소스 거버넌스

  • ResourceQuota, LimitRange로 네임스페이스별 CPU·메모리·오브젝트 수 제한
  • HPA/VPA(수평·수직 오토스케일)와 클러스터 오토스케일러는 역할이 다릅니다. HPA는 워크로드, 클러스터 오토스케일러는 노드 수에 초점이 있는 경우가 많습니다.

7.4 관측 가능성

  • 메트릭(kube-state-metrics, cAdvisor, 애플리케이션 메트릭), 로그(집계 스택), 트레이싱
  • 컨트롤 플레인·etcd·API 지연, 스케줄링 Pending률, OOMKilled, 재시작 횟수는 SLO와 연결해 알람을 거는 것이 좋습니다.

7.5 GitOps·배포

선언적 매니페스트를 Git으로 관리하고 Argo CD, Flux 등으로 동기화하면 감사 가능성과 롤백이 쉬워집니다. 다만 웹훅·동기화 주기·drift 관리가 운영 과제입니다.


8. 빠른 참고: kubectl

kubectl get pods -A -o wide
kubectl describe pod POD -n NAMESPACE
kubectl get endpoints SERVICE -n NAMESPACE
kubectl get networkpolicy -A
kubectl explain pod.spec.affinity

내부 동작과 핵심 메커니즘

이 글의 주제는 「Kubernetes 완벽 가이드 | 아키텍처·스케줄링·Service·etcd·컨트롤러·프로덕션」입니다. 앞선 튜토리얼을 구현·런타임 관점에서 다시 압축합니다. 구성 요소 간 책임 분리와 관측 가능한 지점을 기준으로 “입력이 어디서 검증되고, 핵심 연산이 어디서 일어나며, 부작용(I/O·네트워크·디스크)·동시성이 어디서 터지는가”를 한 장면으로 그리면 장애 분석이 빨라집니다.

처리 파이프라인(개념도)

flowchart TD
  A[입력·요청·이벤트] --> B[파싱·검증·디코딩]
  B --> C[핵심 연산·상태 전이]
  C --> D[부작용: I/O·네트워크·동시성]
  D --> E[결과·관측·저장]

경계에서의 지연·실패(시퀀스 관점)

sequenceDiagram
  participant C as 클라이언트/호출자
  participant B as 경계(프로세스·런타임·게이트웨이)
  participant D as 의존성(외부 API·DB·큐)
  C->>B: 요청/이벤트
  B->>D: 조회·쓰기·RPC
  D-->>B: 지연·부분 실패·재시도 가능
  B-->>C: 응답 또는 오류(코드·상관 ID)

알고리즘·프로토콜·리소스 관점 체크포인트

  • 불변 조건(Invariant): 각 단계가 만족해야 하는 조건(버퍼 경계, 프로토콜 상태, 트랜잭션 격리, 파일 디스크립터 상한)을 문장으로 적어 두면 디버깅 비용이 줄어듭니다.
  • 결정성: 동일 입력에 동일 출력이 보장되는 순수 층과, 시간·네트워크·스레드 스케줄에 의해 달라질 수 있는 층을 분리해야 테스트와 장애 분석이 쉬워집니다.
  • 경계 비용: 직렬화/역직렬화, 문자 인코딩, syscall 횟수, 락 경합, GC·할당, 캐시 미스처럼 누적 비용을 의심 목록에 넣습니다.
  • 백프레셔: 생산자가 소비자보다 빠를 때(소켓 버퍼, 큐 깊이, 스트림) 어디서 어떤 신호로 속도를 줄일지 정의합니다.

프로덕션 운영 패턴

실서비스에서는 기능과 함께 관측·배포·보안·비용·규제가 동시에 요구됩니다.

영역운영 관점 질문
관측성요청 단위 상관 ID, 에러율/지연 분위수(p95/p99), 의존성 타임아웃·재시도가 대시보드에 보이는가
안전성입력 검증·권한·비밀·감사 로그가 코드 경로마다 일관적인가
신뢰성재시도는 멱등 연산에만 적용되는가, 서킷 브레이커·백오프·DLQ가 있는가
성능캐시 계층·배치 크기·커넥션 풀·인덱스·백프레셔가 데이터 규모에 맞는가
배포롤백 룬북, 카나리/블루그린, 마이그레이션 호환성·플래그가 문서화되어 있는가
용량피크 트래픽·디스크·파일 디스크립터·스레드 풀 상한을 주기적으로 검증하는가

스테이징은 데이터 양·네트워크 RTT·동시성을 가능한 한 프로덕션에 가깝게 맞추는 것이 재현율을 높입니다.


확장 예시: 엔드투엔드 미니 시나리오

「Kubernetes 완벽 가이드 | 아키텍처·스케줄링·Service·etcd·컨트롤러·프로덕션」을 실제 배포·운영 흐름으로 옮긴 체크리스트형 시나리오입니다. 도메인에 맞게 단계 이름만 바꿔 적용할 수 있습니다.

  1. 입력 계약 고정: 스키마·버전·최대 페이로드·타임아웃·에러 코드 표를 API 또는 이벤트 경계에 둔다.
  2. 핵심 경로 계측: 요청 ID, 단계별 지연, 외부 호출 결과 코드를 한 화면(로그+메트릭+트레이스)에서 추적한다.
  3. 실패 주입: 의존성 타임아웃·5xx·부분 데이터·락 대기를 스테이징에서 재현한다.
  4. 호환·롤백: 설정/마이그레이션/클라이언트 버전을 되돌릴 수 있는지(또는 피처 플래그) 확인한다.
  5. 부하 후 검증: 피크 대비 p95/p99, 에러율, 리소스 상한, 알림 임계값이 기대 범위인지 본다.

의사코드 스케치(프레임워크 무관)

handle(request):
  ctx = newCorrelationId()
  validated = validateSchema(request)        // 경계에서 거절
  authorize(validated, ctx)                  // 권한·테넌트
  result = domainCore(validated)             // 순수에 가까운 규칙
  persistOrEmit(result, idempotentKey)       // I/O: 멱등·재시도 정책
  recordMetrics(ctx, latency, outcome)
  return result

문제 해결(Troubleshooting)

증상가능 원인조치
간헐적 실패레이스, 타임아웃, 외부 의존성 불안정, DNS최소 재현 스크립트, 분산 트레이스·로그 상관관계, 재시도·서킷 설정 점검
성능 저하N+1, 동기 I/O, 락 경합, 과도한 직렬화, 캐시 미스프로파일러·APM으로 핫스팟 확인 후 한 가지씩 제거
메모리 증가캐시 무제한, 구독/리스너 누수, 대용량 버퍼, 커넥션 미반납상한·TTL·힙/FD 스냅샷 비교
빌드·배포만 실패환경 변수, 권한, 플랫폼 차이, lockfileCI 로그와 로컬 diff, 런타임·이미지 버전 핀
설정이 로컬과 다름프로필·시크릿·기본값, 지역 리전단일 소스(예: 스키마 검증된 설정)와 배포 매트릭스 표준화
데이터 불일치비멱등 재시도, 부분 쓰기, 캐시 무효화 누락멱등 키·아웃박스·트랜잭션 경계 재검토

권장 순서: (1) 최소 재현 (2) 최근 변경 범위 축소 (3) 환경·의존성 차이 (4) 관측으로 가설 검증 (5) 수정 후 회귀·부하 테스트.

정리

Kubernetes는 etcd에 기록된 의도스케줄러·kubelet·kube-proxy·컨트롤러가 각자의 루프로 실현하는 시스템입니다. 운영자는 Pending·NetworkPolicy·PDB·리소스 쿼터 같은 교차점에서 장애를 가장 자주 만납니다. 이 글의 내부 구조 이해는 그 원인을 체계적으로 좁히는 데 도움이 됩니다.


자주 묻는 질문 (FAQ)

Q. iptables와 IPVS 중 무엇을 선택해야 하나요?

A. 대부분의 클러스터는 iptables(또는 nftables 기반 백엔드) 로 충분합니다. Service와 규칙 수가 매우 많고 병목이 검증된 경우 IPVS를 후보로 두고, 커널·CNI·벤더 지원 범위를 함께 검토합니다.

Q. 스케줄러가 아닌 곳에서 Pod가 Pending일 수 있나요?

A. 네. 어드미션 웹훅 거부, 이미지 풀 실패, 볼륨 마운트 실패, 컨테이너 생성 오류 등은 스케줄링 이후 단계에서도 대기·실패 상태가 될 수 있습니다. Events와 컨테이너 상태를 함께 봅니다.

Q. etcd 백업은 왜 중요한가요?

A. 클러스터의 의도한 상태와 메타데이터가 etcd에 있습니다. 워커 노드·스토리지는 별도 복구 전략이 필요하더라도, etcd 스냅샷 없이 컨트롤 플레인만 재구축하면 운영 복구가 크게 어려워질 수 있습니다.

Q. GitOps 없이도 프로덕션 운영이 가능한가요?

A. 가능합니다. 다만 팀 규모·규제·변경 빈도가 커질수록 변경 이력·리뷰·롤백이 중요해지며, GitOps는 그것을 표준화하는 대표 패턴입니다.


같이 보면 좋은 글

  • Kubernetes 실전 가이드 (kubernetes-practical-guide)
  • Docker Compose 완벽 가이드
  • Kubernetes 보안 하드닝 가이드
  • GitHub Actions CI/CD 가이드

이 글에서 다루는 키워드

Kubernetes, kube-scheduler, kube-proxy, etcd, 컨트롤러, Service, Ingress, 프로덕션, DevOps