1장 쿠버네티스 소개
1. 설계 배경: “무엇이 문제였는가?”
- 기존 방식의 한계 : 과거의 모놀리스(Monolith) 애플리케이션은 모든 구성 요소가 단일 프로세스로 실행되어 수평적 확장이 거의 불가능했음 용량을 늘리려면 더 강력한 서버로 업그레이드하는 수직적 확장(Vertical Scaling)에 의존해야 했고 수동으로 수천 개의 컨테이너를 관리하는 것은 불가능에 가까웠음 또한 개발팀은 인프라의 세부 사항을 알아야 했고 특정 클라우드 업체의 API에 종속되는 락인(Lock-in) 현상이 발생함
쿠버네티스의 해결책
하위 하드웨어 인프라를 추상화하여 전체 클러스터를 하나의 거대한 균일한 배포 영역으로 보이게 만듬 개발자는 서버 대수나 특성을 몰라도 애플리케이션을 직접 배포할 수 있는 셀프 서비스 배포가 가능해지며 시스템이 스스로 상태를 감시하고 복구하는 자가 치유(Self-healing) 기능을 통해 운영 부담을 줄
2. 소주제의 키워드
- 1.1 Introducing Kubernetes
조타수(Helmsman)- 그리스어 어원처럼 시스템의 항로(상태)를 유지함 - 1.2 Understanding Kubernetes
[클러스터 OS]- 컨트롤 플레인과 워크로드 플레인의 상호작용 - 1.3 Introducing K8s into your organization
[도입 전략]- 관리형 서비스(KaaS) 선택 및 적정 규모(서비스 20개 이상) 판단
3. 핵심 객체 및 추상화
컨트롤 플레인
클러스터의 뇌 역할을 하며 상태를 제어함
- API 서버 : RESTful API를 노출하는 중앙 접점
- etcd : 클러스터의 모든 상태를 영구 저장하는 분산 데이터 저장소
- 스케줄러 : 애플리케이션 인스턴스를 실행할 최적의 노드를 결정
- 컨트롤러 : 객체를 감시하고 실제 상태를 원하는 상태로 바꿈
워크로드 플레인
실제 애플리케이션이 실행되는 표면
- 쿠블릿 : 노드 대리인으로서 API서버와 통신하고 컨테이너를 관리
- 쿠브 프록시 : 애플리케이션 간의 네트워크 부하 분산을 담당
추상화 목적
인프라의 복잡성을 숨겨 개발자가 비즈니스 로직 구현에만 집중하게 하며 로컬과 클라우드 어디서든 동일한 표준 API로 배포하게함
4. 핵심 동작 시퀀스
1. Input(Desired State)
사용자가 YAML/JSON 형식의 매니페스트를 API 서버에 제출
2. Process(Control Loop)
- 제출/저장 : API 서버가 매니페스트를 검증하고 etcd에 기록
- 실체화 : 관련 컨트롤러가 새 객체를 감지하고 하위 객체(인스턴스 등)를 생성
- 스케줄링 : 스케줄러가 각 인스턴스를 실행할 노드를 할당해 API 정보를 수정
- 실행 : 해당 노드의 쿠블릿이 할당을 감지하고 컨테이너 런타임에 실행을 지시
3. Output(Actual State)
노드에서 컨테이너가 실행되고 서비스 프록시가 네트워크를 구성
즉 사용자는 배의 선장이며 가고자 하는 목적지만 정하면 조타수(쿠버네티스)가 키를 잡고 파도나 바람(시스템 상태)에 맞춰 배를 조정해 목적지까지 항로를 유지
5. 운영 및 안전성 체크 포인트
- 성능 영향 요소 쿠버네티스 자체 운영을 위해 별도의 컴퓨팅 리소스가 추가로 소모됨 직접 설치 시 관리 복잡도가 매우 높음
- 장애 시 현상 노드가 실패하면 쿠버네티스가 이를 감지해 해당 애플리케이션을 자동으로 건강한 노드로 옮김 앱이 크래시되면 스스로 재시작해 가용성을 보장
✅ 체크 포인트
필수 키워드
- 인프라 추상화 : 서버 세부 사항을 숨기고 단일 자원으로 보이게함
- 선언적 모델(Declarative) : 어떻게가 아닌 무엇을 원하는지 기술
- 자가 치유 : 장애 시 자동 재시작 및 이동 배포
- Borg/Omega : 쿠버네티스의 뿌리가 된 구글의 내부 시스템
- etcd : 클러스터의 모든 데이터를 저장하는 유일한 장소
- API 서버 : 클러스터 제어의 중앙 Restful 인터페이스
- 쿠블릿 : 노드 현장에서 컨테이너를 관리하는 대리인
- KaaS(Managed K8s) : GKE, EKS 등 업체가 관리해주는 서비스
- 서비스 20개 규칙 : MSA의 서비스가 20개 이상일때 도입 실익이 큼
혼동 금지
- 수평적 확장 : 서버의 대수를 늘리는 것을 수평(Horizontal)
- 수직적 확장 : 서버의 성능을 높이는 것을 수직(Vertical)
쿠버네티스 한줄 정의
인프라를 추상화하고 선언적 모델을 통해 컨테이너화된 애플리케이션의 배포, 관리, 자가 치유를 자동화한ㄴ 클러스터 OS임
정리
쿠버네티스라는 기계의 작동법보다는 존재 이유를 가르쳐줌 특히 아키텍처 파트에서 컨트롤 플레인이 머리라면 워커 노드는 손발이라는 비유를 기억하자
2장 컨테이너의 이해
1. 설계 배경 “무엇이 문제였는가?”
- 기존 방식의 한계 : 과거에는 대부분의 애플리케이션이 거대한 모놀리스 형태였다 모든 구성 요소가 단일 프로세스에서 실행되어 수평적 확장이 어려웠고 용량을 늘리려면 더 비싼 하드웨어로 교체하는 수직적 확장에 의존해야했음 또한 수천 개의 프로세스를 여러 대의 컴퓨터에 수동으로 배포하고 관리하는 것은 불가능에 가까움
쿠버네티스의 해결책
애플리케이션을 컨테이너라는 표준화된 단위로 패키징해 배포를 자동화함 이를 통해 하부 인프라(하드웨어, 네트워크)를 추상화해 감추고 개발자가 비즈니스 로직에만 집중할 수 있는 환경을 제공
2. 소주제의 키워드
- 2.1 컨테이너 정의
격리- VM과 컨테이너의 차이 및 리눅스 컨테이너의 기본 개념 - 2.2 CRI와 런타임
CRI- 도커 외에 CRI-O, rkt 등 다양한 런타임을 지원하는 인터페이스 - 2.3 데모 애플리케이션
Kiada- MSA 구조의 실습용 앱 소개 - 2.4 네임스페이스와 포드
공유- 컨테이너가 리눅스 네임스페이스를 어떻게 공유하는지 맛보기
3. 핵심 객체 및 추상화
- 컨테이너
- 역할 : 격리된 컴퓨터처럼 작동하는 프로세스 단위
- 주요 속성 : 자체 파일 시스템, 격리된 실행 환경
- CRI(Container Runtime Interface)
- 역할 : 쿠버네티스가 특정 컨테이너 기술에 종속되지 않게 만드는 추상화 계층
- 관려 기술 : CRI-O, Docker, rkt, runC
- 추상화 목적 : 개발자가 OS 커널의 복잡한 기능(Namespace, Cgroups 등)을 몰라도 애플리케이션이 어디서든 동일하게 동작하도록 보장하는 것
- 상호 작용 : Kubelet이 CRI를 통해 컨테이너 런타임에게 컨테이너 실행을 지시
4. 핵심 동작 시퀀스
1. Input(이미지)
애플리케이션 코드와 종속성이 포함된 컨테이너 이미지
2. Process(실행 지시)
Kubelet이 CRI를 통해 이미지로부터 컨테이너를 생성
3. Output(격리된 프로세스)
호스트 OS 커널을 공유하지만 독립된 컴퓨터처럼 실행되는 프로세스
비유
컨테이너는 표준 규격의 화물 컨테이너 박스임 배(쿠버네티스)는 박스 안에 무엇이 들었는지(코드 or 종류) 상관없이 크레인(CRI)을 이용해 박스를 옮기고 쌓는 일에만 집중 가능
5. 운영 및 안전성 체크 포인트
- 성능 영향 요소 컨테이너는 VM과 달리 별도의 OS를 실행하지 않으므로 자원 오버헤드가 거의 없음
- 안정성(격리) 각 컨테이너는 격리된 VM처럼 행동하므로 한 컨테이너의 문제가 다른 곳으로 퍼지는 것을 방지함
- 제약 사항 컨테이너는 호스트 OS의 커널을 고유함 따라서 노드마다 커널 버전이 다르면 드문 경우지만 동작에 차이가 생길 수 있음
✅ 체크 포인트
필수 키워드
- CRI(Container Runtime Interface) : 다양한 컨테이너 런타임을 지원하기 위한 인터페이스
- CRI-O : 도커의 가벼운 대안으로 사용되는 OCI 준수 런타임
- OCI-compliant : 표준화된 컨테이너 규격을 준수하는 런타임들
- Kiada : 이 책에서 사용하는 MSA 데모 애플리케이션
- Namespace : 프로세스를 격리된 가상 컴퓨터처럼 보이게 하는 리눅스 기능
- Host OS Kernel : 모든 컨테이너가 공유하는 자원
- JSON(JavaScript Object Notaion) : 앱 간 데이터 교환에 적합한 직렬화 방식
- Flat Address Space : 클러스터 내 모든 포드가 NAT 없이 통신하는 네트워크 환경
- Standard Output(stdout) : 컨테이너가 로그를 기록해야 하는 권장 스트림
- Immutability(불변성) : 실행 중인 컨테이너는 변경되지 않아야 한다는 속성
혼동 금지
- Pod : 하나 이상의 관련 컨테이너를 담는 최소 배포 단위
- Container : 실제 실행 프로세스
컨테이너 한줄 정의
컨테이너는 애플리케이션을 종속성과 함께 패키징하여 격리된 환경에서 실행하는 기술 쿠버네티스는 이런 컨테이너를 관리하기 위해 CRI를 사용
3장 첫 번째 애플리케이션 배포
1. 설계 배경: “무엇이 문제였는가?”
- 기존 방식의 한계 : 실제 다중 노드 쿠버네티스 클러스터를 설정하는 것은 리눅스 및 네트워크 행정 지식이 없는 사용자에게 매우 어렵고 복잡한 작업임 개별 컨테이너를 수동으로 관리할 경우 하드웨어가 실패하거나 인프라 토폴로지가 변할때마다 운영자가 일일이 대응해야 하는 고통이 따름
- 쿠버네티스의 해결책 : 하부 인프라를 추상화해 전체 클러스터를 하나의 균일한 배포 영역으로 보이게 만듬 개발자는 개별 서버를 관리하는 대신 API를 통해 원하는 상태만 정의하면 쿠버네티스가 물리적 복잡성을 숨기고 애플리케이션을 안정적으로 실행해줌
2. 소주제의 키워드
- 3.1 클러스터 배포
환경 구축- Minikube(로컬 VM), kind(컨테이너 기반), GKE(관리형 클라우드) 등 클러스터 확보 방법 - 3.2 쿠버네티스와 상호작용
통신 도구- kubectl 설치, kubeconfig 설정, API 서버와의 RESTful 통신 원리 - 3.3 첫 애플리케이셔 실행
핵심 배포- Deployment 생성, Pod의 개념, Service를 통한 외부 노출 및 수평 확장
3. 핵심 객체 및 추상화
- Deployment
- 역할 : 애플리케이션 배포 및 상태 관리
- 주요 속성 : 이미지명, 복제본 수
- 저장 위치 : etcd
- Pod
- 역할 : 쿠버네티스의 최소 배포 단위
- 주요 속성 : 하나 이상의 컨테이너 그룹, IP 주소 공유
- Service
- 역할 : 동적인 Pod들에게 고정된 진입점 제공
- 주요 속성 : Cluster IP, LoadBalancer 타입
- 추상화 목적 : 노드, 복잡한 네트워크 토폴로지, 물리적 로드 밸런서 등을 감추고 개발자가 애플리케이션 본연의 논리에만 집중할 수 있는 논리적 뷰(Logical View)를 제공
- 상호작용 :
kubectl이 API 서버에 요청을 보내면 스케줄러가 노드를 할당하고 해당 노드의 Kubelet이 컨테이너를 실행
4. 핵심 동작 시퀀스
사용자가 정의한 기대 상태(Desired State)를 시스템이 구현하는 과정
1. Input(Desired State)
kubectl create deployment 명령을 통해 YAML/JSON 매니페스트를 API 서버에 제출
2. Process(Control Loop)
- 저장 : API 서버가 객체를 etcd에 기록
- 스케줄링 : 스케줄러가 Pod를 실행할 최적의 워커 노드 결정
- 실행 : 노드의 Kubelet이 할당을 감지하고 Docker 등 런타임에 컨테이너 시작 지시
3. Output(Actual State)
노드에서 컨테이너가 실행되고 서비스 객체를 통해 외부 트래픽이 Pod로 전달됨
비유
쿠버네티스 배포는 피자 주문과 같음 사용자(캡틴)이 피자(여기선 Replicas에 해당)을 주문(Deployment)하면 주방(컨트롤 플레인)에서 요리사(스케줄러/Kubelet)를 배치해 피자를 구워내고 배달 주소(Service)를 통해 고객에게 전달하는 것과 같음 즉 피자가 어떤 오븐에서 구워지는지 신경쓸 필요 없음
5. 운영 및 안전성 체크 포인트
- 성능 영향 요소 : 수평적 확장(Scaling out)을 통해 복제본을 늘리면 부하를 분산하고 가용성 높일 수 있음
- 장애 시 현상 : Pod가 할당된 노드에서 실패하더라도 해당 Pod 인스턴스는 다른 노드로 이동하지 않음 대신 새로운 Pod 인스턴스가 생성되어 실패한 Pod를 대체
✅ 체크포인트
필수 키워드
- Pod : 쿠버네티스 배포의 기본단위, 컨테이너들의 묶음
- Deployment : 앱의 기대 상태를 정의하고 Pod를 관리하는 객체
- Service : Pod들에 접근하기 위한 안정적인 IP와 포트 제공
- kubectl : API 서버와 대화힉 위한 명령줄 도구
- Scheduling : Pod를 특정 노드에 할당하는 프로세스
- Replicas : 유지해야 할 Pod 본제본의 개수
- LoadBalancer : 외부 IP를 통해 서비스에 접근하게 해주는 서비스 타입
- ClusterIP : 클러스터 내부에서만 접근 가능한 기본 서비스 주소
- NodePort : 워크 노드의 특정 포트를 열어 접근하는 방식
혼동 금지
Container vs Pod
쿠버네티스는 컨테이너를 직접 배포하지 않고 항상 Pod 단위로 관리함
Pod IP vs Service IP
Pod IP는 일시적이고 변경되지만 Service IP는 서비스 수명 동안 변하지 않는 안정적인 주소
3장 정리
kubectl을 사용해 Deployment로 Pod의 복제본을 만들고 Service로 외부 접근을 허용하며 앱을 확장하는 핵심 배포과정을 다룸
4장 쿠버네티스 API 오브젝트 소개
1. 설계 배경
- 기존 방식의 한계 : 클러스터 내의 수많은 애플리케이션, 부하 분산 장치, 서버, 저장소 등을 수동으로 일일이 구성하고 관리하는 것은 불가능에 가깝다 기존 시스템에서는 인프라의 상태를 한눈에 파악하거나 일관되게 유지하기 위한 중앙 집중화된 인터페이스가 부족했음
- 쿠버네티스의 해결책 : 쿠버네티스 API를 통해 모든 인프라 요소를 Object라는 추상화된 단위로 관리함 사용자는 개별 서버를 조작하는 대신 API 오브젝트를 조작함으로써 클러스터 전체의 설정을 제어할 수 있음
2. 소주제별 키워드
- 4.1 쿠버네티스 API와 친숙해지기
상호작용- RESTful 스타일의 중앙 접점 API와 오브젝트 개념 - 4.2 오브젝트의 개별 속성 살펴보기
매니페스트- Node 오브젝트를 통한 Spec과 Status 구조의 이해 - 4.3 이벤트를 통한 클러스터 관찰
디버깅- 컨트롤러의 작업 기록인 Event 오브젝트 활용
3. 핵심 객체 및 추상화
- API Object
- 역할 : 클러스터의 구성 요소를 대표하는 데이터 단위
- 주요 속성 : Metadata, Spec, Status
- 저장위치 : etcd
- Controller
- 역할 : 오브젝트를 감시하고 실제 상태를 기대 상태로 일치시키는 루프 실행
- 추상화 목적 : 인프라의 복잡합 세부 사항(물리적 서버, 네트워크 설정 등)을 감추고 개발자가 선언적인 매니페스트를 통해 시스템이 어떻게 동작해야 하는지만 정의하도록 도움
- 상호 작용 : 사용자가 Spec에 기대 상태를 적으면 컨트롤러가 이를 읽어 클러스터를 변경하고 Status에 현재 상태를 보고함
4. 핵심 동작 시퀀스
상태 일치(Reconcillation)과정
1. Input(Desired State)
사용자가 YAML/JSON 매니페스트의 Spec 섹션에 원하는 상태를 기술해 API 서버에 제출
2. Process(Control Loop)
- 감시 : 컨트롤러가 자신이 담당하는 오브젝트의 Spec 변화를 상시 감시함
- 조치 : 실제 클러스터 상태와 Spec이 다를 경우 이를 일치시키기 위한 작업을 수행
- 보고 : 작업 결과나 현재 실제 상태를 오브젝트의 Status 섹션에 기록
3. Output(Actual State)
클러스터 리소스가 Spec에 정의된 대로 구성되고 사용자는 Status를 통해 결과를 확인
비유
쿠버네티스 API는 자동 온도 조절기와 같음 사용자가 원하는 온도(여기선 Spec)를 설정하면 조절기(Controller)가 현재 온도(Status)를 확인해 히터를 켜거나 끄는 작업을 자동으로 수행하는 것과 같음
5. 운영 및 안정성 체크 포인트
- 성능 영향 요소
- Event 오브젝트는 클러스터 내에서 매우 많이 생성되어 etcd 저장소에 부담을 줄 수 있음
- 장애 시 현상 : Node 오브젝트의 Status Conditions(MemoryPressure, DiskPressure, PIDPressure) 중 하나라도 True가 되면 해당 노드에 문제가 생겼음을 의미하며 스케줄링 등에 영향을 줌
- 데이터 보존 : Event 오브젝트는 etcd의 부하를 줄이기 위해 생성 후 1시간 뒤에 자도으로 삭제됨
✅ 체크리스트
필수 키워드
- RESTful API : HTTP 메서드(GET, POST 등)를 사용하는 쿠버네티스 통신 방식
- Object : API를 통해 관리되는 클러스터 상태의 실체
- Resource : API에서 특정 오브젝트 유형을 노출하는 URI 경로/뷰
- 매니페스트(Manifest) : 오브젝트를 설명하는 YAML 또는 JSON 파일
- Spec : 사용자가 정의한 원하는 상태
- Status : 시스템이 보고하는 현재 실제 상태
- Metadata : 이름, 생성 시간 등 오브젝트를 식별하는 정보
- Node 오브젝트 : 클러스터의 개별 서버를 대표하는 객체
- Event 오브젝트 : 컨트롤러가 수행한 작업이나 경고를 기록하는 객체
- kubectl explain : API 오브젝트 필드에 대한 문서를 CLI에서 즉시 확인하는 명령
혼동 금지
Resource vs Object
Resource는 HTTP API상의 URI(테이블/뷰) Object는 그 Resource를 통해 생성된 실제 데이터 인스턴스(행)임
Spec vs Status
Spec은 내가 원하는 것(미래) Status는 현재 벌어지고 있는 일(현재)
쿠버네티스 API 정리
쿠버네티스 API 오브젝트는 클러스터의 상태를 기술하는 선언적 데이터 단위이며 컨트롤러를 통해 기대 상태(Spec)와 실제 상태(Status)를 끊임없이 일치시킴
5장 Pod에서 워크로드 실행
1. 설계 배경
- 기존 방식의 한계 : 컨테이너 기술은 단일 프로세스 관리에 최적화되어 설계되었음 하나의 컨테이너 안에 여러 프로세스를 실행하면 개별 프로세스의 로그 관리, 재시작, 리소스 제어가 극도로 어려워지는 고통이 발생함 또한 서로 밀접하게 연관된 프로세스들이 물리적으로 같은 호스트에 있어야만 하는 통신 문제(공유 파일시스템, IPC 등)를 해결할 표준화된 단위가 부족함
- 쿠버네티스의 해결책 : Pod라는 개념을 도입해 하나 이상의 컨테이너를 단일 단위로 묶어 관리 이를 통해 컨테이너의 격리 원칙을 지키면서도 밀접하게 연관된 프로세스들이 항상 동일한 노드에서 실행되고 자원(네트워크, 저장소)을 공유할 수 있는 환경을 제공
2 소주제별 키워드
- 5.1 Pod의 이해
최소 단위- Pod와 컨테이너의 관계, 사이드카 패턴 - 5.2 YAML/JSON 파일로 Pod 생성
매니페스트- 선언적 정의와 객체 생성 흐름 - 5.3 애플리케이션 및 Pod와 상호작용
상태 관리- 로그 확인, 명령어 실행, 파일 복사 - 5.4 Pod에서 다중 컨테이너 실행
협업- 메인 컨테이너와 보조 컨테이너(사이드카) - 5.5 Pod 시작 시 추가 컨테이너 실행
초기화- 초기화 컨테이너(init Container) - 5.6 Pod 및 기타 객체 삭제
정리- 객체 수명 주기 종료
3. 핵심 객체 및 추상화
- Pod
- 역할 : 쿠버네티스의 기본 배포 및 확장 단위
- 주요 속성 : 동일 노드 실행 보장, IP 공유
- 저장 위치 : etcd
- 초기화 컨테이너(init Container)
- 역할 : 메인 컨테이너 실행 전 필요한 설정/준비 작업 수행
- 특징 : 순차적 실행, 성공 후 종료 필수
- Sidecar Container
- 역할 : 메인 컨테이너의 코드를 수정하지 않고 기능을 보완
- ex. 로그 수집기, 리버스 프록시
- 역할 : 메인 컨테이너의 코드를 수정하지 않고 기능을 보완
추상화 목적
개발자에게 개별 물리 서버가 아닌 하나의 논리적 컴퓨터라는 단위를 제공해 네트워크와 저장소 공유를 단순화함
상호작용
사용자가 YMAL 파일에 spec.containers를 정의하면 Kubelet이 이를 감시해 컨테이너 런타임에게 실행을 지시함
4. 핵심 동작 시퀀스
1. Input(Desired State)
사용자가 Pod 이름, 이미지, 포트 등을 기술한 YAML 매니페스트를 API 서버에 제출
2. Process(Control Loop)
- 스케줄링 : 스케줄러가 Pod를 실행할 최적의 워커 노드 결정
- 이미지 풀링 : 해당 노드의 Kubelet이 레지스티리에서 이미지 다운로드
- 초기화 :정의된 순서대로 초기화 컨테이너들을 하나씩 실행
- 메인 실행 : 모든 초기화 완료 후 메인 컨테이너들을 병렬로 시작
3. Output(Actual State)
Pod 상태가 Running으로 변경되고 애플리케이션이 요청을 처리할 준비를 마침
5. 운영 및 안정성 체크포인트
- 성능 영향 요소 : Sidecar Container를 추가하면 추가 프로세스 실행으로 인해 리소스(CPU, 메모리) 요구량이 증가함
- 장애 시 현상 : Pod 내의 특정 컨테이너가 종료되면 Kubelet이 이를 감지해 설정된 restartPolicy에 따라 자동으로 재시작함
- 단 Pod 자체는 특정 노드에 할당되면 실패하더라도 다른 노드로 이동하지 않고 새 인스턴스로 교체됨
✅ 체크포인트
필수키워드
- Pod : 쿠버네티스의 기본 배포 단위
- Sidecar : 주 컨테이너를 돕는 보조 컨테이너
- 초기화 컨테이너(init Container) : 메인 이전에 순차 실행되는 컨테이너
- kubectl apply : 매니페스트를 클러스터에 적용하는 선언적 명령
- kubectl logs : 컨테이너의 표준 출력/에러 로그 확인 도구
- restartPolicy : 컨테이너 실패 시 재시작 여부 결정(OnFailure, Never 등)
- status.phase : Pod의 현재 생애 주기 단계(Pending, Running 등)
- YAML : Pod 정의에 사용되는 인간 친화적 데이터 형식
- Pod IP : 클러스터 내의 모든 포드끼리 통신 가능한 고유 주소
- 공유 볼륨 : Pod 내 컨테이너끼리 데이터를 주고받는 통로
혼동 금지
Pod vs Container
Pod는 배포 단위 Container는 실행 프로세스임 쿠버네티스는 컨테이너를 직접 배포하지 않음
재시작 vs 재생성
컨테이너 실패 시 재시작됨 Pod 삭제 후 다시 만드는 것은 재생성임 즉 Pod는 한 번 죽으면 같은 인스턴스로 살아나지 않음
한줄 정리
Pod는 하나 이상의 컨테이너를 그룹화해 네트워크와 저장소를 공유하게 하는 쿠버네티스의 최소 배포 단위임
6장 Pod 생명 주기 관리
1. 설계 배경
- 기존 방식의 한계 : 단순히 프로세스가 실행 중이라고 해서 애플리케이션이 건강하다고 단정할 수 없다 ex. java 앱에서 메모리 누수가 발생해 응답은 못 하면서 프로세스만 살아있는 경우(Dead Lock 등) 외부 시스템은 이를 감지하고 복구하기 어려움 또한 컨테이너가 시작될 때 특정 데이터를 내려받거나 종료될 때 안전하게 작업을 저장(Graceful Shutdown)하는 과정을 수동으로 제어하는 것은 대규모 환경에서 불가능에 가깝다
- 쿠버네티스의 해결책 : Pod의 상태를 세분화해 관찰하고 Probe를 통해 앱의 내부 건강 상태를 주기적으로 확인하며 Lifecycle Hooks를 통해 시작과 종료 시점에 필요한 동작을 자동화 한다.
2. 소주제별 키워드
- 6.1 Pod의 상태 확인
Phase & Condition- Pod가 현재 어떤 단계에 있고 어떤 조건을 충족했는가 - 6.2 컨테이너의 건강 상태 유지
Probes- Liveness와 Startup 프로브를 통한 자가 치유 - 6.3 컨테이너 시작 및 종료 시 작업 실행
Hooks- Post-start와 Pre-stop 훅의 역할 - 6.4 Pod 수명 주기 이해
Sequence- 초기화부터 종료까지의 전체 시퀀스 및 삭제 유예 기간
3. 핵심 객체 및 추상화
- Liveness Probe
- 역할 : 컨테이너의 생존 여부 확인
- 주요 속성 : HTTP GET, Exec, TCP Socket
- 동작 : 실패 시 컨테이너 재시작
- Startup Probe
- 역할 : 느린 앱의 초기 구동 보호
- 주요 속성 : 완료 전까지 라이브니스 프로브 비활성화
- 동작 : 초기 구동 성공 . 시라이브니스에 제어권 위임
- Lifecycle Hooks
- 역할 : 컨테이너 특정 시점 동작 정의
- 종료 : Post-start(시작 직후), Pre-stop(종료 직전)
추상화 목적
앱 개발자가 복잡한 재시작 로직이나 종료 처리 코드를 모든 앱에 직접 구현하지 않아도 쿠버네티스가 표준화된 인터페이스를 통해 인프라 수준에서 이를 대신 관리하게함
상호작용
Kubelet이 컨테이너의 Probe/Hook을 실행하고 그 결과에 따라 Container Runtime에 재시작 혹은 종료 명령을 내림
4. 핵심 동작 시퀀스
쿠버네티스는 Pod의 실제 상태를 사용자가 정의한 기대 상태로 유지하기 위해 밑과 같은 루프를 실행함
1. Input(Desired State)
restartPolicy, livenessProbe, terminationGracePeriodSeconds 등이 정의된 Pod 매니페스트
2. Process(Control Loop)
- 관찰 : Kubelet이 컨테이너 상태와 프로브 결과를 주기적으로 확인
- 비교 : 현재 상태가 실패(Unhealthy)인지 판단
- 조치 : 실패 시 컨테이너를 파괴하고 새로 생성(재시작이 아님)해 상태를 복구
3. Output(Actual State)
Pod의 status.phase가 다시 Running으로 유지되고 서비스 가용성 확보
비유
Liveness Probe는 잠든 학생을 깨우는 알람시계와 같다 학생(애플리케이션)이 스스로 일어나지 못하면(DeadLock 등), 알람(쿠버네티스)이 울려 억지로 깨워(재시작) 다시 공부(서비스)를 하게 만드는 것임
5. 운영 및 안정성 체크포인트
- 성능 영향 요소 : 너무 잦은 프로브 설정은 노드 리소스를 소모함 특히 자바 앱에서 exec 프로브를 사용하면 매번 JVM을 실햄해야 하므로 큰 오버헤드 발생 가능
- 장애 시 현상(지수 백오프): 컨테이너가 반복해서 실패하면 재시작 대기 시간이 10초, 20초… 최대 5분까지 늘어남(CrashLoopBackOff)
- 안정성 종료 : Pod 삭제 시 기본 30초의 유예 기간(terminationGracePeriodSeconds)을 주어 앱이 안전하게 종료될 시간을 확보함
✅ 체크포인트
필수 키워드
- Pending : Pod 생성 후 노드 할당 및 이미지 준비 단계
- Running : 적어도 하나의 컨테이너가 실행 중인 단계
- Succeeded/Failed : 일회성 Pod의 최종 성공/실패 상태
- Ready Condition : Pod가 요청을 처리할 준비가 되었는지 여부
- RestartPolicy : 실패 시 재시작 규칙(Always, OnFailure, Never)
- CrashLoopBackOff : 컨테이너 재시작 실패가 반복되어 대기 중인 상태
- HTTP GET Probe : 특정 URL 응답 코드로 건강 상태 판단
- Post-start Hook : 컨테이너 메인 프로세스와 비동기적으로 실행되는 시작 작업
- Pre-stop Hook : 종료 신호(SIGTERM) 전달 전 실행되는 작업
- SIGTERM : 쿠버네티스가 컨테이너 종료 시 가장 먼저 보내는 표준 종료 신호
혼동 금지
Restart vs Recreate(재구성)
쿠버네티스는 기존 컨테니어를 재시작하는 것이 아니라 완전히 삭제하고 새 컨테이너를 다시 만듬
Liveness vs Startup
라이브니스는 실행 중 건강 체크 스타트업은 초기 구동 시 라이브니스로부터의 보호가 목적
정리
6장은 Pod의 탄생부터 죽음까지의 전 과정을 자동화하고 앱의 내부 결함을 감지해 스스로 복구하는 자가 치유 인프라의 매커니즘을 다룸
7장 Pod에 저장 볼륨 부착
1. 설계 배경
- 기존 방식의 한계 : 컨테이너의 파일시스템은 격리되어 있으며 일시적(Ephemeral)임 만약 컨테이너 내부 프로세스가 파일에 데이터를 썼더라도 컨테이너가 충돌해 재시작(사실상 재생성)되면 이 데이터는 모두 소실되는 고통이 발생함 또한 한 Pod 내의 여러 컨테이너가 동일한 데이터를 읽거나 써야 하는 공유 환경을 제공할 표준적인 방법이 없었음
- 쿠버네티스의 해결책 : Volume이라는 개념을 Pod에 도입함 볼륨은 Pod의 구성 요소로 정의되어 컨테이너와 별개의 수명 주기를 가지며 컨테이너가 재시작되어도 데이터는 유지됨 이를 통해 컨테이너 간 데이터 공유와 영구적 데이터 보관이 가능해짐
2. 소주제별 키워드
- 7.1 볼륨 소개
마운트- 컨테이너 파일시스템 트리와 볼륨 연결 - 7.2 emptyDir 볼륨
일시적 공유- Pod와 수명을 같이하며 컨테이너간 데이터를 주고받는 통로 - 7.3 외부 저장소 볼륨
영속성- 네트워크 부착 저장소(GCE PD 등)를 통한 노드 장애 대비 데이터 보존 - 7.4 호스트 파일시스템 접근
hostPath- 워커 노드의 파일에 직접 접근하는 특수 목적용 볼륨
3. 핵심 객체 및 추상화
- Volume
- 역할 : Pod 내 컨테이너들이 접근 가능한 공용 디렉터리
- 주요 속성 : 이름, 볼륨 타입
- 저장 위치 : 타입에 따라 다름 - 메모리, 로컬 디스크, 네트워크 디스크 등
추상화 목적
애플리케이션 프로세스에게는 단지 파일시스템 내의 특정 경로로 보이게 함으로써 하부 저장소의 물리적 복잡성(네트워크 프로토콜, 장치 설정 등)을 감추고 비즈니스 로직이 파일 API를 그대로 쓸 수 있게함
상호작용
Kubelet이 볼륨을 준비하고 Container Runtime이 각 컨테이너의 volumeMounts 설정에 따라 지정된 mountPath에 볼륨을 연결함
4. 핵심동작 시퀀스
1. Input(Desired State)
Pod 매니페스트의 spec.volumes에 정의된 마운트 경로
2. Process(Control Loop)
- 볼륨 생성 : Pod가 노드에서 시작될 때 Kubelet이 지정된 타입의 볼륨을 준비함
- 마운트 : 컨테이너가 실행되기 직전 준비된 볼륨을 컨테이너 내부 파일 트리 시스템에 연결함
- 유지 : 컨테이너가 실패해 재시작되어도 볼륨은 해제되지 않고 동일한 겨로에 다시 마운트됩니다
3. Output(Actual State)
애플리케이션 프로세스가 컨테이너 재시작과 상관없이 볼륨 내 파일에 계속 접근할 수 있음
비유
볼륨은 Pod라는 미니 컴퓨터에 꽂혀 있는 공유 USB와 같음 컴퓨터 안의 프로그램(컨테이너)이 재시작되어도 USB(볼륨)는 뽑히지 않고 그대로 꽂혀 있어 데이터가 유지되는 원리
5. 운영 및 안정성 체크포인트
- 성능 영향 요소 : emptyDir.medium을 Memory로 설정하면 RAM을 사용하는 tmpfs를 생성해 매우 빠른 I/O가 가능하지만 노드의 메모리 리소스를 소모함
- 장애 시 현상 : emptyDir은 Pod가 삭제되면 함께 삭제되어 데이터가 소실됨 hostPath는 Pod가 다른 노드로 스케줄링되면 기존 노드에 있던 데이터에 접근할 수 없게 됨
- 네트워크 제약 : GCE PD와 같은 일부 네트워크 볼륨은 한 번에 하나의 노드에만 읽기/쓰기 모드로 부착될 수 있어 여러 노드에 걸친 Pod 복제본 간 공유가 제한될 수 있음
✅ 체크포인트
필수 키워드
- Mounting : 저장 장치의 파일시스템을 운영체제 파일 트리에 부착하는 행위
- emptyDir : Pod 시작 시 생성되고 종료 시 삭제되는 일시적 볼륨
- hostPath : 워커 노드의 파일시스템 경로를 Pod에 직접 노출하는 볼륨
- volumeMounts : 볼륨을 컨테이너 내 어디에 배치할지 결정하는 필드
- mountPath : 볼륨이 나타날 컨테이너 내의 디렉터리 경로
- tmpfs
- medium : Memory 설정 시 사용되는 메모리 기반 파일시스템
- subPath : 볼륨 전체가 아닌 특정 하위 디렉터리만 마운트할 때 사용
- readOnly : 컨테이너가 볼륨에 쓰는 것을 방지하는 설정
- Network Storage : 노드 장애 시에도 데이터를 유지하기 위한 외부 저장소
- Sidecar Pattern : 공유 볼륨을 통해 메인 컨테이너와 데이터를 주고받는 보조 컨테이너 구조
혼동 금지
컨테이너 FS vs emptyDir
컨테이너 FS는 컨테이너 재시작 시 초기화되지만 emptyDir은 Pod가 살아있는 한 유지됨
hostPath vs 네트워크 볼륨
hostPath는 노드에 종속적이라 Pod 이동 시 데이터 접근이 불가하지만 네트워크 볼륨은 노드 간 이동 시에도 부착 가능
정리
7장은 컨테이너의 일시적 파일 시스템 한계를 극복하고 데이터 공유와 영구 보관을 실현하기 위한 Pod 볼륨의 종류와 마운트 매커니즘을 다룸
8장 PersistentVolume으로 데이터 저장
1. 설계 배경
- 기존 방식의 한계 : 이전 장에서 본듯 Pod 매니페스트에 직접 특정 저장소 기술(NFS 서버 IP, GCE Persistent Disk 명칭 등)을 명시하는 방식은 인프라 종속적인 방식이다 이로 인해 동일한 매니페스트를 다른 클러스터에서 사용할 때 매번 수정해야 하는 Portability 상실의 고통이 발생한다 또한 개발자가 하위 저장소의 세부 사항(IP 주소, 특정 클라우드 API 등)까지 알아야 하는 부담이 있음
- 쿠버네티스의 해결책 : 저장소 인프라를 PersistentVolume(PV)이라는 오브젝트로 추상화하고 개발자는 PersistentVolumeClaim(PVC)을 통해 필요한 만큼의 용량과 속성만 요청하게해 Pod와 저장소 기술을 완전히 분리한다
2. 소주제별 키워드
- 8.1 Pod와 스토리지 기술의 분리
추상화- PV와 PVC를 통한 인프라 독립성 확보 - 8.2 PV 및 PVC 생성
바인딩- 정적 프로비저닝과 접근 모드(RWO, ROX, RWX) - 8.3 동적 프로비저닝
StorageClass- 필요 시점에 저장소를 자동 생성하는 매커니즘 - 8.4 노드-로컬 PersistentVolume
로컬 스토리지- 특정 노드에 부착된 고속 저장소 관리
3. 핵심 객체 및 추상화
- PersistentVolume(PV)
- 역할 : 클러스터 관리자가 설정한 실제 저장소 자원
- 주요 속성 : 용량, 접근 모드, 회수 정책
- 저장 위치 : etcd
- PersistentVolumeClaim(PVC)
- 역할 : 개발자가 수행하는 저장소 사용 요청
- 주요 속성 : 필요 용량, 접근 모드, StorageClass
- StorageClass(SC)
- 역할 : 동적 프로비저닝을 위한 템플릿
- 주요 속성 : 프로비저너, 파라미터
추상화 목적
Pod에서 실제 디스크 경로를 감추고 나는 X 만큼의 용량의 저장소가 필요해라는 논리적 요청만 남겨 매니페스트의 이식성을 극대화함
상요작용
PVC가 생성되면 쿠버네티스가 적절한 PV를 찾아 둘을 바인딩(Bound)하고 Pod는 이 PVC를 참조해 저장소를 사용함
4. 핵심 동작 시퀀스
이 챕터는 저장소 할당의 자동화 과정을 정적/동적 관점에서 보여줌
1. Input(Desired State)
사용자가 필요한 용량(Requests.stroage)과 접근 방식(accessModes)을 정의한 PVC 제출
2. Process(Control Loop)
- 매칭 : 쿠버네티스 컨트롤러가 PVC의 요청 사항을 만족하는 사용 가능한(Available) PV를 검색
- 바인딩 : 적절한 PV를 찾으면 PVC와 PV를 1:1로 연결하고 상태를 Bound로 변경
- 마운트 : Pod가 실행될 때 해당 PV의 실제 저장소 기술 정보를 읽어 노드에 부착하고 컨테이너에 마운트함
3. Output(Actual State)
Pod내부에서 지정된 경로를 통해 외부 네트워크 저장소나 로컬 디스크를 투명하게 사용함
비유
호텔 방 예약 시스템과 같음 관리자가 방(PV)을 미리 준비해두면 손님(Pod)은 예약 요청서(PVC)를 작성함 예약이 완료(Binding)되면 손님은 어떤 층, 어떤 호실인지 몰라도 카드키(PVC 참조)만 가지고 방을 사용할 수 있음
5. 운영 및 안정성 체크포인트
- 성능 영향 요소 : 동적 프로비저닝 사용 시 volumeBindingMode : WaitForFirstConsumer 설정은 Pod가 스케줄링될때까지 볼륨 생성을 늦춰 노드 토폴로지 제약을 해결하는 데 도움을 줌
- 장애 시 현상 : PVC를 삭제하더라도 바인딩된 PV의 회수 정책이 Retain이면 실제 데이터와 PV 오브젝트는 유지되지만 Released 상태가 되어 다른 사용자가 즉시 재사용할 수 없음
✅ 체크포인트
필수 키워드
- PersistentVolume(PV) : 인프라 기반의 물리적 저장소 표현
- PersistentVolumeClaim(PVC) : 개발자의 스토리지 사용 신청서
- Binding : PVC와 PV가 1:1로 연결되는 상태
- StorageClass(SC) : 저장소의 종류와 동적 생성 규칙
- Dynamic Provisioning : PVC 생성 시 PV를 자동 생성하는 기능
- ReadWriteOnce(RWO) : 단일 노드에서 읽기/쓰기 가능
- ReadOnlyMany(ROX) : 여러 노드에서 읽기 전용 가능
- ReadWriteMany(RWX) : 여러 노드에서 동시에 읽기/쓰기 가능
- Retain : PVC 삭제 후에도 PV와 데이터를 보존하는 정책
- Delete : PVC 삭제 시 PV와 실제 저장소도 함께 삭제하는 정책
혼동 금지
Access Mode vs Pods
접근 모드는 노드 대수 기준임 RWO 볼륨이라도 동일 녿 내의 여러 Pod는 동시 사용이 가능
PV vs StorageClass
PV는 이미 생성된 자원이고 SC는 자원을 만들어내는 설계도임
정리
8장은 Pod 매니페스틑에서 저장 기술을 분리해 포터빌리티를 높이고 PV/PVC/SC를 통해 저장 자원의 할당과 수명 주기를 자동화하는 방법을 다뤘음
9장 ConfigMap, Secret, Downward API를 통한 설정
1. 설계 배경
- 기존 방식의 한계 : 애플리케이션 설정을 컨테이너 이미지 안에 하드코딩하면 개발이나 운영같은 환경마다 매번 이미지를 새로 빌드해야 하는 고통이 따른다 Pod 매니페스트에 설정을 직접 넣는 방식도 환경별로 매니페스트를 분리해야 하므로 재사용성이 떨어짐
- 쿠버네티스의 해결책 : 설정 데이터를 Pod 디자인과 분리하여 ConfigMap과 Secret 오브젝트에 저장함 이를 통해 동일한 Pod 매니페스트를 여러 환경에서 그대로 사용하면서 각 클러스터의 ConfigMap만 갈아 끼우는 방식으로 포터 빌리티를 확보함
소주제별 키워드
- 9.1 커맨드, 인자, 환경 변수
오버라이드- 이미지 설정을 Pod 차원에서 변경 - 9.2 ConfigMap으로 설정 분리
비민감 데이터- 일반 설정값의 외부화 - 9.3 Secret으로 민감 데이터 전달
보안- 인증서, 암호 등의 안전한 관리 - 9.4 Downward API
메타데이터- 포드명, IP 등 실행 시점 정보 주입 - 9.5 projected 볼륨
통합- 여러 소스를 하나의 디렉터리로 묵
3. 핵심 객체 및 추상화
- ConfigMap
- 역할 : 일반 설정값 저장
- 주요 속성 : Key-value 쌍
- 저장 위치 : etcd
- Secret
- 역할 : 민감 정보 저장
- 주요 속성 : Base64 인코딩, 메모리 기반 저장(볼룸 사용 시)
- 저장 위치 : etcd
- Downward API
- 역할 : Pod 자신이 환경 정보 노출
- 특징 : Rest API 호출 없이 환경 변수나 파일로 정보 획득
추상화 목적
애플리케이션이 쿠버네티스 API의 존재를 몰라도(Kubernetes-agnostic) 표준적인 환경 변수나 파일 시스템 경로를 통해 설정값을 읽을 수 있게 인프라를 숨김
상호작용
Kubelet이 Pod를 실행할 때 ConfigMap/Secret을 참조(Ref)하여 환경 변수를 주입하거나 볼륨을 마운트함
4. 핵심 동작 시퀀스
1. Input(Desired State)
사용자가 설정값이 담긴 ConfigMap을 생성하고 Pod spec에서 이를 참조하도록 정의함
2. Process(Injection/Mounting)
- 검증 : Kubelet이 참조된 ConfigMap이 존재하는지 확인함(optional이 아니면 존재할 때까지 기동 중단)
- 환경 변수 주입 : 컨테이너 프로세스 시작 시 valueFrom 설정을 환경 변수로 변환하여 주입
- 파일 업데이트 : 볼륨 마운트 시 심볼릭 링크를 사용해 설정 변경 시 파일들을 원자적으로 업데이트함
3. Output(Actual State)
애플리케이션 프로세스가 주입된 환경 변수나 마운트된 파일을 통해 설정값을 읽어 동작함
비유
밀키트 요리와 같다 Pod(레시피)는 그대로지만 ConfigMap(소스 종류)에 따라 매콤한 맛이 나기도 하고 달콤한 맛이 나기도함 요리사(쿠버네티스)가 조리 직전에 어떤 소스(설정)를 넣느냐에 따라 최종 요리가 결정됨
5. 운영 및 안정성 체크포인트
- 성능 영향 요소 : 불변(Immutable) ConfigMap을 사용하면 Kubelet이 API 서버를 계속 감시할 필요가 없어 서버 부하를 줄일 수 있음
- 장애 시 현상 : 참조된 ConfigMap이 없고
optional: true가 설정되지 않았다면 컨테이너는 ContainerCreating 상태에 머물며 실행되지 않음 - 보안 주의 : Secret은 볼륨으로 마운트할 때 디스크가 아닌 메모리(tmpfs)에 저장되어 물리적 유출 위험을 줄임
✅ 체크포인트
필수 키워드
- ConfigMap : 일반 설정 정보를 담는 API 객체
- Secret : 암호화가 필요한 데이터를 담는 객체(Base64 인코딩)
- Downward API : Pod의 이름, IP 등 메타데이터를 컨테이너에 전달하는 통로
- envFrom : ConfigMap의 모든 키를 한 번에 환경 변수로 주입
- valueFrom : 특정 키값만 선택하여 주입
- Immutable : 설정을 변경 불가능하게 만들어 안전성과 성능 향상
- Atomic Update : 심볼릭 링크를 통해 여러 설정 파일을 한꺼번에 교체
- Projected Volume : 여러 설정 소스를 하나의 볼륨 디렉터리에 합침
- fieldRef : Downward API에서 Pod 필드 값을 참조할 때 사용
- Base64 : Secret 데이터의 기본 인코딩 방식(암호화는 아님)
혼동 금지
ConfigMap vs Secret
둘 다 설정 전달용이지만 Secret은 메모리 저장(볼륨 시)되어 보안성이 더 높고 인코딩이 적용됨
환경 변수 vs 볼륨
환경 변수는 실행 시 결정되어 업데이트가 어렵지만 볼륨 마운트 방식은 설정 변경 시 실시간 업데이트가 가능
정리
9장은 설정을 외부화(ConfigMap/Secret)하고 실행 시점 정보(Downward API)를 주입해 환경에 독립적인 포터블한 애플리케이션을 배포하는 방벙을 다룸
10장 객체를 네임스페이스와 레이블로 구성하기
1. 설계 배경
- 기존 방식의 한계 : 단일 쿠버네티스 클러스터를 여러 팀이 공유할 때 한 팀이 다른 팀의 객체를 실수로 수정하거나 삭제할 위험이 있음 또한 마이크로서비스 수가 수백 개로 늘어나면 어떤 객체가 어떤 서비스로 속하는지, 현재 안정판인지 카나리배포판인지 구분하기가 매우 힘들어져 시스템 도식화 자체가 고통이됨
- 쿠버네티스의 해결책 : 네임스페이스를 통해 하나의 물리 클러스터를 여러 개의 가상 클러스터로 분할하여 이름 충돌을 방지하고 접근 권한을 관리함 동시에 Label이라는 Key-value 쌍을 도입해 객체의 역할(앱 명칭, 버전 등)을 식별하고 Selector를 통해 수많은 객체 중 원하는 것만 빠르고 정확하게 필터링하여 일괄 조작할 수 있게 함
2. 소주제별 키워드
- 10.1 네임스페이스로 객체 구성
가상 클러스터- 물리적 자원 공유 및 논리적 그룹 분리 - 10.2 레이블로 Pod 구성
식별 정보- 객체의 특성과 역할을 나타내는 메타데이터 - 10.3 레이블 셀렉터로 필터링
검색/조작- 등치 기반 및 집합 기반 필터링 매커니즘 - 10.4 객체 어노테이션
비식별 정보- 레이블보다 큰 용량의 설명적 데이터 저장
3. 핵심 객체 및 추상화
- Namespace
- 역할 : 객체 이름의 범위(Scope) 제공 및 논리적 분리
- 주요 속성 : 이름 중복 허용(다른 네임 스페이스간)
- Label
- 역할 : 객체를 그룹화하고 식별하는 Key-value 쌍
- 주요 속성 : 셀렉터와 연동해 쿼리 가능
- Annotation
- 역할 : 비식별 정보 저장
- 주요 속성 : 최대 256KB 대용량 데이터, 특수문자 허용
추상화 목적
인프라의 복잡한 물리적 경계를 숨기고 개발자가 논리적 그룹(Namespace)과 비즈니스적 속성(Label)을 기반으로 객체를 다루게 함으로써 대규모 마이크로서비스 운영의 복잡성을 관리 가능한 수준으로 낮춤
상호작용
Service나 Deployment가 Label Selector를 통해 Pod들을 감시하고 관리 대상으로 편입시킴
4. 핵심 동작 시퀀스
이 챕터의 프로세스는 객체의 식별과 분류 관점임
1. Input(Desired State)
개발자가 매니페스트의 metadata 섹션에 namespace, labels, annotations를 정의해 제출
2. Process(Control Loop)
- 범위 할당 : API서버가 요청된 네임스페이스에 객체를 생성하고 고유한 UID를 부여
- 색인화 : 시스템은 부여된 레이블을 기반으로 객체들을 인덱싱
- 매칭 : 컨트롤러나 사용자가 셀렉터를 사용해 특정 조건을 만족하는 객체 그룹을 찾아냄
3. Output(Actual State)
필터링된 객체 목록이 출력되거나 특정 노드에 Pod에 스케줄링되거나 서비스가 특정 Pod들로 트래픽을 전달
비유
대형 도서관의 분류 시스템과 같음 네임스페이스는 어린이 도서관, 과학 도서관 같은 별도의 건물(가상 클러스터)이고, 레이블은 책 표지에 붙은 장르, 연령대 스티커임 사서(쿠버네티스)는 스티커(Selector)를 보고 특정 장르의 책만 골라내어 정리함
5. 운영 및 안정성 체크포인트
- 성능 영향 요소 : 어노테이션은 레이블과 달리 필터링에 사용될 수 없지만 도구들이 객체에 대한 추가 정보를 기록하는 용도로 쓰여 시스템 투명도를 높임
- 장애 시 현상 : 네임스페이스를 삭제하면 그 안에 포함된 모든 객체가 함께 삭제됨 삭제 중 Terminating 상태에서 멈춘다면 대개 커스텀 객체의 파이널라이저 문제임
- 주의 사항(격리 한계) : 네임스페이스는 이름의 충돌을 방지할 뿐 실제 실행 환경(Runtime)의 물리적 격리를 보장하지 않음 서로 다른 네임스페이스의 Pod들이 동일한 노드에서 실행될 수 있음
✅ 체크포인트
필수 키워드
- Namespace : 가상 클러스터 분할 단위
- Label : 객체 식별용 Key-Value
- Label Selector : 레이블 기반 객체 필터링 쿼리
- Equality-base : 동등(=) 혹은 비동등(!=)을 따지는 셀렉터
- Set-based : 포함(in) 혹은 미포함(notin)을 따지는 강력한 셀렉터
- Node Selector : 특정 레이블이 있는 노드에 Pod를 배치하는 설정
- Field Selector : 객체의 필드값으로 필터링
- Annotation : 비식별, 대용량 메타데이터 저장소
- headless Service : StatefulSet과 연동해 개별 Pod에 DNS 이름을 부여
- Termination : 삭제 중인 네임 스페이스의 상태
혼동 금지
Label vs Annotation
Label은 객체를 선택(Filter)할때 사용 Annotation은 선택에 사용할 수 없고 오직 정보 기록 용도
Logical vs Physiclal Isolation
네임스페이스는 논리적 격리일 뿐임 보안을 위한 완전한 격리가 필요하다면 별도의 물리 클러스터를 사용해야함
정리
10장은 네임스페이스로 자원을 논리적으로 분리하고 레이블과 셀렉터로 수 많은 객체를 체계적으로 식별/분류하여 운영 효율성을 극대화하는 방법을 다룸
11장 서비스로 Pod 노출(Exposing Pods with Services)
1. 설계 배경
- 기존 방식의 한계 : Pod는 일시적(Ephemeral)인 존재임 Pod가 삭제되고 다시 생성될 때마다 새로운 IP 주소를 할당받기에 클라이언트가 가변적인 Pod IP를 일일이 추적해 연결하는 것은 불가능에 가까움 또한 여러 Pod 복제본이 동일한 서비스를 제공할 때 클라이언트가 어떤 Pod에 연결할지 결정하고 부하를 분산하는 로직을 직접 구현해야 하는 고통이 따름
- 쿠버네티스의 해결책 : Service 오브젝트를 도입해 Pod 집합에 대해 단일하고 안정적인 진입점(stable IP 및 Port)을 제공함 서비스의 IP는 서비스가 존재하는 동안 변하지 않으므로 Pod의 교체나 스케줄링 변화와 무관하게 클라이언트는 일관된 주소로 통신할 수 있음
2. 소주제별 키워드
- 11.1 서비스 소개
안정적 진입점- ClusterIP, 레이블 셀렉터, 서비스 발견(DNS, 환경 변수) - 11.2 서비스 외부 노출
외부 접근- NodePort, LoadBalancer 유형 - 11.3 서비스 엔드포인트 관리
실제 주소 목록- Endpoints 및 EndpointSlice 오브젝트 - 11.4 서비스 DNS 레코드
이름 해석- SRV 레코드, 헤드리스(Headless) 서비스 - 11.5 트래픽 라우팅 최적화
근접성- Local 트래픽 정책, 토폴로지 힌트 - 11.6 준비성 프로브
신뢰성- Readiness Probes를 통한 트래픽 차단/허용 제어
3. 핵심 객체 및 추상화
- Service
- 역할 : Pod 그룹을 위한 가상 IP 제공
- 주요 속성 : Selector, ClusterIP, Port
- 저장 위치 : etcd
- 엔드포인트(Endpoints/EndpointSlice)
- 역할 : 서비스에 연결된 실제 Pod IP와 포트의 동적 리스트
- 특징 : 쿠버네티스가 셀렉터를 기반으로 자동 관리
- 준비성 프로브(Readiness Probe)
- 역할 : Pod가 트래픽을 받을 준비가 되었는지 검사
- 특징 : 실패 시 서비스 엔드포인트에서 자동 제외
추상화 목적
클라이언트로부터 Pod의 개수, 위치, IP 변화를 완전히 숨기고 비즈니스 로직이 논리적인 이름이나 고정 IP만으로 서비스에 접근할 수 있게 함
상호작용
Service가 Label Selector로 Pod를 식별하면 Endpoints Controller가 Endpoints/Slice를 갱신하고 Kube Proxy가 각 노드에 라우팅 규칙을 설정함
4. 핵심 동작 시퀀스
이 챕터의 핵심은 동적인 포드들을 정적인 서비스 주소로 묶어주는 과정임
1. Input(Desired State)
사용자가 특정 레이블 셀렉터와 포트가 정의된 서비스 매니페스트를 API 서버에 제출함
2. Process(Control Loop)
- IP 할당 : 컨트롤 플레인 서비스에 가상 ClusterIP를 할당
- 엔드포인트 생성 : 컨트롤러가 셀렉터에 부합하고 준비성 프로브를 통과한 Pod들을 찾아 엔드포인트 리스트를 만듬
- 프록시 설정 : 각 노드의 Kube Proxy가 이 서비스 IP로 오는 트래픽을 실제 Pod 중 하나로 전달하도록 네트워크 규칙을 구성함
3. Output(Actual State)
클라이언트가 서비스 IP로 접속하면 현재 사용 가능한 Pod중 하나로 연결이 성공함
비유
서비스는 식당의 주문 카운터와 같음 주방 안에서 요리사(Pod)가 교대하거나 바뀌어도 손님(클라이언트)은 항상 같은 카운터(서비스 IP)에서 주문하면 됨 카운터 직원은 현재 요리 가능한 요리사(Ready 상태의 Pod)에게 주문서를 전달함
5. 운영 및 안정성 체크포인트
- 성능 영향 요소 : 서비스 IP는 가상 IP이므로 ping 응답을 하지 않음 연결 가능 여부는 반드시 해당 포트로 직접 접속해 확인해야함
- 장애 시 현상 : 준비성 프로브를 설정하지 않으면 Pod가 생성되자마자 트래픽이 유입되어 앱 초기화 중에 연결 실패가 발생할 수 있음
- 안정성 : Pod 삭제 시 쿠버네티스는 해당 Pod를 모든 서비스 엔드포인트에서 즉시 제거하여 종료 중인 Pod로 트래픽이 가능 것을 방지
✅ 체크포인트
필수 키워드
- ClusterIP : 클러스터 내부에서만 사용하는 기본 서비스 유형
- NodePort : 모든 워커 노드의 특정 포트를 통해 외부 접근 허용
- LoadBalancer : 클라우드 제공업체의 로드 밸랜서를 프로비저닝하여 노출
- Headless Service : ClusterIP가 없어 DNS가 Pod IP들을 직접 반환하는 서비스
- Readiness Probe : Pod의 트래픽 수용 가능 여부를 확인하는 검사
- Endpoints : 서비스의 대상이 되는 IP/Port 쌍의 목록
- EndpointsSlice : 대규모 클러스터에서 엔드포인트 관리 효율을 높인 객체
- InternalTrafficPolicy
- Local : 트래픽을 보낸 Pod와 같은 노드에 있는 엔드포인트만 사용
- SRV record : DNS를 통해 서비스의 포트 이름과 번호를 찾는 레코드
- Session Affinity : 동일 클라이언트의 요청을 계속 같은 Pod로 전달하는 기능(Ingress와 비교되니 주의)
혼동 금지
Liveness vs Readiness
Liveness는 고장 난 컨테이너를 재시작 Readiness는 준비 안 된 Pod를 트래픽에서 제외
Service IP vs Pod IP
Service IP는 불변 Pod IP는 가변
정리
11장은 가변적인 Pod 네트워크 환경에서 고정된 진입점을 제공하는 서비스 객체임 준비된 Pod에게만 트래픽을 보내는 안전성 확보 매커니즘을 다룸
12장 Ingress로 서비스 노출
1. 설계 배경
- 기존 방식의 한계 : LoadBalancer 타입의 서비스를 사용하면 각 서비스마다 고유한 공인 IP 주소가 필요함 서비스가 수백 개로 늘어나면 공인 IP 확보 비용과 관리 부담이 먀우 커지는 고통이 따름 또한 Service는 4계층(L4)에서 동작하므로 쿠키 기반 세션 고정이나 URL 경로 기반 라우팅 같은 정교한 7계층(L7) 기능을 제공하지 못함
- 쿠버네티스의 해결책 : Ingress를 도입해 수많은 서비스를 단 하나의 공인 IP 뒤에 통합 노출함 인그레스는 L7 로드 벨런서 역할을 수행하며 호스트 이름이나 URL 경로에 따라 트래픽을 서로 다른 내부 서비스로 배분하고 TLS 터미네이션 등의 보안 기능을 제공함
2. 소주제별 키워드
- 12.1 Ingress 소개
입구(Entryway)- 외부 클라이언트가 클러스터 서비스에 진입하는 단일 통로 - 12.2 Ingress 생성 및 사용
라우팅 가이드- 호스트 및 경로 기반의 트래픽 전달 규칙 - 12.3 TLS qhdks
종단점 보안- 프록시에서 복호화를 수행하는 TLS 터미네이션 - 12.4 추가 설정 옵션
어노테이션- 세션 고정 등 구현체 별 특화 기능 설정 - 12.5 다중 컨트롤러 사용
IngressClass- 여러 Ingress 구현체 중 누가 처리할지 결정
3. 핵심 객체 및 추상화
- Ingress Object
- 역할 : 외부 노출 규칙 정의서
- 주요 속성 : rules, tls, backend
- 저장 위치 : etcd
- Ingress Controller
- 역할 : API 서버를 감시하여 프록시 설정을 자동 갱신하는 뇌 역할
- 특징 : 클러스터 설치 시 기본 제공되지 않을 수 있음
- 리버스 프록시(L7 Load Balancer)
- 역할 : 실제 트래픽을 받아 배분하는 실행기
- 특징 : Ngins, HAProxy 등이 실제 트래픽을 처리
추상화 목적
Ingress는 서비스들의 추상화임 클라이언트에게는 내부의 복잡한 서비스 구조와 개별 IP를 숨기고 단일한 진입점과 논리적인 URL 구조만 노출함
상호작용
컨트롤러가 인그레스, 서비스, 엔드포인트슬라이스를 감시하고 리버스 프록시의 설정을 변경함
4. 핵심 동작 시퀀스
규칙 정의가 실제 트래픽 흐름으로 변환되는 과정
1. Input(Desired State)
host, path, 대상 서비스(backend)가 명시된 Ingress 매니페스트 제출
2. Process(Control Loop)
- 감시 : Ingress 컨트롤러가 API 서버의 Ingress 객체 생성을 감지
- 조합 : 컨트롤러가 대상 서비스의 엔드포인트(Pod IP 목록)정보를 가져옴
- 구성 : 컨트롤러가 리버스 프록시(Nginx 등)의 라이팅 테이블을 갱신
3. Output(Actual State)
클라이언트가 공인 IP로 보낸 HTTP 요청이 L7 헤더 정보에 따라 적절한 Pod로 전달됨
비유
Ingress는 종합 쇼핑몰의 안내 데스크와 같음 고객(클라이언트)은 쇼핑몰 입구(단일 IP)로 들어와 안내데스크(Ingress 규칙)에 목적지(URL 경로)를 물음 안내원은 해당 매장(서비스)이 있는 위치(Pod IP)로 고객을 안내함
5. 운영 및 안정성 체크포인트
- 성능 영향 요소 : Ingress 프록시는 트래픽을 서비스 IP로 보내지 않고 Pod IP로 직접 전달하는 경우가 많아 불필요한 네트워크 홉을 줄임
- 장애 시 현상 : Ingress 객체를 생성해도 ADDRESS 필드에 IP가 뜨지 않는다면 해당 Ingress를 처리할 Ingress 컨트롤러가 없거나 IngressClass 설정이 잘못된 것임
- 기본 백엔드 : 요청이 어떤 규칙과도 일치하지 않을 때 트래픽을 처리할 catch-all 서비스를 반드시 지정해야 안정적인 응답(ex. 404 페이지)이 가능함
✅ 체크포인트
필수 키워드
- L7 Load Balancer : HTTP 헤더를 해석해 라우팅하는 계층
- Ingress Controller : Ingress 규칙을 프록시 설정으로 실체화하는 컴포넌트
- Path-based Routing : URL 경로에 따라 다른 서비스로 연결
- Host-based Routing : 도메인 이름에 따라 다른 서비스로 연결
- TLS Termination : Ingress 프록시에서 복호화를 처리하고 백엔드에는 평문 전달
- pathType : 경로 매칭 방식(Exact : 일치, Prefix : 접두사 일치)
- Default Backend : 일치하는 규칙이 없을 때 트래픽을 받는 서비스
- IngressClasee : 클러스터 내 여러 Ingress 구현체 중 하나를 지정
- Annotation : 세션 고정 등 특정 컨트롤러 전용 기능을 설정할 때 사용
- /etc/hosts : 도메인 이름이 실제 Ingress IP로 해석되도록 로컬에서 설정
혼동 금지
Service vs Ingress
Service는 Pod 그룹의 추상화이고 Ingress는 서비스 그룹의 추상화
LoadBalancer Service vs Ingress
LoadBalancer 서비스는 L4에서 동작하며 각각 IP가 필요 Ingress는 L7에서 동작하며 하나의 IP만 사용
정리
12장은 단일 IP와 도메인/경로 기반 규칙을 사용해 다수의 내부 서비스를 외부에 효율적이고 안전하게 노출하는 Ingress 메커니즘을 다룸
13장 ReplicaSet으로 Pod 복제
1. 설계 배경
- 기존 방식의 한계 : 프로덕션 클러스터에서 수십 개 또는 수백 개의 동일한 Pod 복사본을 수동으로 하나씩 생성하고 관리하는 것은 극도로 어려움 또한 Pod는 일시적인 존재이므로 Pod가 실행 중인 노드가 실패하면 해당 Pod 인스턴스는 다른 노드로 이동하지 않고 그대로 소실되는 고통이 따름
- 쿠버네티스의 해결책 : ReplicaSet 오브젝트를 통해 Pod 복제본의 생성과 관리를 자동화함 사용자가 원하는 복제본 수를 선언하면 ReplicaSet은 노드 장애 시에도 새로운 Pod를 다른 노드에 생성해 항상 지정된 수의 Pod가 실행되도록 보장함
2. 소주제별 키워드
- 13.1 ReplicaSet 소개
Replication- Pod 템플릿과 원하는 복제본 수 정의 - 13.2 ReplicaSet 업데이트
Scaling- 복제본 수 변경 및 템플릿 수정의 한계 - 13.3 ReplicaSet 컨트롤러의 동작
조정 루프(Reconciliation Loop)- 현재 상태와 기대 상태의 일치 - 13.4 ReplicaSet 삭제
GC- 소유권과 종속 객체 정리
3. 핵심 객체 및 추상화
- ReplicaSet
- 역할 : Pod 복제본 그룹 관리
- 주요 속성 : replicas(복제본 수), selector(레이블 셀렉터), template(Pod 템플릿)
- 저장 위치 : etcd
추상화 목적
개발자에게 개별 Pod의 생존 여부를 일일이 감시해야 하는 부담을 없애주고 클러스터 전체 수준에서 애플리케이션 인스턴스가 항상 N개 유지됨이라는 논리적 보장을 제공
상호작용
ReplicaSet 컨트롤러가 Pod들과 ReplicaSet 객체를 감시하고 차이가 발견되면 Pod 생성 또는 삭제를 통해 상태를 변경
4. 핵심 동작 시퀀스
상태 일치(Reconciliation) 관점에서 무한 반복
1. Input(Desired State)
사용자가 정의한 spec.replicas(원하는 수)와 spec.template(Pod 설계도)
2. Process(Control Loop)
- 관찰(Observe) : 컨트롤러가 셀렉터에 일치하는 실행 중인 Pod 수를 확인
- 비교(Compare) : 실제 Pod 수와 ReplicaSet에 설정된 원하는 수를 비교
- 조정(Update) : 부족하면 템플릿으로 새 Pod 생성, 남으면 기존 Pod 삭제
3. Output(Actual State)
클러스터 내에 정확히 원하는 수만큼의 Pod가 실행되는 결과
비유
ReplicaSet의 Pod 템플릿은 쿠키 커터와 같음 ReplicaSet은 이 커터(템플릿)를 사용해 새로운 Pod 쿠키를 찍어냄 커터의 모양(템플릿)을 바꿔도 이미 구워진 쿠키(실행 중인 Pod)의 모양은 변하지 않음
5. 운영 및 안정성 체크포인트
- 성능 영향 요소 : ReplicaSet은 레이블 셀렉터를 통해 기존에 이미 존재하던 Pod(수동 생성 등)도 자신의 관리 하에 입양(Adopt)할 수 있음
- 장애 시 현상 : 노드가 NotReady 상태가 되면 ReplicaSet 컨트롤러는 해당 노드의 Pod들을 삭제 대상으로 마킹하고 건강한 다른 노드에 새 Pod를 생성해 가용성을 유지함
- 스케일 다운 우선순위
- 복제본을 줄일 경우
- 할당 안된 Pod
- 상태 불명 Pod
- 준비 안된 Pod
- 재시작 횟수가 많은 Pod 위 순서로 먼저 삭제해 시스템 안전성을 극대화함
- 복제본을 줄일 경우
✅ 체크포인트
필수 키워드
- replicas : 유지해야 할 Pod 복제본의 수
- selector : 어떤 Pod가 ReplicaSet에 속하는지 결정하는 기준
- template : 새 Pod를 만들 때 사용하는 설계도
- Reconciliation Loop : 상태를 끊임없이 일치시키는 제어 루프
- OwnerReference : Pod가 어떤 ReplicaSet에 속해 있는지 나타내는 메타데이터
- GC : 소유자 객체 삭제 시 종속된 Pod도 자동 삭제하는 메커니즘
- Orphan : 소유자 객체만 삭제하고 Pod는 남겨두는 형태
- Immutable Selector : 생성 후 변경할 수 없는 레이블 셀렉터 속성
- pod-template-hash : 디플로이먼트가 관리할 때 RS와 Pod에 부여하는 고유 해시 값
- Self-healing : 노드 장애 시 자동으로 Pod를 교체하는 능력
혼동 금지
템플릿 수정 vs 기존 Pod
템플릿을 수정해도 이미 실행중인 Pod는 변하지 않음 수정 후 생성되는 Pod부터 새 템플릿이 적용됨
RS 삭제 vs Pod 보존
기본 삭제 시 포드도 함께 지워지지만 --cascade=orphan 옵션을 쓰면 Pod만 살려둘 수 있음
정리
ReplicaSet은 선언적 모델과 조정 루프를 통해 지정된 수의 Pod 복제본을 유지하고 노드 장애 시 자동 복구를 수행하는 핵심 컨트롤러 객체임
14장 Deployments로 Pod 관리
1. 설계 배경
- 기존 방식의 한계 : ReplicaSet은 Pod 복제본을 유지하는 데는 훌륭하지만 애플리케이션을 새로운 버전으로 업데이트하는 기능은 제공하지 않음 과거에는 새 버전을 배포하기 위해 수동으로 ReplicaSet을 교체하거나 복잡한 과정을 거쳐야 했음 이 과정에서 서비스 중단이 발생하거나 배포 상태를 추적하기 어려운 고통이 따랐음
- 쿠버네티스의 해결책 : Deployment 오브젝트를 통해 애플리케이션 업데이트를 선언적(Declarative)으로 자동화함 개발자가 Deployment의 Pod 템플릿만 수정하면 쿠버네티스가 내부적으로 ReplicaSet을 조절해 새 버전을 배포하고 가동 중지 시간을 최소화하며 필요 시 이전 버전으로의 롤백까지 지원함
2. 소주제별 키워드
- 14.1 Deployment 소개
추상화 계층- 레플리카셋을 관리하는 상위 객체 - 14.2 Deployment 업데이트
배포 전략- Recreate와 RollingUpdate의 메커니즘 - 14.3 기타 배포 전략 구현
패턴- Canary, Blue/Green, A/B 테스트의 논리적 구조
3. 핵심 객체 및 추상화
- Deployment
- 역할 : 무상태 애플리케이션의 배포 및 업데이트 관리
- 주요 속성 : strategy, replicas, template
- 저장 위치 : etcd
- ReplicaSet
- 역할 : Deployment에 의해 생성되어 특정 버전의 Pod 개수를 유지
- 특징 :
pod-template-hash레이블을 통해 버전을 식별
추상화 목적
개발자에게 ReplicaSet과 Pod의 세부 관리 로직을 숨기고 애플리케이션의 최종 상태(이미지 버전, 개수)만 정의하면 시스템이 이를 실현하도록 돕는 것임
상호작용
Deployment 컨트롤러가 Deployment 객체를 감시하고 ReplicaSet을 생성/수정해 Pod의 상태를 변경함
4. 핵심 동작 시퀀스
Deployment의 업데이트는 ReplicaSet 간의 가중치 이동 과정임
1. Input(Desired State)
사용자가 Deployment의 spec.template에서 이미지 태그나 레이블 등을 수정함
2. Process(Control Loop)
- 감시 : Deployment 컨트롤러가 템플릿 변경을 감지하고 새 ReplicaSet을 생성함
- 교체
- Rolling Update 시
- 새 ReplicaSet을 1개씩 늘리고 동시에 이전 ReplicaSet을 1개씩 줄임
- Rolling Update 시
- 검증 :
minReadySeconds동안 Pod가 Ready상태를 유지하는지 확인하며 진행
3. Output(Actual State)
이전 버전의 ReplicaSet은 0이 되고 새 버전의 ReplicaSet이 원하는 복제본 수만큼 Pod를 유지함
비유
Deployment는 공장 전체 라인을 관리하는 총감독임 감독(Deployment)이 새로운 모델(버전) 생산 지시를 내리면 현장 반장(ReplicaSet)들이 투입되어 기존 라인(이전 Pod)을 하나씩 멈추고 새라인(새 Pod)을 가동하여 공장 전체의 생산을 멈추지 않고 신모델로 교체하는 것곽 같음
5. 운영 및 안정성 체크포인트
- 성능 영향 요소 : revisionHistoryLimit 필드를 통해 이전 ReplicaSet(기록)을 몇 개까지 보관할지 결정하며 기본값은 10개임
- 장애 시 현상 : 배포된 새 버전의 Pod가 준비성 프로브(Readiness Probe)를 통과하지 못하면 AVAILABLE 상태가 되지 않아 롤아웃이 중단되고 서비스 가용성을 보호함
- 이력 관리 : kubectl rollout history를 통해 배포 이력을 확인하고 kubectl rollout undo로 즉시 이전 상태로 되돌릴 수 있음
✅ 체크포인트
필수 키워드
- Deployment : ReplicaSet의 상위 추상화 객체
- RollingUpdate : Pod를 순차적으로 교체해 가용성을 유지하는 기본 전략
- Recreate : 기존 Pod를 모두 삭제 후 새 Pod를 생성하는 전략(중단 시간 발생)
- pod-template-hash : Deployment가 ReplicaSet을 식별하기 위해 자동 부여하는 레이블
- minReadySeconds : Pod가 Available로 간주되기 위해 건강하게 유지되어야 하는 최소 시간
- maxSurge : 업데이트 중 원하는 복제본 수보다 초과해서 생성활 수 있는 포드의 최대 수
- maxUnavailable : 업데이트 중 사용할 수 없게 되어도 되는 Pod의 최대 수
- rollout undo : 배포 중단 및 이전 버전으로 롤백 명령
- revision : Deployment의 업데이트 이력 번호
- Stateless : Deployment가 관리하기에 가장 적합한 워크로드 유형
혼동 금지
Deployment vs ReplicaSet
Deployment는 업데이트 로직을 가지며 ReplicaSet을 부하로 부리지만 ReplicaSet은 오직 개수 유지에만 집중
Ready vs Available
Pod가 프로브를 통과하면 Ready Ready 상태로 minReadySeconds를 버티면 Available임
정리
14장은 무상태 애플리케이션을 가동 중지 없이 배포하고 관리하기 위한 선언적 업데이트 매커니즘인 Deployment를 다룸
15장 StatefulSet으로 스테이트풀 워크로드 배포
1. 설계 배경
- 기존 방식의 한계 : Deployment와 같은 일반적인 방식은 모든 Pod가 동일한 설정을 공유하는 Cattle(가축) 모델을 따름 그러나 DB와 같은 스테이트풀 워크로드는 각 복제본이 자신만의 고유한 상태(데이터)를 유지해야 하며 Pod가 재시작되거나 재스케줄링되어도 동일한 데이터 볼륨과 네트워크 정체성(Identity)을 유지해야 하는 고통스러운 요구사항이 있음 Deployment로 이를 구현하려면 복제본마다 별도의 Deployment, 서비스, PVC를 수동으로 만들어야 하는 복잡성이 발생함
- 쿠버네티스의 해결책 : StatefulSet을 도입해 각 Pod 복제본에 고유한 순서 번호(Ordinal)를 부여하고 이를 기반으로 안정적인 네트워크 이름과 전용 스토리지(Sticky Storage)를 자동으로 할당해 관리 효율성을 극대화함
2. 소주제별 키워드
- 15.1 StatefulSet 소개
Pets- 개별 정체성을 가진 고유한 인스턴스 관리 - 15.1.3 StatefulSet 생성
Headless Service- Pod 개별 주소 지정을 위한 필수 요소 - 15.2 StatefulSet 동작 이해
Ordinal- 순차적 생성/삭제 및 노드 장애 대응 - 15.3 StatefulSet 업데이트
Partition- 롤링 업데이트와 카나리 배포 제어 - 15.4 Kubernetes Operators
Automation- 복잡한 앱 관리를 위한 커스텀 컨트롤러
3. 핵심 객체 및 추상화
- StatefulSet
- 역할 : 고유 정체성이 필요한 앱의 복제본 관리
- 주요 속성 : serviceName, volumeClaimTemplates
- 저장 위치 : etcd
- Headless Service
- 역할 : Pod별로 직접적인 DNS 레코드 제공
- 추상화 목적 : Cluster IP를 숨기고 개별 Pod의 IP 주소를 직접 노출해 Peer Discovery를 가능하게함
- volumeClaimTemplates
- 역할 : 각 Pod마다 별도의 PVC를 자동으로 생성
- 특징 : Pod마다 독립적인 영구 볼륨을 가짐
상호작용
StatefulSet이 volumeClaimTemplates를 통해 PVC를 생성하고 Headless Service를 통해 Pod의 고유 DNS 이름을 생성함
4. 핵심 동작 시퀀스
StatefulSet은 순서와 정체성을 기반으로 상태를 일치시킴
1. Input(Desired State)
복제본 수, Pod 템플릿, 그리고 각 Pod가 가질 전용 볼륨의 PVC 템플릿 정의
2. Process(Control Loop)
- 순차 생성 : 0번부터 N-1번까지 순서대로 Pod를 생성하며 이전 포드가 Ready가 되어야 다음 Pod를 생성함(OrderedReady 정책 시)
- 스토리지 바인딩 : 각 Pod(ex. quiz-0)에 대응하는 PVC(ex. db-data-quiz-0)를 생성해 전용 볼륨을 연결함
- 네트워크 정체성 부여 : Headless Service를 통해 Pod명.서비스명.네임스페이스.svc.cluster.local 주소를 할당함
3. Output(Actual State)
각기 다른 데이터와 고속도로(DNS)를 가진 고유한 Pod 인스턴스들이 클러스터에 안정적으로 상주함
5. 운영 및 안정성 체크포인트
- 성능 영향 요소 : podManagementPolicy를 Parallel로 설정하면 순차 생성을 무시하고 동시에 시작해 배포 속도를 높일 수 있지만 초기 정족수(Quorum) 구성이 필요한 앱에서는 주의가 필요함
- 장애 시 현상(At-most-one semantics) : 노드 장애 시 StatefulSet은 동일한 이름의 Pod가 동시에 두 군데에서 실행되지 않도록 매우 보수적으로 동작함 Kubelet이 응답하지 않으면 자동으로 Pod를 교체하지 않으며 관리자가 명확히 확인 후 강제 삭제(—force)해야 할 수도 있음
- 스토리지 보존 : 기본적으로 StatefulSet을 삭제하거나 스케일 다운해도 생성된 PVC는 자도으로 삭제되지 않음(Retain 정책) 이는 실수로 인한 데이터 유실을 방지하기 위함임
✅ 체크리스트
필수 키워드
- Ordinal(서수) : 0,1,2… 순서대로 부여되는 Pod 인덱스
- Headless Service
- clusterIP : None 설정으로 Pod 개별 IP를 반환하는 서비스
- Sticky Storage : 특정 Pod 인덱스에 고정되어 재시작 후에도 유지되는 볼륨
- volumeClaimTemplates : 각 Pod 전용 PVC를 생성하기 위한 설계도
- OrderedReady : 이전 Pod가 준비될 때까지 다음 Pod 생성을 대기하는 기본 정책
- At-most-one : 한 번에 최대 하나의 Pod만 존재함을 보장하는 세멘틱
- Partition : 업데이트 시 특정 인덱스 이상의 Pod만 먼저 업데이트하는 기능
- OnDelete : Pod가 수동으로 삭제될 때만 새 템플릿으로 교체하는 전략
- ControllerRevision : StatefulSet의 업데이트 이력을 저장하는 객체
- Operator : StatefulSet만으로 부족한 복잡한 운영 로직을 자동화하는 소프트웨어
혼동 금지
Deployment vs StatefulSet
Deployment는 Pod 이름에 랜덤 해시가 붙고 볼륨을 공유하려 하지만 StatefulSet은 Pod 이름에 순서 번호가 붙고 볼륨을 개별적으로 가짐
Ready vs Available
Pod가 프로브를 통과하면 Ready 지정된 시간(minReadySeconds)동안 Ready 상태를 유지하면 Available임
정리
15장은 고유한 네트워크 정체성과 전용 스토리지가 필요한 앱을 위해 순서 번호를 기반으로 Pod와 볼륨을 1:1 매칭해 관리하는 StatefulSet 아키텍처를 다룸
16장 DaemonSet으로 노드 에이전트 및 데몬 배포
1. 설계 배경
- 기존 방식의 한계 : Deployment나 ReplicaSet은 복제본을 클러스터 전체에 흩뜨려 배포하지만 특정 노드에 정확히 몇 개가 들어갈지는 제어하기 어려움 로그 수집기나 모니터링 에이전트처럼 모든 노드에 반드시 하나씩 실행되어야 하는 시스템 서비스를 수동으로 관리하거나 일반 컨트롤러로 배포하는 것은 노드가 추가/삭제될 때마다 운영자에게 엄청난 고통을 줌
- 쿠버네티스의 해결책 : DaemonSet을 통해 클러스터의 각 노드마다 정확히 하나의 Pod 복제본이 실행되도록 보장함 새 노드가 추가되면 자동으로 Pod를 생성하고 노드가 삭제되면 Pod를 정리해 인프라 수준의 에이전트 관리를 자동화함
2. 소주제별 키워드
- 16.1 DaemonSet 소개
노드별 실행- 노드 수에 따른 자동 스케줄링및 조정 루프 - 16.2 노드 에이전트 Pod의 특수 기능
자원 접근- hostPath, 커널 성능, 우선순위 클래스 - 16.3 로컬 데몬 포드와 통신
로컬 엔드포인트- hostPort, hostNetwork, Local 트래픽 정책
3. 핵심 객체 및 추상화
- DaemonSet
- 역할 : 노드별 에이전트 배포 관리
- 주요 속성 : selector, template, nodeSelctor
- 저장 위치 : etcd
- 우선순위 클래스(PriorityClass)
- 역할 : 시스템 Pod의 중요도 명시
- 특징 : system-nod-critical 등을 사용해 자원 부족 시에도 퇴출(Eviction) 방지
추상화 목적
개발자가 클러스터의 크기나 노드 목록을 몰라도 이 에이전트는 모든(또는 특정 조건을 만족하는) 노드에 상주해야한다는 의도만 선언하면 시스템이 물리적 인프라 변화에 맞춰 잗ㅇ으로 실행 상태를 유지함
상호작용
DaemonSet Controller가 Node 객체의 변화를 감시하고 각 노드에 대응하는 Pod를 직접 생성/삭제함 이때 Deployment와 달리 중간에 ReplicaSet같은 객체를 두지 않고 Pod를 직접 소유함
4. 핵심 동작 시퀀스
DaemonSet 프로세스는 노드 존재 여부와 Pod 일치 관점에서 작동함
1. Input(Desired State)
Pod 템플릿과 대상 노드를 결정하는 nodeSelector(선택사항)가 정의된 DaemonSet 매니페스트
2. Process(Control Loop)
- 관찰 : 컨트롤러가 현재 노드 목록과 해당 노드들에서 실행 중인 DaemonSet Pod를 확인
- 비교 : 특정 노드에 Pod가 없거나 노드가 삭제되었는데 Pod가 남았는지 확인
- 조정 : Pod가 없는 노드에는 새 Pod를 생성하고 더 이상 존재하지 않는 노드와 연결된 Pod는 삭제함
3. Output(Actual State)
클러스터의 각 워커 노드마다 에이전트 Pod가 하나씩 실행되는 결과
비유
DaemonSet은 각 층(노드)마다 배치된 전담 관리인과 같음 건물이 증축(노드 추가)되면 즉시 새 관리인을 배치하고 층이 폐쇄(노드 제거)되면 관리인도 함께 철수시키는 자동화된 인사 시스템
5. 운영 및 안정성 체크포인트
- 성능 영향 요소 : DaemonSet Pod는 기본적으로 컨트롤 플레인(마스터) 노드에는 배포되지 않음 이를 무시하고 모든 노드에 배포하려면 tolerations 설정을 통해 마스터 노드의 taints를 허용해야함
- 장애 시 현상 : 노드 에이전트 Pod는 시스템 운영에 필수적이므로 일반 Pod보다 높은 우선순위(priorityClassName)를 가져야함 그렇지 않다면 자원 부족 시 일반 워크로드에 밀려 에이전트가 중단될 위험이 있음
- 보안 위험 : DaemonSet Pod는 노드 자원에 접근하기 위해 hostPath(파일 시스템), hostNetwork(네트워크), privileged(커널 권한) 등을 자주 사용하므로 보안 검토가 필수적임
✅ 체크포인트
필수 키워드
- DaemonSet: 각 노드에 Pod하나를 보장하는 컨트롤러
- nodeSelector : DaemonSet을 특정 레이블의 노드에만 배포하도록 제한
- Taints & Tolerations : 마스터 노드 등 특수한 노드에 배포하기 위해 필요한 기법
- PriorityClass : Pod의 중요도를 설정해 자원 확보 시 우선순위 부여
- hostPath : 호스트 노드의 파일시스템에 직접 접근하는 볼륨
- hostNetwork : Pod가 독자적 네트워크 대신 호스트 노드의 네트워크 환경 사용
- hostPort : 호스트 노드의 특정 포트를 Pod 컨테이너에 직접 매핑
- internalTrafficPolicy
- Local : 트래픽을 보낸 노드와 동일한 노드의 Pod로만 전달
- RollingUpdate : Daemon Pod를 하나씩 순차적으로 교체하는 기본 업데이트 저략
- OnDelete : 사용자가 기존 Daemon Pod를 지울 때만 새 버전으로 교체
혼동 금지
ReplicaSet vs DaemonSet
RS는 복제본 수를 맞추고 아무 데나 배포하지만 DS는 노드당 하나를 위치에 맞춰 배포함
hostPort vs NodePort
NodePort는 모든 노드의 Pod를 열어 전체 서비스로 연결 hostPort는 해당 노드의 특정 Pod를 직접 연결
정리
16장은 시스템 수준의 서비스를 위해 각 노드에 Pod 복제본을 배치하고 관리하며 호스트 자원에 접근하는 특수 기능을 활용하는 DaemonSet을 다룸
17장 Job과 CronJob으로 유한 워크로드 실행
1. 설계 배경
- 기존 방식의 한계 : Deployment, StatefulSet, DaemonSet은 애플리케이션을 지속적으로 실행하는 데 최적화되어있음 만약 프로세스가 종료되면 Kubelet은 이를 장애로 간주해 무조건 재시작한다 따라서 DB 초기화, 데이터 분석, 보고서 생성과 같이 한 번의 작업을 마치면 종료되어야 하는 유한 워크로드(Finite workload)를 관리하기에는 부적합하며 수동으로 Pod를 생성할 경우 노드 장애 시 자동 재배치가 되지 않는 고통이 따름
- 쿠버네티스의 해결책 : Job 리소스를 통해 작업의 성공적인 완료를 보장한다 Job은 작업이 실패하면 다시 시도하고 지정된 횟수만큼 성공할 때까지 Pod를 관리함 또한 CronJob을 도입해 이러한 작업을 특정 시간이나 주기적으로 예약 실행할 수 있게함
2. 소주제별 키워드
- 17.1 Job 리소스로 작업 실행
완료 보장- 유한 작업의 성공적 종료 및 실패 대응 - 17.2 CronJob으로 작업 예약
예약 엔진- Job의 실행 스케줄링 및 이력 관리
3. 핵심 객체 및 추상화
- Job
- 역할 : 유한 작업의 실행 및 완료 관리
- 주요 속성 : completions, parallelism
- 저장 위치 : etcd
- CronJob
- 역할 : Job을 스케줄에 따라 생성하는 래퍼(Wrapper)
- 주요 속성 : schedule, jobTemplate
- 저장 위치 : etcd
추상화 목적
개발자가 작업의 상태를 직접 모니터링하거나 재시작 로직을 짤 필요 없이 성공 횟수와 동시 실행 수라는 고차원적 목표만 선언하면 인프라가 이를 완수하게 함
상호작용
Job 컨트롤러가 Pod의 상태를 감시하고 성공하지 못하면 새 Pod를 생성함 CronJob 컨트롤러는 시간을 감시하다가 Job객체를 생성함
4. 핵심 동작 시퀀스
1. Input(Desired State)
사용자가 completions(필요 성공 횟수)와 parallelism(동시 실행 수)이 정의된 Job 매니페스트를 제출함
2. Process(Control Loop)
- 관찰 : Job 컨트롤러가 성공적으로 완료된 Pod의 수를 확인
- 비교 : 현재 성공 횟수가 completions 목표치에 도달했는지 확인
- 조정 : 부족한 경우 Pod를 생성하되 현재 실행 중인 Pod 수가 parallelism을 넘지 않도록 제어함
3. Output(Actual State)
작업이 모두 완료되면 Pod는 삭제되지 않고 Completed 상태로 유지되어 로그 확인을 가능하게함
비유
Job은 할당된 업무를 완수할 때까지 퇴근을 불허하는 엄격한 팀장임 직원이 아파서 결근하면(Pod 실패) 팀장은 새 직원을 채용해서라도(Pod 재생성) 반드시 업무 보고서(성공 완료)를 받아내고야 맘
5. 운영 및 안전성 체크포인트
- 성능 영향 요소 : parallelism을 높게 설정하면 작업 속도는 빨라지나 클러스터 자원을 한꺼번에 소모할 수 있음
- 장애 시 현상 :
- restartPolicy : Never인 경우 Pod가 실패하면 컨트롤러가 아예 새로운 Pod를 만들고 OnFailure인 경우 동일한 Pod 내에서 컨테이너만 재시작됨
- 안전 장치 : activeDeadlineSeconds를 설정하면 작업이 무한 루프에 빠져도 지정된 시간 후 강제 종료하고 Job을 실패로 처리함
✅ 체크포인트
필수 키워드
- Job : 유한 작업을 완료까지 관리하는 리소스
- CronJob : Job을 스케줄링하는 상위 객체
- completions : Job이 완료되기 위해 성공해야 하는 Pod 수
- parallelism : 동시에 실행할 수 있는 최대 Pod 수
- restartPolicy : Job에서는 반드시 Onfailure 또는 Never여야함
- Indexed mode : 각 Pod에 0부터 시작하는 고유 인덱스 부여
- JOB_COMPLETION_INDEX : indexed Job에서 Pod에 주입되는 환경 변수
- activeDeadlineSeconds : Job 전체 실행 시간에 대한 타임아웃
- schedule : CronJob에서 사용하는 크론탭 형식의 시간 설정
- suspend : 실행 중이거나 예약된 Job을 일시 정지
혼동 금지
Job vs Deployment
Job은 성공 후 종료가 목표 Deployment는 중단 없는 실행이 목표
Never vs OnFailure
Never는 새 Pod를 만들고 OnFailure는 기존 Pod 내 컨테이너만 다시 띄움
정리
17장은 작업의 완료를 보장하는 Job과 이를 스케줄링하는 CronJob을 통해 배치 및 관리형 유한 워크로드를 자동화하는 방법을 다룸