Kubernetes

StatefulSet

Operation CWAL 2021. 1. 25. 23:36

redis, mysql과 같이 상태를 유지해야하는(Stateful) 어플리케이션은 자신만의 Persistent Volume을 요구한다. 또한 자체적인 고가용성(High Availability)를 위해 Main&Backup 또는 Read Replicas로 구성하는 것이 일반적이다.

 

출처: redislabs.com

 

Deployment의 경우 모든 Pod이 동등하며 랜덤하게 관리되므로, 특정 Pod을 Master 또는 Slave로 지칭하거나, 우선순위를 부여할 수 없다. 또한 Service를 통해 접근시 Load Balancing이 발생하기 때문에 어떤 Pod에 연결될지 알 수 없다. 무엇보다 한개의 Persistent Volume과 Claim을 여러 Pod에서 가지려고 하는 문제가 발생한다.

 

이런 Stateful Application 배포를 위해, K8s는 StatefulSet를 제공하며 다음과 같은 특징을 가지고 있다.

 

  • Pod마다 고정된 이름 및 Domain Name, Persistent Volume
  • 순서에 따른 배포 및 Scaling in/out
    • pod-0, pod-1, pod-2, ... 의 순서로 생성되며, scale-in시 역순으로 제거
  • Pod 마다 고정된 이름 및 Domain Name, Volume 
    • 랜덤한 이름이 아닌 생성 순서에 따른 Numbering으로 이름을 부여
    • Headless Service 생성시, 'pod-0.mysvc'와 같이 Pod 단위로 Domain Name으로 접근 가능
    • Pod 생성시 자신만의 Volume이 생성되며, 재생성시에도 동일한 Volume과 Binding

Deployment와 StatefulSet의 비교

 

아래는 nginx를 StatefulSet으로 배포한 예시이다.


apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
      volumeMounts:
      - name: data
        mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: gp2
      resources:
        requests:
          storage: 30Gi

 

위 StatefulSet을 통해 web-0, web-1, web-2 Pod이 순서대로 생성되며, 'serviceName'과 Headless Service를 추가하였으므로 'web-0.nginx'와 같은 이름으로 다른 Pod에서 접근이 가능하다.

volumeClaimTemplate의 경우, 예시에선 AWS EKS 환경을 가정하여 'gp2' Storage Class를 사용하였다. 실사용시, 각자 환경에 맞는 Dyanmic Provisioner를 활용해야 한다.

 

참고
Kubernetes - StatefulSets
Understanding StatefulSets in Kubernetes

 

'Kubernetes' 카테고리의 다른 글

ETCD Encryption  (0) 2021.04.21
Imperative Vs. Declarative  (0) 2021.04.08
Container Runtime과 Docker  (0) 2021.03.09
Calico IPAM  (0) 2021.01.31
Calico 설치 및 Mode 변경  (2) 2021.01.29