Skip to main content

Pod & Workload Resources

K8s의 최소 배포 단위 Pod와 이를 관리하는 상위 오브젝트들


1. Pod

1.1 Pod란

Pod는 K8s에서 생성/관리할 수 있는 최소 배포 단위. 하나 이상의 컨테이너를 포함하며, 같은 Pod 내 컨테이너는 네트워크와 스토리지를 공유함.

특성설명
네트워크 공유같은 Pod 내 컨테이너는 localhost로 통신
스토리지 공유Volume을 통해 파일시스템 공유 가능
생명주기Pod 삭제 시 모든 컨테이너가 함께 삭제됨
IPPod 하나에 IP 하나. 내부 컨테이너는 포트로 구분

1.2 Pod 생명주기

stateDiagram-v2
[*] --> Pending: 생성 요청
Pending --> Running: 스케줄링 + 컨테이너 시작
Running --> Succeeded: 정상 종료 (Job)
Running --> Failed: 비정상 종료
Running --> Unknown: 노드 통신 끊김
Succeeded --> [*]
Failed --> [*]
상태의미
Pending스케줄링 대기 또는 이미지 다운로드 중
Running하나 이상의 컨테이너가 실행 중
Succeeded모든 컨테이너 정상 종료 (exitCode 0)
Failed하나 이상의 컨테이너 비정상 종료
Unknown노드와 통신 불가

1.3 Multi-container 패턴

하나의 Pod에 여러 컨테이너를 넣는 패턴. 메인 앱을 보조하는 역할.

패턴역할예시
Sidecar메인 앱을 보조로그 수집기, 프록시 (Istio Envoy)
Ambassador외부 통신을 대리DB 프록시, API Gateway
Adapter출력을 표준 형식으로 변환로그 포맷 변환, 메트릭 변환

1.4 Init Container

메인 컨테이너 이전에 실행되는 초기화 컨테이너. 순차적으로 실행되며, 모든 Init Container가 성공해야 메인 컨테이너가 시작됨.

spec:
initContainers:
- name: wait-for-db
image: busybox
command: ['sh', '-c', 'until nslookup db-service; do sleep 2; done']
containers:
- name: app
image: my-app:v1

활용: DB 준비 대기, 설정 파일 다운로드, 권한 설정, 마이그레이션 실행

1.5 Probe (헬스 체크)

Probe목적실패 시
Liveness컨테이너가 살아있는가재시작
Readiness트래픽을 받을 준비가 되었는가Service에서 제외 (재시작 안 함)
Startup앱이 시작되었는가 (느린 앱용)시작 실패로 판단 → 재시작
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5

Probe 방식: HTTP GET, TCP Socket, gRPC, Exec(명령 실행)

1.6 Pod Disruption Budget (PDB)

자발적 중단(노드 drain, 업그레이드) 시 최소 가용 Pod 수를 보장하는 오브젝트.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
spec:
minAvailable: 2 # 또는 maxUnavailable: 1
selector:
matchLabels:
app: web

2. ReplicaSet

선언된 수만큼 Pod를 유지하는 컨트롤러. 직접 사용하는 경우는 거의 없고 Deployment가 내부적으로 관리함.

spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.25
  • Pod가 죽으면 자동으로 새 Pod 생성 (자가치유)
  • Label Selector로 관리 대상 Pod를 식별

3. Deployment

3.1 가장 많이 사용하는 워크로드

Deployment = ReplicaSet + 롤링 업데이트/롤백 기능.

flowchart TB
Deployment["Deployment<br/>(v2로 업데이트)"]
Deployment --> RS1["ReplicaSet v1<br/>(replicas: 0)"]
Deployment --> RS2["ReplicaSet v2<br/>(replicas: 3)"]
RS1 --> Pod1_old["Pod v1 (삭제됨)"]
RS2 --> Pod1["Pod v2"]
RS2 --> Pod2["Pod v2"]
RS2 --> Pod3["Pod v2"]

3.2 배포 전략

전략동작다운타임
RollingUpdate (기본)새 Pod를 점진적으로 생성하면서 구 Pod를 삭제❌ 없음
Recreate모든 구 Pod를 삭제한 후 새 Pod 생성✅ 있음
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 원하는 수 대비 추가 생성 가능한 Pod 수
maxUnavailable: 0 # 원하는 수 대비 동시에 사용 불가능한 Pod 수

3.3 롤백

# 업데이트 히스토리
kubectl rollout history deployment/web

# 이전 버전으로 롤백
kubectl rollout undo deployment/web

# 특정 리비전으로 롤백
kubectl rollout undo deployment/web --to-revision=2

# 업데이트 상태 확인
kubectl rollout status deployment/web

4. StatefulSet

4.1 상태가 있는 워크로드

DeploymentStatefulSet
Pod 이름랜덤 (web-7d9f8-xk2p)순차적 (db-0, db-1, db-2)
생성/삭제 순서동시순차적 (0→1→2, 삭제는 역순)
네트워크 ID불안정 (재시작 시 변경)안정적 (Headless Service)
스토리지공유 또는 없음Pod별 고유 PVC
용도무상태 앱 (웹 서버, API)상태 앱 (DB, 메시지 큐, ZooKeeper)

4.2 Headless Service

StatefulSet의 각 Pod에 안정적인 DNS 이름을 부여.

apiVersion: v1
kind: Service
metadata:
name: db
spec:
clusterIP: None # Headless
selector:
app: db
ports:
- port: 5432
---
# Pod DNS: db-0.db.default.svc.cluster.local
# db-1.db.default.svc.cluster.local

4.3 volumeClaimTemplates

Pod마다 고유한 PVC를 자동 생성.

volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
# → db-0은 data-db-0 PVC, db-1은 data-db-1 PVC 사용

5. DaemonSet

모든 (또는 특정) 노드에 Pod를 하나씩 배포.

활용예시
로그 수집Fluentd, Filebeat
모니터링node-exporter, Datadog Agent
네트워크CNI 플러그인 (Calico, Cilium)
스토리지CSI 노드 플러그인
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
spec:
selector:
matchLabels:
app: node-exporter
template:
spec:
containers:
- name: node-exporter
image: prom/node-exporter:latest

노드가 추가되면 자동으로 Pod가 생성되고, 노드가 제거되면 Pod도 삭제됨.


6. Job & CronJob

6.1 Job — 일회성 작업

apiVersion: batch/v1
kind: Job
metadata:
name: db-backup
spec:
completions: 1 # 성공해야 하는 Pod 수
backoffLimit: 3 # 재시도 횟수
template:
spec:
containers:
- name: backup
image: postgres:16
command: ["pg_dump", "-h", "db", "-U", "admin", "-d", "mydb"]
restartPolicy: Never

6.2 CronJob — 주기적 작업

apiVersion: batch/v1
kind: CronJob
metadata:
name: db-backup-cron
spec:
schedule: "0 2 * * *" # 매일 02:00
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: postgres:16
command: ["pg_dump", "..."]
restartPolicy: Never

7. 워크로드 선택 가이드

flowchart TD
Start["어떤 워크로드?"]
Start -->|"무상태 앱<br/>(웹, API)"| Deployment["Deployment"]
Start -->|"상태 앱<br/>(DB, 큐)"| StatefulSet["StatefulSet"]
Start -->|"모든 노드에<br/>하나씩"| DaemonSet["DaemonSet"]
Start -->|"일회성 작업"| Job["Job"]
Start -->|"주기적 작업"| CronJob["CronJob"]

다음 글

→ #4 Service & Networking — ClusterIP, NodePort, Ingress, CNI, NetworkPolicy


📝 참고 자료