상태 유지가 필요한 데이터베이스, 분산 시스템과 같은 Application을 관리하는데 사용되는 오브젝트다. 고유한 네트워크 식별자를 제공하고, 스토리지의 데이터를 영구적으로 사용 가능하도록 기능을 지원한다.
StatefulSet 기본 개요
- 고유한 네트워크 식별자가 필요하거나 스토리지를 지속적으로 적용해서 사용하고자 할 때 적합하다.
- 파드에는 고유한 id 값이 할당되기 때문에 파드가 재실행되더라도 동일한 PV 마운트가 가능하다.
- Deployment에서 PVC를 사용하면 동일한 PV가 마운트 되고, StatefulSet은 파드별로 PVC 생성 후 볼륨이 할당된다.
- Deployment는 파드를 최적의 워커 노드에 배치하려는 특성이 있지만 StatefulSet은 최대한 동일 노드에 배치한다.
StatefulSet 주의사항
- 고유한 식별자, 순차적인 배포, 스케일링 기능이 필요하지 않을 시 deployment 가 더 적합할 수 있다.
- 파드의 스토리지는 Storage Class를 이용해서 동적으로 할당되거나 사전에 프로비전된 PV를 사용해야 한다.
- 워커 노드에서 리소스 부족으로 타 워커 노드에 배치되는 경우 기존 워커 노드의 PV를 마운트 시도하면서 파드 생성에 실패한다.
- nodeSelector로 워커 노드 위치를 지정하면 워커 노드 장애시 정상화 될 때까지 파드는 보류 상태가 되며 가용성을 해친다.
- Network File System과 동적 볼륨 프로비저닝을 결합해 파드가 어떤 노드에서 실행되어도 데이터 접근이 가능하게 할 수 있다.
- 다만, NFS를 사용 시 고가용성은 문제가 해결되만 Block Storage 대비 성능적으로 이슈가 발생할 수도 있다.
Database 구성 YAML Sample
데이터베이스 패스워드, DB 정보 등을 동일하게 각 파드에 설정하기 위해 ConfigMap, Secret 오브젝트를 같이 생성한다. 데이터를 유지하기 위해 Persistant Volume Claim Template을 추가로 설정한다.
- StatefulSet YAML Sample
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
labels:
app: postgres-sts
spec:
replicas: 2
selector:
matchLabels:
app: postgres
serviceName: "postgres-pod"
template:
metadata:
labels:
app: postgres
spec:
# terminationGracePeriodSeconds: 10
containers:
- name: postgres-container
image: postgres:latest
ports:
- containerPort: 5432
name: postgres
protocol: TCP
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: secret-postgres
key: DB_PASSWORD
- name: POSTGRES_DB
valueFrom:
configMapKeyRef:
name: config-postgres
key: DB_SCHEMA
volumeMounts:
- name: postgres-volume
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: postgres-volume
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: standard
resources:
requests:
storage: 1Gi
- ConfigMap / Secret 오브젝트 YAML Sample
apiVersion: v1
kind: ConfigMap
metadata:
name: config-postgres
data:
DB_SCHEMA: demo
---
apiVersion: v1
kind: Secret
metadata:
name: secret-postgres
type: Opaque
data:
DB_PASSWORD: cXdlcjEyMzQ= # CMD: echo -n "qwer1234" | base64
StorageClass YAML Sample
간단하게 로컬 환경에서 테스트 하는 경우 openebs를 설치한 다음 provisioner를 설정해야 한다. kubernetes.io/local 를 적용하게 되면 local 타입의 Storage는 동적 할당을 지원하지 않기 때문에 openebs를 사용해야 한다.
- openebs 설치
kubectl apply -f https://openebs.github.io/charts/openebs-operator.yaml
- StorageClass YAML Sample
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
annotations:
storageclass.kubernetes.io/is-default-class: "true" # default class로 지정
provisioner: openebs.io/local # openebs 적용
reclaimPolicy: Retain # revision 할 경우 기존의 pod retain/delete(default) 중 선택
volumeBindingMode: WaitForFirstConsumer # pod가 스케줄링 될 때까지 지연 후 바인딩 시작
배포 후 설정 결과 확인
- StatefulSet, StorageClass 배포
k apply -f storage-class-sample.yaml
k apply -f stateful-set-sample.yaml
- 마운트 결과 확인
k exec -it postgres-0 -- bash -c "cat /proc/mounts" | grep postgresql
/dev/root /var/lib/postgresql/data ext4 rw,relatime,discard,errors=remount-ro,commit=30 0 0
데이터 상태 유지 테스트
- 테스트 데이터 입력
k exec -it postgres-0 -- bash -c "echo 123456789 > /var/lib/postgresql/data/sample.txt"
- 샘플 데이터 확인
k exec -it postgres-0 -- bash -c "cat /var/lib/postgresql/data/sample.txt"
123456789
- statefulset pod의 worker 노드 위치 확인
k get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
postgres-0 1/1 Running 0 45m 10.233.125.59 worker2 <none> <none>
postgres-1 1/1 Running 0 50m 10.233.105.183 worker1 <none> <none>
- pod 삭제
k delete po postgres-0
pod "postgres-0" deleted
- 동일한 worker node에 pod가 배치 되는지 확인
k get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql-0 1/1 Running 0 27s 10.233.125.55 worker2 <none> <none>
mysql-1 1/1 Running 0 7m22s 10.233.105.180 worker1 <none> <none>
- 샘플 데이터 확인
k exec -it postgres-0 -- bash -c "cat /var/lib/postgresql/data/sample.txt"
123456789
데이터베이스 접속 설정
- 포드 포워딩 설정
# master 1 서버에서 진행
k port-forward --address 0.0.0.0 pod/postgres-0 5432:5432 &
k port-forward --address 0.0.0.0 pod/postgres-1 5433:5432 &
- JumpHost 서버에서 postgres-0 접속 테스트
psql -h 10.0.40.62 -p 5432 -U postgres
- JumpHost 서버에서 postgres-1 접속 테스트
psql -h 10.0.40.62 -p 5433 -U postgres
- 생성한 Database Schema 확인
SELECT datname FROM pg_database;
postgres
demo
template1
template0
'Infrastructure & Systems > Kubernetes' 카테고리의 다른 글
[Kubernetes] Secret 이용 Private Registry 인증정보 설정 (0) | 2025.04.02 |
---|---|
[Kubernetes] Kubespray로 k8s 설치 (0) | 2025.03.31 |
[Kubernetes] DaemonSet YAML Sample (0) | 2025.03.24 |
[Kubernetes] Deployments YAML Sample (0) | 2025.03.24 |
[Kubernetes] Multi-Cluster 환경에서 kubectl (0) | 2024.11.29 |