1. StatefulSets 의 개념:

Deployment 와 유사하나 상태를 유지해줘야 하는 어플리케이션에서 유용하다. 예를 들면 Database 를 쿠버네티스에서 사용하는 경우. 

2. StatefulSets 과 Deployment 와의 차이점:

StatefulSets 도 Deployment 처럼 여러 Pod 들을 관리할 수 있다는 특징이 있다:

 

그러나 StatefulSets 은 각각의 Pod 들을 고유하게 식별할 수 있는 영구적이고 순차적인 id 가 있고, 각 Pod 마다 stable hostname 과 고유한 Persistnet Storage 가 할당된다.

  • Stable hostname 이라는 것은 StatefulSet 의 Pod 가 받은 고유한 id 를 바탕으로 Pod 를 식별할 수 있는 이름을 말한다.  <statefulset-name>-<ordinal-index> 형식으로 이뤄진다.

 

예시로 demo 라는 Pod 의 이름을 가진 StatefulSets 에서 3개의 replica 를 가지도록 설정하면 각각의 Pod 의 이름은 demo-0, demo-1, demo-2 이렇게 될 것이다.

 

3. StatefulSets에서 Pod의 배포, 스케일링, 업데이트:

이렇게 순차적인 id 를 가진 pod 는 배포될 때도 id 의 순서대로 부팅된다.

 

위의 예시대로 설명하자면 demo-0 이 먼저 부팅되고 이후에 demo-1 Pod 가 부팅되는 식으로 이뤄진다.

 

만약 demo-0 이 부팅하다가 실패하면 demo-1 도 부팅되지 않는다.

 

Rolling Update 로 배포하는 경우라면 id 의 역순서대로 Pod 가 갱신된다.

 

위의 예시대로 설명하자면 demo-2 가 먼저 업데이트되고 이후에 demo-1 이 업데이트 되는 식으로 진행된다.

 

이런 순서는 Pod Management Policy 에 따라서 설정되는데 기존 값이 "OrderedReady" 이기 때문이다.

 

이 값을 "Parallel" 로 변경할 수 있는데 그러면 Rolling Update 는 병렬로 실행된다. 

4. StatefulSets 과 Persistent Volume Claim:

StatefulSets 의 각 Pod 는 자신만의 PVC (Persistent Volume Claim) 을 할당함으로써 자신만의 스토로지를 할당받을 수 있다.

 

이때 Persistent Volume 의 access Mode 는 "ReadWriteOnce" 로 설정되어야한다.

 

StatefulSet 이 PVC 를 이용하는 예제는 다음과 같다:

  • spec.volumeClaimTemplates 에 PVC 오브젝트 값을 입력하면 된다.
  • spec.template.spec.container 에 사용할 컨테이너 이미지를 입력하면 된다.
  • spec.template.spec.container.volumeMounts 에 사용할 Volume 의 Path 를 지정하면 된다.
    apiVersion: apps/v1
    kind: StatefulSets
    metadata: 
    name: demo-statefulSets
    spec: 
    selector: 
      matchLabels: 
        app: demo 
    serviceName: demo-service 
    replicas: 3 
    updateStrategy: 
      type: RollingUpdate
    template: 
      metadata: 
        labels: 
          app: demo
      spec: 
        containers:
        - name: demo-container
          images: k8s.gcr.io/demo:0.1
          ports:
          - containerPort: 80
            name: web
          volumeMounts:
          - name: www
            mountPath: /usr/share/web
    volumeClaimTemplates: 
    - metadata: 
        name: demo-pvc
      spec: 
        accessModes: ["ReadWriteOnce"]
        resources: 
          requests: 
           stroage: 1Gi 

5. StatefulSets 과 Network

StatefulSests 에서도 쿠버네티스 내부/외부와 통신을 하려면 Service 오브젝트를 생성해야하고 이를 명시해야한다. 

 

StatefulSet 을 이용하는 경우 해당 Pod 와 직접적인 통신을 원하는 경우가 많기 때문에 Headless Service 를 이용하는 경우가 많다.  

  • 일반 Service 객체를 이용해 통신을 하는 경우라면 로드 밸런서를 통해서 Pod 들 중 하나와 통신을 할 것이다. 

 

Headless Service 를 이용하는 StatefulSets 의 예시는 다음과 같다:

  • Pod 와 직접적인 통신을 하기 위해선 dns 조회를 해야하며 dns 조회는 다음 형식을 따라야한다. <pod-name>.<service-name>.<namespace>.svc.cluster.local
  • 여기서 또 중요한 건 StatefulSet 의 yaml 에서 spec.selector.matchLabels.app 에 있는 값과 spec.template.metadata.labels.app 에 있는 값이 같아야지 올바르게 동작한다는 것이다:
    • spec.selector.matchLabels.app 값은 StatefulSet 이 관리해야 할 Pod 를 식별할 수 있도록 하는 Label 값을 등록하는 것이다.
    • spec.template.metadata.labels.app 값은 Pod 가 등록될 때 같이 등록될 Label 을 말하는 것이다.
apiVersion: v1
kind: Service 
metadata: 
  name: demo-service
  labels:
    app: demo
spec: 
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector: 
    app: demo
apiVersion: apps/v1
kind: StatefulSets
metadata: 
  name: demo-statefulSets
spec: 
  selector: 
    matchLabels: 
      app: demo 
  serviceName: demo-service 
  replicas: 3 
  updateStrategy: 
    type: RollingUpdate
  template: 
    metadata: 
      labels: 
        app: demo

+ Recent posts