스테이트풀셋
주요 용도
안정된 프레임워크에서 동작하는 애플리케이션에 스케일링 기능을 제공하는 파드 컨트롤러.
주로 데이터베이스, 메시지 큐, 로그 처리 시스템 등 상태 정보를 유지해야 하는 애플리케이션에 사용
특징
- 고유한 네트워크 ID: 스테이트풀셋에서 생성되는 각 파드는 규칙적인 이름과 고유한 네트워크 ID(도메인 네임)를 가진다. 예를 들어, 파드 이름이 statefulset-0, statefulset-1, statefulset-2와 같이 부여된다.
- 순차적 생성 및 종료: 파드는 순서대로 생성되고 종료된다. 첫 번째 파드가 Running 상태가 되면 그 다음 파드가 생성되는 식으로 동작다.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: example-statefulset
spec:
serviceName: "example"
replicas: 3
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example
spec:
containers:
- name: example
image: example-image
ports:
- containerPort: 80
volumeClaimTemplates:
- metadata:
name: example-storage
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
스테이트풀셋에서 초기화 컨테이너 활용
스테이트풀셋에서 초기화 컨테이너(Init Containers)는 파드가 시작되기 전에 실행되어 필요한 초기화 작업을 수행한다. 이는 데이터베이스 스키마 설정, 초기 데이터 로드 등과 같은 작업을 포함할 수 있다. 만약 이 초기화 작업이 StatefulSet의 다른 파드와 통신해야 한다면, 헤드리스 서비스가 필요하다. 헤드리스 서비스를 사용하면 초기화 컨테이너가 특정 파드에 직접 접근할 수 있습니다. 헤드리스는 실제 주소와 연결된 IP주소가 없는 대신 스테이트풀셋 안에 있는 각 파드의 IP주소가 반환되기 때문이다.
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app: myapp
spec:
clusterIP: None
selector:
app: myapp
ports:
- port: 80
name: http
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-statefulset
spec:
serviceName: "my-service"
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
initContainers:
- name: init-myservice
image: busybox
command: ['sh', '-c', 'echo Initializing...; sleep 5']
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 80
volumeMounts:
- name: my-storage
mountPath: /data
volumeClaimTemplates:
- metadata:
name: my-storage
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
위의 예시에서, my-service는 헤드리스 서비스로 설정되었고 my-statefulset의 각 파드는 my-service를 포함한 고유한 네트워크 ID를 갖게 된다(todo-db-0.my-service.default.svc.cluster.local). 초기화 컨테이너는 필요에 따라 이 네트워크 ID를 사용하여 특정 파드에 접근할 수 있습니다.
볼륨 클레임 템플릿으로 스토리지 요청
각 파드의 영구볼륨클레임마다 별도의 스토리지가 마운트되게 하기위해 volumeClaimTemplates 필드를 기술해야함
볼륨 클레임 템플릿을 포함한 스테이트풀셋을 배치하면 각 파드마다 영구볼륨 클레임이 생성되며 파드와 영구볼륨클레임이 연결됨. 예를 들어 파드 0이 대체되었다면 새로운 파드 0에도 기존 영구볼륨클레임이 사용됨
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: example-statefulset
spec:
serviceName: "example"
replicas: 3
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example
spec:
containers:
- name: example
image: example-image
ports:
- containerPort: 80
volumeMounts:
- name: example-storage
mountPath: /data
volumeClaimTemplates:
- metadata:
name: example-storage
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
주의점
스테이트풀셋은 애플리케이션에 안정적인 환경을 제공하는 것이 목적인 리소스라 업데이트에 있어서는 유연성이 다소 떨어짐.
볼륨 클레임을 추가하는 등의 변경이 있으면 기존 스테이트풀셋을 업데이트할 수 없음(경고 발생함)
예시) 기존 정의
... 생략 ...
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
여기서 아래처럼 스토리지 크기를 변경한다.
... 생략 ...
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 2Gi # 변경 시도: 스토리지 크기 변경
이제 다시 이 yaml파일을 통해 스테이트풀셋을 배포하면 아래와 같은 경고가 뜸
The StatefulSet "web" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden
그래서 이런 변경이 필요하다면 먼저 기존 스테이트풀셋을 삭제하고 다시 새로운 스테이트풀셋을 생성해야함
kubectl delete statefulset web --cascade=orphan // 기존꺼 삭제
kubectl apply -f new-statefulset.yaml // 다시 새로운거 생성
댓글