[MacOS 환경 #7] 쿠버네티스 StatefulSet 개념 + 실습 정리

도람·2025년 11월 12일
post-thumbnail

StatefulSet

StatefulSet은 말 그대로

“상태(State)를 가진 파드를 순서대로 생성·유지하는 컨트롤러”이다.

Deployment는 파드를 아무 순서나 생성·삭제하지만,
StatefulSet은 순서를 엄격히 지킨다.

예를 들어,

  • 생성 순서 → pod-0 → pod-1 → pod-2
  • 삭제 순서 → pod-2 → pod-1 → pod-0
  • 각각 고유즉, DB나 캐시처럼 데이터 보존이 중요한 서비스에 쓰인다.한 이름(myapp-0, myapp-1)과 고유한 스토리지(PVC)를 가진다.

즉, DB나 캐시처럼 데이터 보존이 중요한 서비스에 쓰인다.
ex)MySQL, Redis, Kafka, ZooKeeper 등


apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "web"
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: nginx
        ports:
        - containerPort: 80
          name: web

이건 간단히 Nginx 파드 3개를 순서대로 만드는 StatefulSet 예시다.


실행 흐름

동작설명
생성 순서web-0 → web-1 → web-2
삭제 순서web-2 → web-1 → web-0
각 파드고유한 이름과 PVC를 가짐
사용 사례MySQL, Redis, Kafka, ZooKeeper 등

실습

StatefulSet은 Headless Service와 함께 동작해야 한다.
즉, 두 개의 YAML 파일이 필요하다.


1. Headless Service 생성(statefulset-svc.yaml)

StatefulSet 파드들이 DNS 이름으로 서로 통신할 수 있게 해주는 서비스다.

vim statefulset-svc.yaml 

하고 밑에 있는 스크립트를 복사붙여넣기 한다.

apiVersion: v1
kind: Service
metadata:
  name: web
  labels:
    app: web
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None     #Headless Service (ClusterIP 없음)
  selector:
    app: web

2. StatefulSet (statefulset.yaml) 생성

StatefulSet이 순서대로 파드를 생성하고, 각 파드마다 고유한 이름을 부여한다.

vim statefulset.yaml

하고 밑에 있는 스크립트를 복사붙여넣기 한다.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "web"
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
  volumeClaimTemplates:
  - metadata:
      name: web-storage
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: hostpath
      resources:
        requests:
          storage: 1Gi

clusterIP: None 으로 지정하면, 파드별로 web-0.web, web-1.web 같은 고유 DNS 이름이 생성된다.


## 3. PV 생성 (pv.yaml) StatefulSet이 사용할 실제 물리 저장소를 정의한다.
vim pv.yaml

으로 파일을 밑에 있는 스크립트로 복붙해준다.

apiVersion: v1
kind: List
items:
- apiVersion: v1
  kind: PersistentVolume
  metadata:
    name: web-pv-0
  spec:
    capacity:
      storage: 1Gi
    accessModes:
      - ReadWriteOnce
    persistentVolumeReclaimPolicy: Delete
    hostPath:
      path: /data/web-storage-0
    storageClassName: hostpath

- apiVersion: v1
  kind: PersistentVolume
  metadata:
    name: web-pv-1
  spec:
    capacity:
      storage: 1Gi
    accessModes:
      - ReadWriteOnce
    persistentVolumeReclaimPolicy: Delete
    hostPath:
      path: /data/web-storage-1
    storageClassName: hostpath

- apiVersion: v1
  kind: PersistentVolume
  metadata:
    name: web-pv-2
  spec:
    capacity:
      storage: 1Gi
    accessModes:
      - ReadWriteOnce
    persistentVolumeReclaimPolicy: Delete
    hostPath:
      path: /data/web-storage-2
    storageClassName: hostpath
kubectl apply -f pv.yaml
kubectl get pv
kubectl get pvc

STATUS가 Bound로 바뀌면 PVC와 PV가 연결된 것이다.


4. Headless Service와 StatefulSet 생성

kubectl apply -f statefulset-svc.yaml
kubectl apply -f statefulset.yaml

kubectl apply -f statefulset-svc.yaml


하여 Headless Service를 생성한다.


kubectl apply -f statefulset.yaml


하여 StatefulSet를 생성한다.


5. 파드 순서대로 생성 확인

kubectl get pods -o wide
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          1m
web-1   1/1     Running   0          40s
web-2   1/1     Running   0          15s

→ 순서대로 web-0, web-1, web-2가 생성된 것을 확인할 수 있다.

이 명령어를 실행하여 파드가 순서대로 생성되었는지 확인할 수 있다.
이렇게 0부터 1 순서대로 생성되는 것을 확인할 수 있다.


6. 생성한 거 삭제하기

아래 순서대로 삭제하면 모든 관련 리소스를 안전하게 제거할 수 있다.

# StatefulSet 삭제
kubectl delete -f statefulset.yaml

# Headless Service 삭제
kubectl delete -f statefulset-svc.yaml

# PVC(파드별 스토리지 요청) 삭제
kubectl delete pvc --all

# PV(실제 물리 볼륨) 삭제
kubectl delete pv --all

저작권 문제를 방지하기 위해 공식 문서 내용을 참고하였으며, 일부 설명은 ChatGPT를 활용해 재구성하였습니다.
본 포스트는 학습용 예시로 작성되었습니다.

profile
정도를 걷는 엔지니어

0개의 댓글