데이터베이스와 같이 stateful 한 워크로드를 위한 리소스이다. 데이터를 영구적으로 저장하기 위해 사용한다.
1. 스테이트풀셋 생성
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sample-statefulset
spec:
serviceName: sample-statefulset
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.16
ports:
- containerPort: 80
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1G
위 내용으로 스테이트풀셋을 생성하고, 아래 커맨드로 파드명 규칙을 확인해보면, 레플리카셋이나 데몬셋과는 다르게 파드명 suffix 로 incremental index 가 붙는것을 알 수 있다.
$ kubectl get pods -o wide -l app=sample-app
매니페스트에서 주요하게 보아야 할 내용은 아래와 같다.
- spec.template.spec.containers[].volumeMounts[]: 컨테이너에서 사용할 볼륨명과 마운트 경로
- spec.volumeClaimTemplates[]: 스테이트풀셋이 생성할 영구 볼륨 요청 템플릿
즉, 스테이트풀셋이 volumeClaimTemplates 에 정의된 볼륨 리소스를 생성하여 영구 볼륨을 확보하고, 이를 컨테이너에서 요청하는 것이다. 생성된 persistentvolumes 과 persistentvolumeclaims 는 다음 커맨드로 확인할 수 있다.
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pvc-66206fda-ac99-4923-9b7c-eff0e3a3f677 1G RWO Delete Bound default/www-sample-statefulset-0 standard <unset> 22m
pvc-922ab66a-e5cc-447c-99d6-99d2f476345e 1G RWO Delete Bound default/www-sample-statefulset-1 standard <unset> 22m
pvc-9ecd3989-6435-4cbc-9e94-146866a59ddf 1G RWO Delete Bound default/www-sample-statefulset-2 standard <unset> 22m
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
www-sample-statefulset-0 Bound pvc-66206fda-ac99-4923-9b7c-eff0e3a3f677 1G RWO standard <unset> 25m
www-sample-statefulset-1 Bound pvc-922ab66a-e5cc-447c-99d6-99d2f476345e 1G RWO standard <unset> 22m
www-sample-statefulset-2 Bound pvc-9ecd3989-6435-4cbc-9e94-146866a59ddf 1G RWO standard <unset> 22m
PV(persistentvolumes)와 PVC(persistentvolumeclaims) 에 대한 내용은 추후에 영구 볼륨을 따로 다룰 때 자세히 설명하고, 여기서는 간단히 정리하면 다음과 같다.
- PV: 물리적인 스토리지. namespaced: false. 즉, cluster 전역 스토리지
- PVC: 물리적인 스토리지를 namespace 에서 사용하기 위한 객체. namespaced: true
- PVC 에서 PV 의 사용을 요청하기 위해서는 PVC 와 PV 의 아래 조건이 맞아야 한다.(바인딩 조건)
- PVC 에 selector 가 설정되어 있으면 PV 중에서 selector 에 일치하는 key=value 를 찾는다.(optional)
- spec.accessModes 가 일치하여야 한다.
- PV 의 spec.capacity.storage 용량이 PVC spec.resources.request.storage 용량 이상이어야 한다.
- PV 와 PVC 둘 다 storageClassName 이 명시되어 있으면 그 값이 일치하여야 한다.(둘 다 명시되어있지 않으면 빈문자열로 취급되어 일치함. 한쪽만 명시되면 불일치함)
- PVC 는 파드에 설정되고, 파드는 PVC 를 통해서 PV 를 인식하고 사용한다.
- PVC 한개가 여러개의 PV 에 바인딩 될 수는 없다.
- 한번 바인딩이 되었다가 풀리면 PV 가 released 상태가 되며, 바인딩 되었던 PVC 에서는 다시 바인딩이 불가능하기 때문에, PV 를 삭제 후 다시 생성해야 한다. PV 를 조건에 맞게 생성하면 자동으로 바인딩이 이루어진다.
2. 스테이트풀셋 스케일링의 특이점
레플리카셋이나 데몬셋은 scale out 또는 scale in 시에 생성/삭제되는 파드가 무작위이지만, 스테이트풀셋은 아래와 같은 규칙이 있다.
- scale out: pod 명 suffix index 가 1씩 증분하면서 생성되며, 하나의 파드가 생성 후 ready 상태가 되면 다음 파드가 생성된다.
- scale in: pod 명의 suffix 가 큰 것부터 하나씩 삭제된다. 삭제될 때도 하나씩 순차적으로 삭제된다.
이러한 특징 때문에 0번째 파드가 항상 가장 오래 남아있게 되는데, 그 특징으로 0번째 파드를 마스터로 사용하는 이중화 애플리케이션에 적합하다.
3. 파드 관리 정책
위에서 스테이트풀셋의 파드는 생성/삭제시 순차적으로 진행된다고 하였는데, 이를 변경하는 파라미터가 있다. spec.podManagementPolicy 필드로, 기본값이 OrderedReady 이고, 이를 Parallel 로 설정하면 레플리카셋과 동일하게 파드 생성/삭제가 병렬로 이루어진다.