큐에 추가된 프로비저닝을 통한 flex-start로 대규모 워크로드 실행

이 페이지에서는 동적 워크로드 스케줄러를 기반으로 하는 큐에 추가된 프로비저닝을 통한 flex-start를 사용하여 GPU가 포함된 대규모 일괄 및 AI 워크로드의 GPU 가용성을 최적화하는 방법을 보여줍니다.

이 페이지를 읽기 전 다음 내용을 숙지해야 합니다.

이 가이드는 일괄 워크로드를 실행하기 위해 Kubernetes 컨테이너 조정 기능을 사용하는 데 관심이 있는 머신러닝(ML) 엔지니어, 플랫폼 관리자 및 운영자, 데이터 및 AI 전문가를 대상으로 합니다. Google Cloud 콘텐츠에서 참조하는 일반적인 역할과 예시 태스크에 대한 자세한 내용은 일반 GKE 사용자 역할 및 태스크를 참조하세요.

큐에 추가된 프로비저닝을 통한 flex-start 작동 방식

큐에 추가된 프로비저닝을 통한 flex-start를 사용하면 GKE가 요청된 모든 리소스를 동시에 할당합니다. 큐에 추가된 프로비저닝을 통한 flex-start는 다음 도구를 사용합니다.

  • 큐에 추가된 프로비저닝을 통한 flex-start는 동적 워크로드 스케줄러프로비저닝 요청 커스텀 리소스 정의(CRD)를 기반으로 합니다. 이러한 도구는 사용 가능한 리소스와 워크로드 요구사항에 따라 할당된 용량을 관리합니다.
  • (선택사항) Kueue는 큐에 추가된 프로비저닝 요청을 통한 flex-start의 수명 주기를 자동화합니다. Kueue는 작업 큐에 추가를 구현하고 프로비저닝 요청 수명 주기를 자동으로 처리합니다.

큐에 추가된 프로비저닝을 통한 flex-start를 사용하려면 노드 풀을 만들 때 --flex-start--enable-queued-provisioning 플래그를 추가해야 합니다.

권장사항:

워크로드가 다음 기준을 충족하는 경우 대규모 일괄 및 AI 워크로드에 큐에 추가된 프로비저닝을 통한 flex-start를 사용합니다.

  • 워크로드의 시작 시간이 유연합니다.
  • 워크로드가 여러 노드에서 동시에 실행되어야 합니다.

단일 노드에서 실행할 수 있는 소규모 워크로드에 flex-start VM을 사용합니다. GKE의 GPU 프로비저닝에 대한 자세한 내용은 AI 워크로드용 액셀러레이터 획득을 참조하세요.

시작하기 전에

시작하기 전에 다음 태스크를 수행했는지 확인합니다.

  • Google Kubernetes Engine API를 사용 설정합니다.
  • Google Kubernetes Engine API 사용 설정
  • 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치한 경우 gcloud components update 명령어를 실행하여 최신 버전을 가져옵니다. 이전 gcloud CLI 버전에서는 이 문서의 명령어를 실행하지 못할 수 있습니다.

큐에 추가된 프로비저닝을 통한 flex-start로 노드 풀 사용

이 섹션은 Standard 클러스터에만 적용됩니다.

다음 방법 중 하나를 사용하여 큐에 추가된 프로비저닝을 통한 flex-start가 클러스터의 특정 노드 풀에서 작동할 수 있도록 지정할 수 있습니다.

노드 풀 만들기

gcloud CLI를 사용하여 큐에 추가된 프로비저닝을 통한 flex-start가 사용 설정된 노드 풀을 만듭니다.

gcloud container node-pools create NODEPOOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=LOCATION \
    --enable-queued-provisioning \
    --accelerator type=GPU_TYPE,count=AMOUNT,gpu-driver-version=DRIVER_VERSION \
    --machine-type=MACHINE_TYPE \
    --flex-start \
    --enable-autoscaling  \
    --num-nodes=0   \
    --total-max-nodes TOTAL_MAX_NODES  \
    --location-policy=ANY  \
    --reservation-affinity=none  \
    --no-enable-autorepair

