상태 있는 애플리케이션을 위한 워크로드.
- 이름 — web-0 · web-1 · web-2 — 순서가 있고 재생성돼도 같은 이름
- 순서 — 0 → 1 → 2 순으로 만들고, 역순으로 지운다
- 볼륨 — volumeClaimTemplates 로 파드마다 전용 PVC 를 만든다
- 파드가 재생성돼도 같은 볼륨에 다시 붙는다
- 네트워크 — 헤드리스 서비스와 함께 쓰면 web-0.svc 로 개별 접근이 가능하다
Deployment 와 무엇이 다른가
-
Deployment — 파드가 서로 '대체 가능' 하다는 전제
- 이름이 무작위고 순서가 없다
- 모두 같은 PVC 를 쓰거나 볼륨이 없다
-
StatefulSet — 파드가 '개체' 다
- 클러스터 멤버가 서로를 이름으로 식별해야 하는 것들에 쓴다
- DB 복제 세트 · Kafka · ZooKeeper · Elasticsearch
헤드리스 서비스가 짝이다
apiVersion: v1
kind: Service
metadata:
name: web
spec:
clusterIP: None # 헤드리스
selector: { app: web }
ports: [{ port: 80 }]
보통 서비스는 파드 여러 개를 묶어 대표 주소 하나를 주고, 요청이 오면 그중 아무거나 골라 보낸다. 그런데 DB 복제 세트 같은 것은 "아무나" 가 아니라 "0번한테" 보내야 한다. 리더가 0번이면 쓰기는 0번으로 가야 하기 때문이다.
clusterIP: None(헤드리스)으로 두면 대표 주소를 만들지 않고, DNS 가 파드 주소를 그대로 알려 준다. 그래서 파드마다 고유한 이름이 생긴다.
web-0.web.default.svc.cluster.local
│ │ │
│ │ └ 네임스페이스
│ └ 헤드리스 서비스 이름
└ 파드 이름 — 이 주소로 부르면 '그 파드' 에만 간다
이 덕분에 클러스터 멤버가 서로를 이름으로 지목해 부를 수 있다. 카프카 브로커가 다른 브로커를 찾거나 복제본이 리더에게 붙는 일이 전부 이 주소로 이뤄진다.
마지막으로 배선이 하나 필요하다. StatefulSet 의 serviceName 필드에 이 헤드리스 서비스 이름을 적어야 위 DNS 이름들이 실제로 만들어진다. 빠뜨리면 파드는 뜨는데 서로를 못 찾는다.
PVC 가 남는다
StatefulSet 을 지워도 PVC 는 남는다 (의도된 동작이다)
- 데이터를 지키기 위해서다
- 다시 만들면 같은 볼륨에 붙는다
- 정리를 잊으면 볼륨이 계속 쌓인다
replicas 를 줄여도 그 파드의 PVC 는 남는다
- 다시 늘리면 옛 데이터가 그대로 붙는다 (대개 원하는 동작이다)
운영에서 주의할 것
- 순차 생성이라 파드 하나가 Ready 가 안 되면 다음이 안 뜬다
- 기동이 느린 애플리케이션은 전체 배포가 매우 길어진다
- podManagementPolicy: Parallel 로 동시 생성할 수도 있다
- 롤링 업데이트도 역순으로 하나씩 (N-1 → 0)
- partition 을 두면 일부만 먼저 올릴 수 있다 (카나리)
- force delete 를 쓰면 같은 이름의 파드가 두 개 도는 상태가 생길 수 있다
- 볼륨 손상으로 이어진다. 마지막 수단으로만
정말 StatefulSet 이 필요한가
-
필요하다 — 멤버가 서로를 이름으로 식별해야 한다 (DB 복제 · Kafka)
- 파드마다 다른 데이터를 가져야 한다
- 시작·종료 순서가 의미를 갖는다
-
필요 없다 — 데이터를 외부 스토리지(RDS · S3)에 둔다
- Deployment 로 충분하다
- 세션을 Redis 에 둔다 → 상태가 파드에 없다
가능하면 상태를 클러스터 밖으로 빼는 편이 운영이 훨씬 쉽다 쿠버네티스에서 DB 를 직접 돌리는 것은 그럴 이유가 분명할 때만
업데이트 전략
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 2 # 인덱스 2 이상만 업데이트
partition 을 두면 일부만 먼저 올릴 수 있다 (카나리)
- replicas 5, partition 4 → web-4 만 새 버전
- 확인 후 partition 을 낮춰 가며 전체로 확대
역순(N-1 → 0)으로 진행되므로 partition 이 '이상' 을 뜻한다
면접 함정
- ❌ "상태가 있으면 무조건 StatefulSet" → 외부 스토리지를 쓰면 Deployment로도 된다.
- ❌ "StatefulSet을 지우면 데이터도 지워진다" → PVC는 남는다.