KR_CS_StatefulSet - somaz94/DevOps-Engineer GitHub Wiki

Q6: StatefulSetκ³Ό Stateless μ• ν”Œλ¦¬μΌ€μ΄μ…˜

질문: StatefulSetκ³Ό Stateless μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 차이λ₯Ό μ„€λͺ…ν•˜κ³ , Kubernetesμ—μ„œ 각각의 배포 방법과 μŠ€μΌ€μΌλ§ μ „λž΅μ„ μ„€λͺ…ν•˜μ„Έμš”. Persistent Volume, Headless Service, Pod Identity의 역할을 μ€‘μ‹¬μœΌλ‘œ μ„€λͺ…ν•˜μ„Έμš”.


μ£Όμš” μš©μ–΄

μš©μ–΄ μ„€λͺ…
StatefulSet μƒνƒœλ₯Ό κ°€μ§„ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ΄€λ¦¬ν•˜λŠ” K8s 였브젝트
Stateless Application λ‚΄λΆ€ μƒνƒœλ₯Ό μœ μ§€ν•˜μ§€ μ•Šκ³  각 μš”μ²­μ„ 독립 μ²˜λ¦¬ν•˜λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜
Headless Service ClusterIPκ°€ None인 μ„œλΉ„μŠ€ β€” Pod IPλ₯Ό 직접 λ°˜ν™˜
Ordinal Index StatefulSet Pod의 μˆœμ„œ 번호 (pod-0, pod-1, pod-2)
PVC (PersistentVolumeClaim) Podκ°€ PVλ₯Ό μš”μ²­ν•˜λŠ” 였브젝트
volumeClaimTemplates StatefulSetμ—μ„œ 각 Podλ§ˆλ‹€ PVCλ₯Ό μžλ™ μƒμ„±ν•˜λŠ” ν…œν”Œλ¦Ώ

Stateless vs Stateful κ°œλ…

Stateless (Deployment):               Stateful (StatefulSet):
β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚Pod A β”‚ β”‚Pod B β”‚ β”‚Pod C β”‚           β”‚ mysql-0  β”‚ β”‚ mysql-1  β”‚ β”‚ mysql-2  β”‚
β”‚      β”‚ β”‚      β”‚ β”‚      β”‚           β”‚ (Master) β”‚ β”‚ (Slave)  β”‚ β”‚ (Slave)  β”‚
β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜           β”‚  PV-0    β”‚ β”‚  PV-1    β”‚ β”‚  PV-2    β”‚
         ↓                           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  Shared Database                         └─────── Replication β”€β”€β”€β”€β”€β”€β”˜
  (External State)

Stateless vs Stateful 비ꡐ

ν•­λͺ© Stateless (Deployment) Stateful (StatefulSet)
Pod 이름 랜덀 (nginx-abc123) μˆœμ„œ 번호 (mysql-0, mysql-1)
생성 μˆœμ„œ λ™μ‹œ 생성 κ°€λŠ₯ 순차 생성 (0 β†’ 1 β†’ 2)
μ‚­μ œ μˆœμ„œ λ™μ‹œ μ‚­μ œ κ°€λŠ₯ μ—­μˆœ μ‚­μ œ (2 β†’ 1 β†’ 0)
Network Identity λΆˆμ•ˆμ • (Pod IP λ³€κ²½) μ•ˆμ •μ  (DNS μœ μ§€)
Storage 곡유 λ˜λŠ” μ—†μŒ 각 Podλ§ˆλ‹€ PVC
Service Type ClusterIP / LoadBalancer Headless + ClusterIP
μ‚¬μš© 사둀 μ›Ή μ„œλ²„, API μ„œλ²„ DB, λ©”μ‹œμ§•, λΆ„μ‚° μŠ€ν† λ¦¬μ§€

Kubernetes Deployment (Stateless)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

Rolling Update:

  • maxSurge: 1 β†’ μ΅œλŒ€ replica+1κ°œκΉŒμ§€ λ™μ‹œ μ‹€ν–‰ ν—ˆμš©
  • maxUnavailable: 0 β†’ 항상 replica 수 μœ μ§€ (무쀑단)

Kubernetes StatefulSet (Stateful)

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql-headless   # Headless Service ν•„μˆ˜
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
  volumeClaimTemplates:          # Podλ§ˆλ‹€ PVC μžλ™ 생성
  - metadata:
      name: mysql-data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: gp3
      resources:
        requests:
          storage: 10Gi

Headless Service

clusterIP: None 으둜 μ„€μ •ν•˜λ©΄ VIP 없이 Pod IPλ₯Ό 직접 λ°˜ν™˜.

apiVersion: v1
kind: Service
metadata:
  name: mysql-headless
spec:
  clusterIP: None
  selector:
    app: mysql
  ports:
  - port: 3306

DNS 쑰회 결과:

mysql-headless β†’ 10.244.1.10 (mysql-0)
              β†’ 10.244.2.20 (mysql-1)
              β†’ 10.244.3.30 (mysql-2)

κ°œλ³„ Pod DNS:
mysql-0.mysql-headless.default.svc.cluster.local β†’ 10.244.1.10
mysql-1.mysql-headless.default.svc.cluster.local β†’ 10.244.2.20

Pod μž¬μ‹œμž‘ 후에도 DNS 이름 μœ μ§€ β†’ Master/Slave 직접 μ§€μ • κ°€λŠ₯.


Persistent Volume 관리

  • StatefulSet μ‚­μ œ μ‹œ PVCλŠ” μ‚­μ œλ˜μ§€ μ•ŠμŒ (데이터 보쑴)
  • Pod μž¬μƒμ„± μ‹œ κΈ°μ‘΄ PVC μž¬μ‚¬μš©
  • PVC μˆ˜λ™ μ‚­μ œ ν•„μš”: kubectl delete pvc mysql-data-mysql-0

λ³Όλ₯¨ ν™•μž₯ (StorageClassμ—μ„œ allowVolumeExpansion: true ν•„μš”):

kubectl patch pvc mysql-data-mysql-0 \
  -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'

Update Strategy

μ „λž΅ λ™μž‘
RollingUpdate (κΈ°λ³Έ) μ—­μˆœμœΌλ‘œ 순차 μ—…λ°μ΄νŠΈ (mysql-2 β†’ mysql-1 β†’ mysql-0)
OnDelete μžλ™ μ—…λ°μ΄νŠΈ μ—†μŒ, Pod μˆ˜λ™ μ‚­μ œ μ‹œ μƒˆ λ²„μ „μœΌλ‘œ μž¬μƒμ„±
Parallel λͺ¨λ“  Pod λ™μ‹œ 생성/μ‚­μ œ (μˆœμ„œ 보μž₯ λΆˆν•„μš”ν•œ 경우)

μ°Έκ³ 

⚠️ **GitHub.com Fallback** ⚠️