스테이트풀(Stateful) 워크로드 만들기

이 페이지에서는 Google Distributed Cloud(GDC) 에어 갭 어플라이언스 Kubernetes 클러스터 내에서 스테이트풀(Stateful) 워크로드를 만들고 관리하는 방법을 설명합니다. 스테이트풀(Stateful) 워크로드를 사용하면 영구 스토리지를 사용하여 애플리케이션 배포를 확장할 수 있습니다. 영구 스토리지는 워크로드가 예약된 위치와 관계없이 애플리케이션에 일관된 ID와 안정적인 호스트 이름을 제공합니다.

이 페이지는 조직의 애플리케이션 워크로드를 만드는 애플리케이션 운영자 그룹 내 개발자를 대상으로 합니다.

시작하기 전에

이 문서의 작업을 완료하려면 필요한 권한을 요청하고 환경을 준비해야 합니다.

IAM 역할 요청

Kubernetes 클러스터에서 스테이트풀(Stateful) 워크로드를 만들거나, 삭제하거나, 수정하거나, 보려면 조직 IAM 관리자에게 네임스페이스 관리자(namespace-admin) 역할을 부여해 달라고 요청하세요. 이 역할은 프로젝트 네임스페이스에 바인딩됩니다.

개발 환경 준비

사전 구성된 베어메탈 Kubernetes 클러스터에 대해 명령어를 실행하려면 다음 리소스가 있어야 합니다.

  1. Kubernetes 클러스터 이름을 찾거나 플랫폼 관리자에게 클러스터 이름을 문의합니다.

  2. 로그인하고 생성합니다. Kubernetes 클러스터의 kubeconfig 파일이 없는 경우 kubeconfig 파일을

  3. Kubernetes 클러스터의 kubeconfig 경로를 사용하여 이 안내의 CLUSTER_KUBECONFIG를 바꿉니다.

StatefulSet 리소스 만들기

StatefulSet 매니페스트를 작성하고 kubectl apply를 실행하여 리소스를 만들어 StatefulSet 객체를 만듭니다. 클라이언트가 StatefulSet 리소스의 포드에 요청을 보내는 안정적인 방법을 제공하려면 Service 객체도 만들어야 합니다.

kubectl apply 명령어는 매니페스트 파일을 사용하여 클러스터에서 리소스를 생성, 업데이트, 삭제합니다. 이것은 객체 구성의 선언적 메서드입니다. 이 메서드는 변경 내용을 객체 구성 파일에 다시 병합하지 않고 실시간 객체에 대한 쓰기를 보관합니다.

StatefulSetService 리소스를 만들려면 다음을 실행합니다.

kubectl --kubeconfig CLUSTER_KUBECONFIG -n NAMESPACE \
    apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: SERVICE_NAME
  labels:
    app: APP_NAME
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: APP_NAME
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: STATEFULSET_NAME
spec:
  selector:
    matchLabels:
      app: APP_LABEL_NAME
  serviceName: "SERVICE_NAME"
  replicas: NUMBER_OF_REPLICAS
  template:
    metadata:
      labels:
        app: APP_LABEL_NAME
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: CONTAINER_NAME
        image: CONTAINER_IMAGE
        resources:
          requests:
            nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1
          limits:
            nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: CONTAINER_STORAGE_VOLUME_PATH
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi
EOF

다음을 바꿉니다.

  • CLUSTER_KUBECONFIG: 컨테이너 워크로드를 배포하는 Kubernetes 클러스터의 kubeconfig 파일입니다.

  • NAMESPACE: 컨테이너 워크로드를 배포할 프로젝트 네임스페이스입니다.

  • SERVICE_NAME: Service 객체의 이름입니다. StatefulSet 객체가 serviceName에서 Service 객체도 설정하는지 확인합니다.

  • APP_NAME: 배포 내에서 실행할 애플리케이션의 이름입니다.

  • APP_LABEL_NAME: StatefulSet 객체에 속하는 포드를 결정하는 라벨 선택기입니다.

  • STATEFULSET_NAME: StatefulSet 객체의 이름입니다.

  • NUMBER_OF_REPLICAS: 배포가 관리하는 복제된 Pod 객체의 수입니다.

  • CONTAINER_NAME: 컨테이너의 이름입니다.

  • CONTAINER_IMAGE: 컨테이너 이미지의 이름입니다. 컨테이너 레지스트리 경로와 이미지 버전(예: REGISTRY_PATH/nginx:1.23)을 포함해야 합니다. 컨테이너 레지스트리 경로 설정에 대한 자세한 내용은 관리형 Harbor 서비스 개요를 참조하세요.

  • CONTAINER_STORAGE_VOLUME_PATH: 스토리지 볼륨이 마운트되는 컨테이너 내의 경로입니다.

예를 들어 다음 StatefulSet 객체와 상응하는 Service 객체는 스테이트풀(Stateful) 컨테이너 워크로드를 만듭니다.

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
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: REGISTRY_PATH/nginx:1.23
        resources:
          requests:
            nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1
          limits:
            nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1
        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라는 Service 객체가 생성됩니다. Service 객체는 labels.app: nginxselector.app: nginx로 표시된 nginx라는 앱을 타겟팅합니다. Service 객체는 포트 80을 노출하고 이름을 web으로 지정합니다. 이 Service 객체는 네트워크 도메인을 제어하고 인터넷 트래픽을 StatefulSet 객체로 배포된 컨테이너식 애플리케이션으로 라우팅합니다.
  • replicas: 3 필드로 설정된 대로 복제된 Pod 객체 3개로 web이라는 StatefulSet가 생성됩니다.
  • .spec.template 섹션으로 설정된 Pod 템플릿은 Pod 객체에 app: nginx 라벨이 지정되어 있음을 나타냅니다.
  • .template.spec 섹션으로 설정된 Pod 사양은 StatefulSet의 포드가 버전 1.23에서 nginx 이미지를 실행하는 컨테이너 nginx 하나를 실행함을 나타냅니다.
  • Pod 사양은 Service 객체에서 열린 웹 포트를 사용합니다.
  • .template.spec.volumeMounts 섹션은 www라는 mountPath 필드를 지정합니다. mountPath는 스토리지 볼륨이 마운트되는 컨테이너의 경로입니다.
  • StatefulSet는 프로비저닝된 스토리지 1GB씩으로 web-www-0, web-www-1, web-www-2라는 PersistentVolumeClaim 객체 3개를 프로비저닝합니다.

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

StatefulSet 리소스에서 영구 스토리지 요청

영구 스토리지는 동적으로 프로비저닝될 수 있으므로 기본 볼륨이 필요 시 생성됩니다. 애플리케이션은 PersistentVolumeClaim 객체를 사용하여 영구 스토리지를 요청할 수 있습니다.

일반적으로 Pod 객체를 만드는 것 외에도 PersistentVolumeClaim 객체를 만들어야 합니다. 하지만 StatefulSet 객체에는 PersistentVolumeClaim 객체를 생성하는 volumeClaimTemplates 배열이 포함되어 있습니다. 각 StatefulSet 복제본은 자체 PersistentVolumeClaim 객체를 가져옵니다.

자세한 내용은 컨테이너 스토리지 구성을 참조하세요.