StatefulSet

이 페이지에서는 Kubernetes StatefulSet 객체에 대해 설명하고 Google Kubernetes Engine에서 이를 사용하는 방법을 설명합니다.

StatefulSet란 무엇인가요?

StatefulSet는 예약된 위치에 관계없이 GKE가 유지관리하는 고유한 영구 ID 및 안정적인 호스트 이름이 포함된 Pod 집합을 나타냅니다. 모든 특정 StatefulSet Pod에 대한 상태 정보 및 기타 복원 데이터는 StatefulSet와 연결된 영구 디스크 스토리지에서 유지관리됩니다.

StatefulSet는 ID의 서수 색인과 해당 Pod의 순서를 사용합니다. 기본적으로 StatefulSet Pod는 순차적으로 배포되며 서수 순서의 역순으로 종료됩니다. 예를 들어 web이라는 StatefulSet에는 web-0, web-1, web-2라는 Pod가 있습니다. web Pod 사양이 변경되면 Pod가 정상적으로 중지되고 순차적으로 다시 생성됩니다. 이 예시에서는 web-2가 먼저 종료되고 그 다음으로 web-1이 종료됩니다. 또는 Pod가 실행 중 및 준비 상태가 될 때까지 기다리거나 다른 Pod를 시작 또는 종료하기 전에 Pod가 종료될 때까지 기다리는 대신, StatefulSet가 모든 Pod를 동시에 실행하거나 종료하도록 podManagementPolicy: Parallel 필드를 지정할 수 있습니다.

StatefulSet는 Pod의 사양이 포함된 Pod 템플릿을 사용합니다. Pod 사양은 각 Pod의 모양을 결정합니다. 즉, 컨테이너 내에서 실행할 애플리케이션, 마운트할 볼륨, 라벨 및 선택기 등을 결정합니다.

사용 패턴

StatefulSet는 Google Compute Engine 영구 디스크와 같은 영구 스토리지에 데이터를 저장하는 스테이트풀(Stateful) 애플리케이션과 클러스터형 애플리케이션을 배포하도록 설계되었습니다. StatefulSet는 고유하고 영구적인 ID 및 안정적인 호스트 이름이 필요한 Kafka, MySQL, Redis, ZooKeeper, 기타 애플리케이션을 배포하는 데 적합합니다. 스테이트리스(Stateless) 애플리케이션의 경우에는 배포를 사용합니다.

StatefulSet 만들기

kubectl apply를 사용하여 StatefulSet를 생성할 수 있습니다.

StatefulSet를 만든 후에는 원하는 개수의 Pod가 항상 실행되고 사용 가능한 상태로 유지됩니다. StatefulSet는 오류가 발생했거나 해당 노드에서 축출된 Pod를 자동으로 교체하고, 새 Pod를 StatefulSet의 Pod 사양에 정의된 스토리지 리소스, 리소스 요청 및 제한, 기타 구성과 자동으로 연결합니다.

다음은 서비스 및 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 # Label selector that determines which Pods belong to the StatefulSet
                     # Must match spec: template: metadata: labels
      serviceName: "nginx"
      replicas: 3
      template:
        metadata:
          labels:
            app: nginx # Pod template's label selector
        spec:
          terminationGracePeriodSeconds: 10
          containers:
          - name: nginx
            image: gcr.io/google_containers/nginx-slim:0.8
            ports:
            - containerPort: 80
              name: web
            volumeMounts:
            - name: www
              mountPath: /usr/share/nginx/html
      volumeClaimTemplates:
      - metadata:
          name: www
        spec:
          accessModes: [ "ReadWriteOnce" ]
          resources:
            requests:
              storage: 1Gi