다음을 바꿉니다.

  • NODEPOOL_NAME: 선택한 노드 풀의 이름
  • CLUSTER_NAME: 클러스터의 이름
  • LOCATION: 클러스터의 Compute Engine 리전입니다(예: us-central1).
  • GPU_TYPE: GPU 유형입니다.
  • AMOUNT: 노드 풀의 노드에 연결할 GPU 수입니다.
  • DRIVER_VERSION: 설치할 NVIDIA 드라이버 버전입니다. 다음 중 하나일 수 있습니다.
    • default: GKE 버전의 기본 드라이버 버전을 설치합니다.
    • latest: GKE 버전에 사용 가능한 최신 드라이버 버전을 설치합니다. Container-Optimized OS를 사용하는 노드에서만 사용할 수 있습니다.
  • TOTAL_MAX_NODES: 전체 노드 풀에 대해 자동으로 확장되는 최대 노드 수입니다.
  • MACHINE_TYPE: 노드의 Compute Engine 머신 유형입니다.

    권장사항:

    가속기 최적화 머신 유형을 사용하여 AI/ML 워크로드의 성능과 효율성을 향상시킵니다.

선택적으로 다음 플래그를 사용할 수 있습니다.

  • --node-locations=COMPUTE_ZONES: GKE가 GPU 노드를 만드는 하나 이상의 영역을 쉼표로 구분한 목록입니다. 영역은 클러스터와 동일한 리전에 있어야 합니다. 사용 가능한 GPU가 있는 영역을 선택합니다.
  • --enable-gvnic: 이 플래그는 GPU 노드 풀에서 gVNIC를 사용 설정하여 네트워크 트래픽 속도를 높입니다.

이 명령어는 다음 구성을 사용하여 노드 풀을 만듭니다.

  • --flex-start 플래그와 --enable-queued-provisioning 플래그를 함께 사용하여 GKE에 큐에 추가된 프로비저닝을 통한 flex-start가 사용 설정된 노드 풀을 만들고 cloud.google.com/gke-queued taint를 노드 풀에 추가하도록 지시합니다.
  • GKE를 사용하면 큐에 추가된 프로비저닝 및 클러스터 자동 확장을 사용 설정할 수 있습니다.
  • 노드 풀에는 처음에 노드가 0개 있습니다.
  • --no-enable-autorepair 플래그는 자동 복구를 사용 중지하므로 복구된 노드에서 실행되는 워크로드가 중단될 수 있습니다.

큐에 추가된 프로비저닝을 통한 flex-start의 노드 풀을 만들도록 노드 자동 프로비저닝 사용 설정

노드 자동 프로비저닝을 사용하여 버전 1.29.2-gke.1553000 이상이 실행되는 클러스터에서 큐에 추가된 프로비저닝을 통한 flex-start의 노드 풀을 관리할 수 있습니다. 노드 자동 프로비저닝을 사용 설정하면 GKE가 연결된 워크로드에 필요한 리소스로 노드 풀을 만듭니다.

노드 자동 프로비저닝을 사용 설정하려면 다음 설정을 고려하고 GPU 한도 구성의 단계를 완료합니다.

  • 이 기능을 사용 설정할 때 큐에 추가된 프로비저닝을 통한 flex-start에 필요한 리소스를 지정합니다. 사용 가능한 resourceTypes를 표시하려면 gcloud compute accelerator-types list 명령어를 실행합니다.
  • --no-enable-autoprovisioning-autorepair 플래그를 사용하여 노드 자동 복구를 사용 중지합니다.
  • GKE가 자동 프로비저닝된 GPU 노드에 GPU 드라이버를 자동으로 설치하도록 합니다. 자세한 내용은 GPU에서 노드 자동 프로비저닝을 사용하여 드라이버 설치를 참조하세요.

큐에 추가된 프로비저닝을 통한 flex-start로 일괄 및 AI 워크로드 실행

큐에 추가된 프로비저닝을 통한 flex-start로 일괄 워크로드를 실행하려면 다음 구성 중 하나를 사용합니다.

권장사항:

Kueue를 사용하여 큐에 추가된 프로비저닝을 통한 flex-start로 일괄 및 AI 워크로드를 실행합니다.

Kueue가 포함된 작업에 대한 큐에 추가된 프로비저닝을 통한 flex-start

다음 섹션에서는 Kueue가 포함된 작업에 대한 큐에 추가된 프로비저닝을 통한 flex-start를 구성하는 방법을 보여줍니다.

  • 큐에 추가된 프로비저닝을 통한 flex-start 노드 풀 설정
  • 예약 및 큐에 추가된 프로비저닝을 통한 flex-start 노드 풀 설정

이 섹션에서는 ai-on-gke 저장소의 dws-examples 디렉터리에 있는 샘플을 사용합니다. Google은 Apache2 라이선스에 따라 샘플을 dws-examples 디렉터리에 게시했습니다.

