🗣️ Statefulset이 사용되는 이유
웹, WAS등의 서비스들은 무상태(Stateless)의 서비스이다.
하나의 PV를 여럿이서 공유한다.
그러고 보통 공통으로 읽기만 하면 된다.
(Deployment는 RWO를 거의 쓰지 않는다. 대신, ROX, RWX등이 지원되는 파일 스토리지를 많이 사용한다.)
그러나, 데이터베이스, 메시지 브로커 등은 각각의 PV를 가질 필요가 있다.
이렇게 되면, 각 Pod가 동일하지는 않다.
즉, Stateful하다.
보통 분산 데이터베이스를 위해 사용되는 경우가 대부분 이다.
💜 StatefulSet

StatefulSet의 Pod들은 동일한 컨테이너 스펙을 가진다.
그러나, 각 Pod는 고유한 ID를 항상 가진다. 상태를 가지고, 각각의 PVC로 각각의 PV에 접근 해야 하기 때문이다.
StatefulSet의 생성은 항상 작은 번호부터 순차적으로 생긴다.
이렇게 되면, Pod - PVC - PV의 매칭에 편리하다.
롤링 업데이트 및 제거될 때에는 거꾸로 제거된다.
분산 시스템의 경우, 보통 Write가 이루어지는 Master가 0번과 같이 낮은 번호를 가지는데, 낮은 번호부터 제거되면 새로운 대표자 선출이 계속되어 비효율적이기 때문이다.
대신, 높은 숫자부터 제거하면, 새로운 대표자 선출이 최소화 될 수 있어 더 성능에 좋다.
만약 Pod가 죽고 재생성되면 어떻게 될까?
동일한 Pod의 ID로 생성되기에, 이전에 생성된 PVC-PV와 다시 매칭 될 수 있다.
🏋️ StatefulSet 연습
StatefulSet 생성
nginx-sts.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: gp2
resources:
requests:
storage: 1Gi
|
Headless Service 생성
headless-nginx.yaml
1
2
3
4
5
6
7
8
9
10
11
|
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
clusterIP: None
selector:
app: nginx
ports:
- port: 80
targetPort: 80
|
데이터 지속성 확인
각자 다른 페이지를 생성해주자.
1
2
3
4
5
6
7
|
kubectl exec web-0 -- sh -c "echo 'Data from web-0 at $(date)' > /usr/share/nginx/html/index.html"
kubectl exec web-1 -- sh -c "echo 'Data from web-1 at $(date)' > /usr/share/nginx/html/index.html"
kubectl exec web-2 -- sh -c "echo 'Data from web-2 at $(date)' > /usr/share/nginx/html/index.html"
kubectl exec web-0 -- cat /usr/share/nginx/html/index.html
kubectl exec web-1 -- cat /usr/share/nginx/html/index.html
kubectl exec web-2 -- cat /usr/share/nginx/html/index.html
|
0번 파드를 제거해보자.
1
|
kubectl delete po web-0
|
이후, 다시 데이터를 확인해보자:
1
|
kubectl exec web-0 -- cat /usr/share/nginx/html/index.html
|
📚 마무리
StatefulSet은 상태를 가진 Pod들을 관리하는 데 쓰이는 Stateful Deployment라고 할 수 있다.
보통 PV와 함께 쓰인다.
- Deployment와는 달리, 작은번호부터 순차적으로 생성된다.
- 롤링 업데이트 및 삭제 시에는 마스터를 최대한 늦게 죽이기 위해, 큰 번호부터 제거된다.
- Pod가 고정된 고유번호화 함께 PVC-PV와 바인딩되기에, 죽고 다시 깨어나도 동일한 고유의 PV에 연결될 수 있고, 이름도 고유하며 재사용된다.