예를 들면 다음과 같습니다.

  • metadata: name 필드로 표시된 nginx라는 서비스 객체가 생성됩니다. 이 서비스는 labels: app: nginxselector: app: nginx로 표시된 nginx라는 앱을 대상으로 합니다. 이 서비스는 포트 80을 노출하고 이름을 web으로 지정합니다. 이 서비스는 네트워크 도메인을 제어하고 StatefulSet로 배포된 컨테이너식 애플리케이션으로 인터넷 트래픽을 라우팅합니다.
  • web이라는 StatefulSet는 3개의 복제된 Pod(replicas: 3)로 생성됩니다.
  • Pod 템플릿(spec: template)은 해당 Pod에 app: nginx 라벨이 지정되었음을 나타냅니다.
  • Pod 사양(template: spec)은 버전 0.8에서 nginx-slim 이미지를 실행하는 nginx 컨테이너 한 개가 StatefulSet의 Pod에서 실행됨을 나타냅니다. 컨테이너 이미지는 Container Registry에서 호스팅됩니다.
  • Pod 사양에는 서비스로 열린 web 포트가 사용됩니다.
  • template: spec: volumeMountswww라는 mountPath를 지정합니다. mountPath는 스토리지 볼륨이 마운트되는 컨테이너 내의 경로입니다.
  • StatefulSet는 1GB의 프로비저닝된 스토리지를 포함하여 PersistentVolumeClaim, www를 프로비저닝합니다.

Pod 사양에 포함되는 지침은 다음과 같이 요약할 수 있습니다.

  • 각 Pod 라벨을 app: nginx로 지정합니다.
  • 각 Pod에서 이름이 nginx인 하나의 컨테이너를 실행합니다.
  • 0.8 버전에서 nginx-slim 이미지를 실행합니다.
  • Pod에 포트 80이 사용됩니다.
  • 데이터를 마운트 경로에 저장합니다.

StatefulSet 구성에 대한 자세한 내용은 StatefulSet API 참조를 확인하세요.

StatefulSet 업데이트

해당 컨테이너 이미지 및 볼륨이 포함된 Pod 사양을 변경하여 StatefulSet를 업데이트할 수 있습니다. 또한 객체 리소스 요청과 제한 사항, 라벨, 주석도 업데이트할 수 있습니다. StatefulSet를 업데이트하려면 kubectl, Kubernetes API 또는 Google Cloud Console의 GKE 워크로드 메뉴를 사용하면 됩니다.

업데이트 처리 방법을 결정하기 위해 StatefulSet는 spec: updateStrategy에 정의된 업데이트 전략을 사용합니다. 여기에는 OnDeleteRollingUpdate의 두 가지 전략이 있습니다.

  • OnDelete는 객체 구성이 변경되면 Pod를 자동으로 삭제하고 다시 만들지 않습니다. 대신 이전 Pod를 수동으로 삭제해서 컨트롤러가 업데이트된 Pod를 만들도록 해야 합니다.
  • RollingUpdate는 객체 구성이 변경되면 Pod를 자동으로 삭제하고 다시 만듭니다. 이전 항목이 삭제되기 전에 새 Pod가 실행 중 및 준비 상태여야 합니다. 이 전략을 사용할 경우 Pod 사양을 변경하면 출시가 자동으로 트리거됩니다. 이것은 StatefulSet의 기본 업데이트 전략입니다.

StatefulSet는 Pod를 역순으로 업데이트합니다. 업데이트 출시는 다음 명령어를 실행하여 모니터링할 수 있습니다.

kubectl rollout status statefulset [STATEFULSET_NAME]

순차적 업데이트 파티션 나누기

순차적 업데이트의 파티션을 나눌 수 있습니다. 파티션 나누기는 업데이트를 스테이징하거나, 카나리아를 롤아웃하거나, 단계별 롤아웃을 수행하는 경우에 유용합니다.

업데이트를 파티션으로 나눌 때는 StatefulSet의 Pod 사양을 업데이트할 때 순서 값이 파티션 값보다 크거나 같은 모든 Pod가 업데이트됩니다. 순서 값이 파티션 값보다 작은 Pod는 업데이트되지 않고, 삭제된 경우에도 이전 버전의 사양을 사용해서 다시 생성됩니다. 파티션 값이 복제본 수보다 크면 업데이트가 Pod로 전파되지 않습니다.

다음 단계