Kueue를 설치하려면 관리자 권한이 있어야 합니다. 이러한 권한을 얻으려면 IAM 역할 roles/container.admin을 부여받아야 합니다. GKE IAM 역할에 대한 자세한 내용은 IAM 허용 정책 만들기 가이드를 참조하세요.

개발 환경 준비

  1. Cloud Shell에서 다음 명령어를 실행합니다.

    git clone https://github.com/GoogleCloudPlatform/ai-on-gke
    cd ai-on-gke/tutorials-and-examples/workflow-orchestration/dws-examples
    
  2. 클러스터에 최신 Kueue 버전을 설치합니다.

    VERSION=KUEUE_VERSION
    kubectl apply --server-side -f https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/manifests.yaml
    

    KUEUE_VERSION을 최신 Kueue 버전으로 바꿉니다.

0.7.0 이전 버전에서 Kueue를 사용하는 경우 ProvisioningACC 기능 게이트를 true로 설정하여 Kueue 기능 게이트 구성을 변경합니다. 자세한 설명과 기본 게이트 값은 Kueue의 기능 게이트를 참조하세요. Kueue 설치에 대한 자세한 내용은 설치를 참조하세요.

동적 워크로드 스케줄러 노드 풀 전용 설정용 Kueue 리소스 만들기

다음 매니페스트를 사용하여 dws-cluster-queue라는 클러스터 수준 큐dws-local-queue라는 LocalQueue 네임스페이스를 만듭니다. 이 네임스페이스에서 dws-cluster-queue 큐를 참조하는 작업은 큐에 추가된 프로비저닝을 통한 flex-start를 사용하여 GPU 리소스를 가져옵니다.

apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: "default-flavor"
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: AdmissionCheck
metadata:
  name: dws-prov
spec:
  controllerName: kueue.x-k8s.io/provisioning-request
  parameters:
    apiGroup: kueue.x-k8s.io
    kind: ProvisioningRequestConfig
    name: dws-config
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ProvisioningRequestConfig
metadata:
  name: dws-config
spec:
  provisioningClassName: queued-provisioning.gke.io
  managedResources:
    - nvidia.com/gpu
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
  name: "dws-cluster-queue"
spec:
  namespaceSelector: {}
  resourceGroups:
    - coveredResources: ["cpu", "memory", "nvidia.com/gpu", "ephemeral-storage"]
      flavors:
        - name: "default-flavor"
          resources:
            - name: "cpu"
              nominalQuota: 1000000000 # "Infinite" quota
            - name: "memory"
              nominalQuota: 1000000000Gi # "Infinite" quota
            - name: "nvidia.com/gpu"
              nominalQuota: 1000000000 # "Infinite" quota
            - name: "ephemeral-storage"
              nominalQuota: 1000000000Ti # "Infinite" quota
  admissionChecks:
    - dws-prov
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
  namespace: "default"
  name: "dws-local-queue"
spec:
  clusterQueue: "dws-cluster-queue"
---
apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
  labels:
    control-plane: controller-manager
  name: controller-manager-metrics-monitor
  namespace: kueue-system
spec:
  endpoints:
    - path: /metrics
      port: 8080
      scheme: http
      interval: 30s
  selector:
    matchLabels:
      control-plane: controller-manager
---

이 클러스터 큐의 할당량 한도는 높으며 이 큐에는 큐에 추가된 프로비저닝을 통한 flex-start 통합만 사용 설정됩니다. Kueue API 및 한도 설정 방법에 대한 자세한 내용은 Kueue 개념을 참조하세요.

LocalQueue를 배포합니다.

kubectl create -f ./dws-queues.yaml

출력은 다음과 비슷합니다.

resourceflavor.kueue.x-k8s.io/default-flavor created
admissioncheck.kueue.x-k8s.io/dws-prov created
provisioningrequestconfig.kueue.x-k8s.io/dws-config created
clusterqueue.kueue.x-k8s.io/dws-cluster-queue created
localqueue.kueue.x-k8s.io/dws-local-queue created

다른 네임스페이스에서 큐에 추가된 프로비저닝을 통한 flex-start를 사용하는 작업을 실행하려면 위 템플릿을 사용하여 추가 LocalQueues를 만들면 됩니다.

작업 실행

다음 매니페스트에서 샘플 작업은 큐에 추가된 프로비저닝을 통한 flex-start를 사용합니다.

apiVersion: batch/v1
kind: Job
metadata:
  name: sample-job
  namespace: default
  labels:
    kueue.x-k8s.io/queue-name: dws-local-queue
  annotations:
    provreq.kueue.x-k8s.io/maxRunDurationSeconds: "600"
spec:
  parallelism: 1
  completions: 1
  suspend: true
  template:
    spec:
      nodeSelector:
        cloud.google.com/gke-nodepool: NODEPOOL_NAME
      tolerations:
        - key: "nvidia.com/gpu"
          operator: "Exists"
          effect: "NoSchedule"
      containers:
        - name: dummy-job
          image: gcr.io/k8s-staging-perf-tests/sleep:v0.0.3
          args: ["120s"]
          resources:
            requests:
              cpu: "100m"
              memory: "100Mi"
              nvidia.com/gpu: 1
            limits:
              cpu: "100m"
              memory: "100Mi"
              nvidia.com/gpu: 1
      restartPolicy: Never

이 매니페스트에는 큐에 추가된 프로비저닝을 통한 flex-start 구성과 관련된 다음 필드가 포함됩니다.

  • kueue.x-k8s.io/queue-name: dws-local-queue 라벨은 Kueue가 해당 작업을 조정할 책임이 있다는 것을 GKE에 알려줍니다. 이 라벨은 작업이 대기 중인 큐도 정의합니다.
  • suspend: true 플래그는 GKE에 작업 리소스를 만들지만 포드를 아직 예약하지 않도록 지시합니다. 노드가 작업을 실행할 준비가 되면 Kueue는 해당 플래그를 false로 변경합니다.
  • nodeSelector는 지정된 노드 풀에서만 작업을 예약하도록 GKE에 지시합니다. 이 값은 큐에 추가된 프로비저닝이 사용 설정된 노드 풀의 이름인 NODEPOOL_NAME과 일치해야 합니다.
  1. 작업을 실행합니다.

    kubectl create -f ./job.yaml
    

    출력은 다음과 비슷합니다.

    job.batch/sample-job created
    
  2. 작업 상태를 확인합니다.

    kubectl describe job sample-job
    

    출력은 다음과 비슷합니다.

    Events:
      Type    Reason            Age    From                        Message
      ----    ------            ----   ----                        -------
      Normal  Suspended         5m17s  job-controller              Job suspended
      Normal  CreatedWorkload   5m17s  batch/job-kueue-controller  Created Workload: default/job-sample-job-7f173
      Normal  Started           3m27s  batch/job-kueue-controller  Admitted by clusterQueue dws-cluster-queue
      Normal  SuccessfulCreate  3m27s  job-controller              Created pod: sample-job-9qsfd
      Normal  Resumed           3m27s  job-controller              Job resumed
      Normal  Completed         12s    job-controller              Job completed
    

또한 Kueue가 통합된 큐에 추가된 프로비저닝을 통한 flex-start는 다음과 같이 오픈소스 생태계에서 사용할 수 있는 다른 워크로드 유형도 지원합니다.

  • RayJob
  • JobSet v0.5.2 이상
  • Kubeflow MPIJob, TFJob, PyTorchJob.
  • 워크플로 조정자가 자주 사용하는 Kubernetes 포드
  • Flux 미니 클러스터

이 지원에 대한 자세한 내용은 Kueue의 일괄 사용자를 참조하세요.

예약 및 동적 워크로드 스케줄러 노드 풀 설정용 Kueue 리소스 만들기

다음 매니페스트를 사용하여 두 개의 서로 다른 노드 풀(reservation-nodepooldws-nodepool)에 연결된 두 개의 ResourceFlavors를 만들 수 있습니다. 이러한 노드 풀의 이름은 예시적인 이름일 뿐입니다. 노드 풀 구성에 따라 이러한 이름을 수정합니다. 또한 ClusterQueue 구성을 사용하면 수신되는 작업이 reservation-nodepool을 사용하려고 시도하고, 용량이 없으면 이러한 작업에서 동적 워크로드 스케줄러를 사용하여 GPU 리소스를 가져옵니다.

apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: "reservation"
spec:
  nodeLabels:
    cloud.google.com/gke-nodepool: "reservation-nodepool" # placeholder value
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: "dws"
spec:
  nodeLabels:
    cloud.google.com/gke-nodepool: "dws-nodepool" # placeholder value
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
  name: "cluster-queue"
spec:
  namespaceSelector: {} # match all.
  resourceGroups:
    - coveredResources: ["cpu", "memory", "nvidia.com/gpu"]
      flavors:
        - name: "reservation" # first we try reservation
          resources:
            - name: "cpu"
              nominalQuota: 9
            - name: "memory"
              nominalQuota: 36Gi
            - name: "nvidia.com/gpu"
              nominalQuota: 9
        - name: "dws" # if reservation is saturated we try dws
          resources:
            - name: "cpu"
              nominalQuota: 1000000000 # "Infinite" quota
            - name: "memory"
              nominalQuota: 1000000000Gi # "Infinite" quota
            - name: "nvidia.com/gpu"
              nominalQuota: 1000000000 # "Infinite" quota
  admissionChecksStrategy:
    admissionChecks:
      - name: "dws-prov"
        onFlavors: [dws]
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
  namespace: "default"
  name: "user-queue"
spec:
  clusterQueue: "cluster-queue"
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: AdmissionCheck
metadata:
  name: dws-prov
spec:
  controllerName: kueue.x-k8s.io/provisioning-request
  parameters:
    apiGroup: kueue.x-k8s.io
    kind: ProvisioningRequestConfig
    name: dws-config
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ProvisioningRequestConfig
metadata:
  name: dws-config
spec:
  provisioningClassName: queued-provisioning.gke.io
  managedResources:
    - nvidia.com/gpu

이 클러스터 큐의 할당량 한도는 높으며 이 큐에는 큐에 추가된 프로비저닝을 통한 flex-start 통합만 사용 설정됩니다. Kueue API 및 한도 설정 방법에 대한 자세한 내용은 Kueue 개념을 참조하세요.

다음 명령어를 사용하여 매니페스트를 배포합니다.

kubectl create -f ./dws_and_reservation.yaml

출력은 다음과 비슷합니다.

resourceflavor.kueue.x-k8s.io/reservation created
resourceflavor.kueue.x-k8s.io/dws created
clusterqueue.kueue.x-k8s.io/cluster-queue created
localqueue.kueue.x-k8s.io/user-queue created
admissioncheck.kueue.x-k8s.io/dws-prov created
provisioningrequestconfig.kueue.x-k8s.io/dws-config created

작업 실행

이전 설정과 달리 이 매니페스트에는 nodeSelector 필드가 포함되지 않습니다. ClusterQueue의 여유 용량에 따라 Kueue에서 이 필드를 채우기 때문입니다.

apiVersion: batch/v1
kind: Job
metadata:
  generateName: sample-job-
  namespace: default
  labels:
    kueue.x-k8s.io/queue-name: user-queue
  annotations:
    provreq.kueue.x-k8s.io/maxRunDurationSeconds: "600"
spec:
  parallelism: 1
  completions: 1
  suspend: true
  template:
    spec:
      tolerations:
        - key: "nvidia.com/gpu"
          operator: "Exists"
          effect: "NoSchedule"
      containers:
        - name: dummy-job
          image: gcr.io/k8s-staging-perf-tests/sleep:v0.0.3
          args: ["120s"]
          resources:
            requests:
              cpu: "100m"
              memory: "100Mi"
              nvidia.com/gpu: 1
            limits:
              cpu: "100m"
              memory: "100Mi"
              nvidia.com/gpu: 1
      restartPolicy: Never
  1. 작업을 실행합니다.

    kubectl create -f ./job-without-node-selector.yaml
    

    출력은 다음과 비슷합니다.

    job.batch/sample-job-v8xwm created
    

작업에서 사용하는 노드 풀을 확인하려면 작업에서 사용하는 ResourceFlavor를 알아야 합니다.

문제 해결

Kueue 문제 해결에 대한 자세한 내용은 Kueue에서 프로비저닝 요청 문제 해결을 참조하세요.

Kueue가 없는 작업에 대한 큐에 추가된 프로비저닝을 통한 flex-start

ProvisioningRequest 객체 정의

각 작업에 대한 프로비저닝 요청을 통해 요청을 만듭니다. 큐에 추가된 프로비저닝을 통한 flex-start는 포드를 시작하지 않고 노드만 프로비저닝합니다.

  1. 다음 provisioning-request.yaml 매니페스트를 만듭니다.

    표준

    apiVersion: v1
    kind: PodTemplate
    metadata:
      name: POD_TEMPLATE_NAME
      namespace: NAMESPACE_NAME
      labels:
        cloud.google.com/apply-warden-policies: "true"
    template:
      spec:
        nodeSelector:
          cloud.google.com/gke-nodepool: NODEPOOL_NAME
          cloud.google.com/gke-flex-start: "true"
        tolerations:
          - key: "nvidia.com/gpu"
            operator: "Exists"
            effect: "NoSchedule"
        containers:
          - name: pi
            image: perl
            command: ["/bin/sh"]
            resources:
              limits:
                cpu: "700m"
                nvidia.com/gpu: 1
              requests:
                cpu: "700m"
                nvidia.com/gpu: 1
        restartPolicy: Never
    ---
    apiVersion: autoscaling.x-k8s.io/API_VERSION
    kind: ProvisioningRequest
    metadata:
      name: PROVISIONING_REQUEST_NAME
      namespace: NAMESPACE_NAME
    spec:
      provisioningClassName: queued-provisioning.gke.io
      parameters:
        maxRunDurationSeconds: "MAX_RUN_DURATION_SECONDS"
      podSets:
      - count: COUNT
        podTemplateRef:
          name: POD_TEMPLATE_NAME
    

    다음을 바꿉니다.

    • API_VERSION: API 버전(v1 또는 v1beta1). 안정성과 최신 기능 액세스를 위해 v1을 사용하는 것이 좋습니다.
    • NAMESPACE_NAME: Kubernetes 네임스페이스 이름. 네임스페이스는 포드 네임스페이스와 동일해야 합니다.
    • PROVISIONING_REQUEST_NAME: ProvisioningRequest 이름. 포드 주석에서 이 이름을 참조합니다.
    • MAX_RUN_DURATION_SECONDS: 선택사항으로 노드의 최대 런타임(초 단위). 기본값은 7일까지입니다. 자세한 내용은 큐에 추가된 프로비저닝을 통한 flex-start 작동 방식을 참조하세요. 요청을 만든 후에는 이 값을 변경할 수 없습니다. 이 필드는 GKE 버전 1.28.5-gke.1355000 이상에서 사용 가능합니다.
    • COUNT: 요청된 포드 수. 노드는 하나의 영역에 원자적으로 예약됩니다.
    • POD_TEMPLATE_NAME: PodTemplate 이름.
    • NODEPOOL_NAME: 선택한 노드 풀의 이름입니다. 자동 프로비저닝된 노드 풀을 사용하려면 삭제합니다.

    GKE는 포드를 만드는 동안 포드에 유효성 검사와 변형을 적용할 수 있습니다. cloud.google.com/apply-warden-policies 라벨을 사용하면 GKE에서 PodTemplate 객체에 같은 유효성 검사와 변형을 적용할 수 있습니다. 이 라벨은 GKE에서 포드의 노드 리소스 요구사항을 계산하는 데 필요합니다. 큐에 추가된 프로비저닝을 통한 flex-start 통합은 PodSet 사양 하나만 지원합니다. 여러 포드 템플릿을 혼합하려면 가장 많은 리소스를 요청하는 템플릿을 사용합니다. GPU 유형이 다양한 VM과 같이 서로 다른 머신 유형을 혼합할 수 없습니다.

    노드 자동 프로비저닝

    apiVersion: v1
    kind: PodTemplate
    metadata:
      name: POD_TEMPLATE_NAME
      namespace: NAMESPACE_NAME
      labels:
        cloud.google.com/apply-warden-policies: "true"
    template:
      spec:
        nodeSelector:
          cloud.google.com/gke-accelerator: GPU_TYPE
          cloud.google.com/gke-flex-start: "true"
        tolerations:
          - key: "nvidia.com/gpu"
            operator: "Exists"
            effect: "NoSchedule"
        containers:
          - name: pi
            image: perl
            command: ["/bin/sh"]
            resources:
              limits:
                cpu: "700m"
                nvidia.com/gpu: 1
              requests:
                cpu: "700m"
                nvidia.com/gpu: 1
        restartPolicy: Never
    ---
    apiVersion: autoscaling.x-k8s.io/API_VERSION
    kind: ProvisioningRequest
    metadata:
      name: PROVISIONING_REQUEST_NAME
      namespace: NAMESPACE_NAME
    spec:
      provisioningClassName: queued-provisioning.gke.io
      parameters:
        maxRunDurationSeconds: "MAX_RUN_DURATION_SECONDS"
      podSets:
      - count: COUNT
        podTemplateRef:
          name: POD_TEMPLATE_NAME
    

    다음을 바꿉니다.

    • API_VERSION: API 버전(v1 또는 v1beta1). 안정성과 최신 기능 액세스를 위해 v1을 사용하는 것이 좋습니다.
    • NAMESPACE_NAME: Kubernetes 네임스페이스 이름. 네임스페이스는 포드 네임스페이스와 동일해야 합니다.
    • PROVISIONING_REQUEST_NAME: ProvisioningRequest 이름. 포드 주석에서 이 이름을 참조합니다.
    • MAX_RUN_DURATION_SECONDS: 선택사항으로 노드의 최대 런타임(초 단위). 기본값은 7일까지입니다. 자세한 내용은 큐에 추가된 프로비저닝을 통한 flex-start 작동 방식을 참조하세요. 요청을 만든 후에는 이 값을 변경할 수 없습니다. 이 필드는 GKE 버전 1.28.5-gke.1355000 이상에서 사용 가능합니다.
    • COUNT: 요청된 포드 수. 노드는 하나의 영역에 원자적으로 예약됩니다.
    • POD_TEMPLATE_NAME: PodTemplate 이름.
    • GPU_TYPE: GPU 하드웨어의 유형.

    GKE는 포드를 만드는 동안 포드에 유효성 검사와 변형을 적용할 수 있습니다. cloud.google.com/apply-warden-policies 라벨을 사용하면 GKE에서 PodTemplate 객체에 같은 유효성 검사와 변형을 적용할 수 있습니다. 이 라벨은 GKE에서 포드의 노드 리소스 요구사항을 계산하는 데 필요합니다.

  2. 매니페스트를 적용합니다.

    kubectl apply -f provisioning-request.yaml
    

포드 구성

이 섹션에서는 Kubernetes 작업을 사용하여 포드를 구성합니다. 하지만 Kubernetes JobSet 또는 Kubeflow, Ray, 커스텀 컨트롤러와 같은 다른 프레임워크를 사용할 수도 있습니다. 작업 사양에서 다음 주석을 사용하여 포드를 ProvisioningRequest에 연결합니다.

apiVersion: batch/v1
kind: Job
spec:
  template:
    metadata:
      annotations:
        autoscaling.x-k8s.io/consume-provisioning-request: PROVISIONING_REQUEST_NAME
        autoscaling.x-k8s.io/provisioning-class-name: "queued-provisioning.gke.io"
    spec:
      ...

포드 주석 키 consume-provisioning-request는 사용할 ProvisioningRequest를 정의합니다. GKE는 consume-provisioning-requestprovisioning-class-name 주석을 사용하여 다음을 수행합니다.

  • 큐에 추가된 프로비저닝을 통한 flex-start로 프로비저닝된 노드에서만 포드를 예약합니다.
  • 클러스터 자동 확장 처리에서 포드와 큐에 추가된 프로비저닝을 통한 flex-start 간의 리소스 요청 중복을 방지합니다.
  • safe-to-evict: false 주석을 삽입하여 클러스터 자동 확장 처리가 노드 간에 포드를 이동하고 일괄 계산을 중단하지 않도록 합니다. 포드 주석에서 safe-to-evict: true를 지정하여 이 동작을 변경할 수 있습니다.

프로비저닝 요청 상태 관찰

프로비저닝 요청 상태는 포드 예약 여부를 정의합니다. Kubernetes 감시를 사용하여 변경사항을 효율적으로 관찰하거나 Kubernetes 객체의 상태 추적에 이미 사용하는 다른 도구를 사용할 수 있습니다. 다음 표에서는 가능한 프로비저닝 요청 상태와 가능한 각 결과를 설명합니다.

프로비저닝 요청 상태 설명 가능한 결과
대기 중 요청이 아직 확인 및 처리되지 않았습니다. 처리 후 요청이 Accepted 또는 Failed 상태로 전환됩니다.
Accepted=true 요청이 수락되어 리소스를 사용할 수 있을 때까지 기다리는 중입니다. 리소스가 발견되었고 노드가 프로비저닝된 경우 요청이 Provisioned 상태로 전환되고, 불가능한 경우 Failed 상태로 전환됩니다.
Provisioned=true 노드가 준비되었습니다. 10분 안에 포드를 시작하여 프로비저닝된 리소스를 소비해야 합니다. 이 시간이 지나면 클러스터 자동 확장 처리에서 노드를 필요하지 않은 것으로 간주하여 삭제합니다.
Failed=true 오류로 인해 노드를 프로비저닝할 수 없습니다. Failed=true는 종결 상태입니다. 조건의 ReasonMessage 필드에 있는 정보를 기준으로 조건 문제를 해결합니다. 새 프로비저닝 요청 요청을 만들고 다시 시도합니다.
Provisioned=false 노드가 아직 프로비저닝되지 않았습니다.

Reason=NotProvisioned인 경우 모든 리소스를 사용할 수 있기 전의 임시 상태입니다.

Reason=QuotaExceeded인 경우 이 이유와 조건의 Message 필드에 있는 정보를 기준으로 조건 문제를 해결합니다. 할당량을 추가로 요청해야 할 수 있습니다. 자세한 내용은 프로비저닝 요청이 할당량으로 제한되는지 확인 섹션을 참조하세요. 이 Reason은 GKE 버전 1.29.2-gke.1181000 이상에서만 사용할 수 있습니다.

Reason=ResourcePoolExhausted이고 MessageExpected time is indefinite가 포함된 경우 다른 영역이나 리전을 선택하거나 요청된 리소스를 조정합니다.

포드 시작

프로비저닝 요청이 Provisioned=true 상태에 도달하면 작업을 실행하여 포드를 시작할 수 있습니다. 이렇게 하면 kube-scheduler 및 클러스터 자동 확장 처리 성능에 영향을 줄 수 있는 대기 또는 실패한 요청에 예약할 수 없는 포드가 확산되는 것을 방지할 수 있습니다.

또는 예약할 수 없는 포드가 있어도 무방하다면 프로비저닝 요청과 동시에 포드를 만들 수 있습니다.

프로비저닝 요청 취소

요청이 프로비저닝되기 전에 취소하려면 ProvisioningRequest를 삭제하면 됩니다.

kubectl delete provreq PROVISIONING_REQUEST_NAME -n NAMESPACE

대부분의 경우 ProvisioningRequest를 삭제하면 노드 생성이 중지됩니다. 하지만 상황에 따라(예: 노드가 이미 프로비저닝된 경우) 노드가 계속 생성될 수 있습니다. 이러한 경우 포드가 생성되지 않으면 클러스터 자동 확장 처리는 10분 후에 노드를 삭제합니다.

할당량 문제 해결

프로비저닝 요청으로 프로비저닝된 모든 VM은 선점형 할당량을 사용합니다.

Accepted 상태인 ProvisioningRequests의 개수는 전용 할당량으로 제한됩니다. 프로젝트마다 할당량을 구성하며 리전별로 하나의 할당량 구성이 있습니다.

Google Cloud 콘솔에서 할당량 확인

Google Cloud 콘솔에서 할당량 한도 이름과 현재 사용량을 확인하려면 다음 단계를 수행합니다.

  1. Google Cloud 콘솔에서 할당량 페이지로 이동합니다.

    할당량으로 이동

  2. 필터 상자에서 측정항목 속성을 선택하고 active_resize_requests를 입력한 다음 Enter 키를 누릅니다.

기본값은 100입니다. 할당량을 늘리려면 할당량 조정 요청에 나열된 단계를 수행합니다.

프로비저닝 요청이 할당량으로 제한되는지 확인

프로비저닝 요청이 처리되는 데 예상보다 오래 걸리면 요청이 할당량으로 제한되지 않는지 확인합니다. 할당량을 추가로 요청해야 할 수 있습니다.

버전 1.29.2-gke.1181000 이상을 실행하는 클러스터의 경우 특정 할당량 제한으로 인해 요청이 처리되지 않는지 확인합니다.

kubectl describe provreq PROVISIONING_REQUEST_NAME \
    --namespace NAMESPACE

출력은 다음과 유사합니다.

…
Last Transition Time:  2024-01-03T13:56:08Z
    Message:               Quota 'NVIDIA_P4_GPUS' exceeded. Limit: 1.0 in region europe-west4.
    Observed Generation:   1
    Reason:                QuotaExceeded
    Status:                False
    Type:                  Provisioned
…

이 예시에서는 europe-west4 리전에 할당량이 충분하지 않으므로 GKE가 노드를 배포할 수 없습니다.

큐에 추가된 프로비저닝에서 flex-start로 노드 풀 마이그레이션

flex-start 소비 옵션은 Flex-start VM을 만듭니다. --enable-queued-provisioning 플래그를 사용하여 만든 기존 노드 풀을 flex-start를 사용하도록 마이그레이션하려면 다음 단계를 수행합니다.

  1. 노드 풀이 비어 있는지 확인합니다.

    kubectl get nodes -l cloud.google.com/gke-nodepool=NODEPOOL_NAME
    
  2. 노드 풀을 Flex-start VM으로 업데이트합니다.

    gcloud container node-pools update NODEPOOL_NAME \
      --cluster=CLUSTER_NAME --flex-start
    

이 작업은 다음을 수행합니다.

  • 노드 풀을 Flex-start VM 노드 풀로 업데이트합니다.
  • flex-start VM을 사용하는 노드의 가격 책정을 적용합니다.

1.32.2-gke.1652000 이상(Flex-start VM을 사용하는 노드의 최소 버전)에서 실행되는 클러스터의 모든 노드는 단기 업그레이드를 사용합니다.

다음 단계