이 문서에서는 Kueue 및 Topology Aware Scheduling (TAS)을 사용하여 Google Kubernetes Engine (GKE)에서 TPU 노드 풀을 프로비저닝하고 동적 슬라이스를 예약하는 방법을 설명합니다.
슬라이스 맞춤 리소스와 직접 상호작용하여 동적 슬라이싱을 사용할 수도 있습니다. 자세한 내용은 맞춤 스케줄러로 동적 슬라이싱 사용을 참고하세요.
이 안내를 따르기 전에 동적 슬라이싱 개념을 이해해야 합니다.
요구사항
GKE에서 동적 슬라이싱을 사용하려면 다음 요구사항을 충족해야 합니다.
- 신속 채널에서 버전 1.35.2-gke.1842000 이상의 Standard 클러스터를 사용합니다.
- Ironwood (TPU7x) 버전을 사용합니다.
- 노드에 Container-Optimized OS 이미지를 사용합니다.
- 증분 프로비저닝을 사용하려면 모든 용량 모드 예약을 사용하세요. 모든 용량 모드는 TPU Cluster Director에서 사용 설정하는 기능입니다.
시작하기 전에
시작하기 전에 다음 태스크를 수행했는지 확인합니다.
- Google Kubernetes Engine API를 사용 설정합니다. Google Kubernetes Engine API 사용 설정
- 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치했으면
gcloud components update명령어를 실행하여 최신 버전을 가져옵니다. 이전 gcloud CLI 버전에서는 이 문서의 명령어를 실행하지 못할 수 있습니다.
- 빠른 채널에서 버전 1.35.2-gke.1842000 이상의 기존 Standard 클러스터가 있는지 확인합니다. 새 클러스터를 만들려면 리전 클러스터 만들기를 참고하세요.
- 리전에 Ironwood (TPU7x)에 충분한 할당량이 있는지 확인합니다.
- 멀티슬라이스 워크로드를 실행하려면 v0.10.1 이상의 JobSet을 설치하세요.
- 모든 용량 모드에서 TPU 용량 요청
Kueue를 사용하여 GKE에서 동적 슬라이싱 사용
이 섹션에서는 GKE에서 동적 슬라이싱을 사용하는 워크플로를 설명합니다.
- 모든 용량 모드 예약의 토폴로지 및 상태 보기
- 클러스터에서 슬라이스 컨트롤러를 사용 설정합니다.
- TPU 노드 풀을 만듭니다.
- 슬라이스 커스텀 리소스를 만들도록 Kueue 구성
- Kueue를 사용하여 동적 슬라이싱에서 워크로드 실행
- 삭제합니다.
슬라이스 컨트롤러 사용 설정
동적 슬라이싱을 사용하려면 클러스터에서 슬라이스 컨트롤러를 사용 설정하세요.
클러스터를 업데이트합니다.
gcloud container clusters update CLUSTER_NAME \ --location=LOCATION \ --enable-slice-controller다음을 바꿉니다.
CLUSTER_NAME: 클러스터 이름입니다.LOCATION: 사용 가능한 TPU 용량이 있는 리전입니다.
kubectl명령어로 클러스터와 통신할 수 있도록 사용자 인증 정보를 가져옵니다.gcloud config set container/cluster CLUSTER_NAME gcloud container clusters get-credentials CLUSTER_NAME \ --location=LOCATION다음 명령어의 출력에서
slices.accelerator.gke.io값이 있는지 확인합니다.kubectl get crd slices.accelerator.gke.io출력은 다음과 비슷합니다.
slices.accelerator.gke.io 2026-01-09T23:58:02Z
증분 프로비저닝으로 노드 풀 만들기
이 섹션에서는 증분 프로비저닝을 사용하여 TPU 노드 풀을 만드는 방법을 설명합니다. GKE는 모든 TPU 용량을 TPU VM 또는 하위 블록의 16노드 그룹의 노드 풀로 변환합니다. GKE는 호스트 머신의 정상 부분에 노드를 배치하고 비정상 머신이 복구되는 동안 점진적으로 프로비저닝하여 정상 VM 16개를 모두 찾을 수 없는 경우에도 이러한 노드 풀을 프로비저닝합니다.
다음 중 하나에 속하도록 노드 풀을 타겟팅할 수 있습니다.
- 모든 용량 모드 예약에 노출되는 특정 TPU 블록입니다. 차단 타겟팅을 사용하면 GKE가 지정된 블록 내에서 사용 가능한 모든 하위 블록에 노드 풀을 만들 수 있습니다.
- 더 세부적인 제어를 위한 TPU의 특정 하위 블록 또는 특정 16노드 TPU VM 그룹입니다.
워크로드 정책 만들기
Ironwood (TPU7x)로 TPU 슬라이스 노드 풀을 만들려면 먼저 accelerator-topology-mode 필드가 provision_only로 설정된 워크로드 정책을 만들어야 합니다. 이 설정은 증분 프로비저닝 프로세스를 트리거합니다.
워크로드 정책을 만듭니다.
gcloud compute resource-policies create workload-policy WORKLOAD_POLICY_NAME \
--project=PROJECT_ID \
--region=REGION \
--type=HIGH_THROUGHPUT \
--accelerator-topology=4x4x4 \
--accelerator-topology-mode=provision_only
다음을 바꿉니다.
WORKLOAD_POLICY_NAME: 워크로드 정책의 이름입니다.PROJECT_ID: Google Cloud 프로젝트 ID입니다.REGION: 워크로드 정책의 리전입니다.
이 명령어에서 다음을 실행합니다.
- 단일 하위 블록 내의 총 칩 수와 일치하도록 항상
accelerator-topology필드를4x4x4로 설정합니다. - 증분 프로비저닝 프로세스가 트리거되도록 항상
accelerator-topology-mode필드를provision_only로 설정하세요.provision_only필드가 설정되면 노드 풀은 ICI 또는 OCS 링크를 형성하지 않고 TPU 노드를 프로비저닝합니다.
블록 또는 하위 블록에 속하도록 노드 풀 타겟팅
'전체 용량' 모드 예약 내에서 특정 하위 블록 또는 블록을 타겟팅할 수 있습니다.
- 블록 타겟팅: 각 노드 풀은 지정된 블록의 용량을 사용합니다. GKE는 해당 블록의 사용 가능한 하위 블록 내에 노드 풀을 배치합니다. 사용하려는 블록에 하위 블록이 있는 만큼 노드 풀을 만들어야 합니다.
하위 블록 타겟팅: 각 노드 풀은 사용 가능한 특정 하위 블록에 매핑됩니다. 하위 블록 타겟팅을 사용하는 경우 하나 이상의 VM이 정상이면 GKE가 노드 풀을 만듭니다. 증분 프로비저닝은 모든 노드가 지정된 하위 블록 내에 배치되도록 하는 데 도움이 됩니다.
Block
예약의 블록 이름과 블록에서 사용 가능한 하위 블록 수를 가져오려면 모든 용량 모드 예약의 토폴로지 및 상태 보기 문서에서 다음 단계를 완료하세요.
모든 예약 블록을 나열하고
name:필드의 값을 복사하여 블록의 이름을 식별합니다. 이 값은 이 문서에 있는 블록 또는BLOCK_NAME의 이름입니다.예약 블록을 설명하고
reservationSubBlockCount필드의 값을 식별하여 만들 노드 풀 수를 확인합니다. 이 값은 사용 가능한 하위 블록 수입니다. 예를 들어reservationSubBlockCount: 4값은 블록에 사용할 수 있는 하위 블록이 4개 있으며 별도의 노드 풀 4개를 만들어야 함을 나타냅니다.
예약 경로를 설정합니다.
export RESERVATION_PATH="projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME"다음을 바꿉니다.
RESERVATION_NAME: TPU 예약의 이름입니다.BLOCK_NAME: 블록의 이름입니다.
이전 단계에서 식별된 각 하위 블록에 대해 노드 풀을 만듭니다. 예를 들어 개수가
4이면 이 명령어를 네 번 실행합니다. 각 노드 풀에 고유한 이름을 사용합니다.gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --node-locations=ZONE \ --machine-type=tpu7x-standard-4t \ --num-nodes=16 \ --placement-policy=WORKLOAD_POLICY_NAME \ --reservation-affinity=specific \ --reservation=${RESERVATION_PATH}다음을 바꿉니다.
NODE_POOL_NAME: 새 노드 풀의 이름입니다.CLUSTER_NAME: GKE 클러스터의 이름입니다.WORKLOAD_POLICY_NAME: 생성한 워크로드 정책의 이름입니다.ZONE: 노드 풀의 영역입니다(예:us-central1-a).
하위 블록
블록 이름과 사용 가능한 하위 블록의 ID를 가져오려면 모든 용량 모드 예약의 토폴로지 및 상태 보기 문서에서 다음 단계를 완료하세요.
차단 이름을 확인하려면 모든 예약 차단을 나열하고
name:필드의 값을 복사합니다. 이 값은 이 문서에 있는 블록 또는BLOCK_NAME의 이름입니다.하위 블록의 이름을 식별하려면 블록의 모든 하위 블록을 나열하고
reservationSubBlocks아래 각 항목의name:필드에 있는 값을 복사합니다. 이 값은 이 문서에 나오는 하위 블록 또는SUBBLOCK_NAME의 이름입니다.
예약 경로를 설정합니다.
export RESERVATION_PATH="projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME/reservationSubBlocks/SUBBLOCK_NAME"다음을 바꿉니다.
RESERVATION_NAME: TPU 예약의 이름입니다.BLOCK_NAME: 블록의 이름입니다.SUBBLOCK_NAME: 하위 블록의 이름입니다.
노드 풀을 만듭니다.
gcloud container node-pools create NODE_POOL_NAME \ --project=PROJECT_ID \ --cluster=CLUSTER_NAME \ --node-locations=ZONE \ --machine-type=tpu7x-standard-4t \ --num-nodes=16 \ --placement-policy=WORKLOAD_POLICY_NAME \ --reservation-affinity=specific \ --reservation=${RESERVATION_PATH}다음을 바꿉니다.
NODE_POOL_NAME: 새 노드 풀의 고유한 이름(예:sub-block-pool-1)PROJECT_ID: Google Cloud 프로젝트 ID입니다.CLUSTER_NAME: GKE 클러스터의 이름입니다.ZONE: 노드 풀의 영역입니다(예:us-central2-b).WORKLOAD_POLICY_NAME: 생성한 워크로드 정책의 이름입니다.
이 단계에서는 노드가 생성되지만 칩 간 상호 연결 (ICI) 링크는 아직 활성화되지 않습니다. 따라서 이러한 노드 풀에서 직접 워크로드를 실행할 수 없습니다.
슬라이스를 형성하고 워크로드를 예약할 수 있도록 필요한 모든 ICI 링크를 사용 설정하려면 다음 방법 중 하나를 사용하여 동적 슬라이스를 만드세요.
- 슬라이스 커스텀 리소스를 만듭니다. 포드 대신 슬라이스 컨트롤러가 활성화하는 지정된 토폴로지를 정의하는 슬라이스 커스텀 리소스를 사용합니다.
- Kueue 및 TAS로 GKE 워크로드를 예약합니다. Kueue는 Slice 커스텀 리소스의 생성 및 삭제를 자동으로 처리합니다. Kueue에서 만든 슬라이스 커스텀 리소스를 수동으로 수정하지 마세요.
Kueue 및 TAS로 동적 슬라이스 만들기
이 섹션에서는 Kueue 및 TAS를 사용하여 GKE 워크로드를 예약합니다.
동적 슬라이싱을 위한 JobSet 및 Kueue 리소스 설치
JobSet 설치:
helm install jobset oci://registry.k8s.io/jobset/charts/jobset \ --version 0.11.1 \ --namespace jobset-system \ --create-namespace \ --set controller.resources.requests.cpu=4 \ --set controller.resources.requests.memory=16GiKueue를 설치합니다.
helm install kueue oci://registry.k8s.io/kueue/charts/kueue \ --version 0.16.6 \ --namespace kueue-system \ --create-namespace \ --wait \ --set controllerManager.replicas=3 \ --set controllerManager.manager.resources.requests.cpu=16 \ --set controllerManager.manager.resources.requests.memory=64GiKueue 슬라이스 컨트롤러를 설치하려면 다음 매니페스트를
slice-controller.yaml로 저장합니다.apiVersion: v1 kind: Namespace metadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: slice-controller control-plane: controller-manager name: slice-controller-system --- apiVersion: v1 kind: ServiceAccount metadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: slice-controller control-plane: controller-manager name: slice-controller-controller-manager namespace: slice-controller-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: slice-controller control-plane: controller-manager name: slice-controller-leader-election-role namespace: slice-controller-system rules: - apiGroups: - "" resources: - configmaps verbs: - get - list - watch - create - update - patch - delete - apiGroups: - coordination.k8s.io resources: - leases verbs: - get - list - watch - create - update - patch - delete - apiGroups: - "" resources: - events verbs: - create - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: control-plane: controller-manager name: slice-controller-manager-role rules: - apiGroups: - "" resources: - events verbs: - create - patch - update - watch - apiGroups: - "" resources: - nodes - pods verbs: - get - list - watch - apiGroups: - "" resources: - secrets verbs: - get - list - update - watch - apiGroups: - accelerator.gke.io resources: - slices verbs: - create - delete - get - list - patch - update - watch - apiGroups: - accelerator.gke.io resources: - slices/finalizers verbs: - update - apiGroups: - admissionregistration.k8s.io resources: - mutatingwebhookconfigurations verbs: - get - list - update - watch - apiGroups: - batch resources: - jobs verbs: - get - list - patch - update - watch - apiGroups: - jobset.x-k8s.io resources: - jobsets verbs: - get - list - patch - update - watch - apiGroups: - leaderworkerset.x-k8s.io resources: - leaderworkersets verbs: - get - list - patch - update - watch - apiGroups: - kueue.x-k8s.io resources: - admissionchecks verbs: - get - list - watch - apiGroups: - kueue.x-k8s.io resources: - admissionchecks/status - workloads/status verbs: - get - patch - update - apiGroups: - kueue.x-k8s.io resources: - workloads verbs: - create - get - list - patch - update - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: control-plane: controller-manager name: slice-controller-metrics-auth-role rules: - apiGroups: - authentication.k8s.io resources: - tokenreviews verbs: - create - apiGroups: - authorization.k8s.io resources: - subjectaccessreviews verbs: - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: control-plane: controller-manager name: slice-controller-metrics-reader rules: - nonResourceURLs: - /metrics verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: slice-controller control-plane: controller-manager name: slice-controller-leader-election-rolebinding namespace: slice-controller-system roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: slice-controller-leader-election-role subjects: - kind: ServiceAccount name: slice-controller-controller-manager namespace: slice-controller-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: slice-controller control-plane: controller-manager name: slice-controller-manager-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: slice-controller-manager-role subjects: - kind: ServiceAccount name: slice-controller-controller-manager namespace: slice-controller-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: control-plane: controller-manager name: slice-controller-metrics-auth-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: slice-controller-metrics-auth-role subjects: - kind: ServiceAccount name: slice-controller-controller-manager namespace: slice-controller-system --- apiVersion: v1 kind: Secret metadata: labels: control-plane: controller-manager name: slice-controller-webhook-server-cert namespace: slice-controller-system --- apiVersion: v1 kind: Service metadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: slice-controller control-plane: controller-manager name: slice-controller-controller-manager-metrics-service namespace: slice-controller-system spec: ports: - name: https port: 8443 protocol: TCP targetPort: 8443 selector: app.kubernetes.io/name: slice-controller control-plane: controller-manager --- apiVersion: v1 kind: Service metadata: labels: control-plane: controller-manager name: slice-controller-webhook-service namespace: slice-controller-system spec: ports: - port: 443 protocol: TCP targetPort: 9443 selector: control-plane: controller-manager --- apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: slice-controller control-plane: controller-manager name: slice-controller-controller-manager namespace: slice-controller-system spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: slice-controller control-plane: controller-manager template: metadata: annotations: kubectl.kubernetes.io/default-container: manager labels: app.kubernetes.io/name: slice-controller control-plane: controller-manager spec: containers: - args: - --metrics-bind-address=:8443 - --leader-elect - --health-probe-bind-address=:8081 - --zap-log-level=3 - --feature-gates=UseRetryMechanismForSliceCreation=true - --activation-timeout=6m command: - /manager image: tpuongke/kueue-slice-controller:latest livenessProbe: httpGet: path: /healthz port: 8081 initialDelaySeconds: 15 periodSeconds: 20 name: manager ports: - containerPort: 9443 name: webhook-server protocol: TCP readinessProbe: httpGet: path: /readyz port: 8081 initialDelaySeconds: 5 periodSeconds: 10 resources: limits: cpu: 12000m memory: 32Gi requests: cpu: 8000m memory: 16Gi securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL volumeMounts: - mountPath: /tmp/k8s-webhook-server/serving-certs name: cert readOnly: true securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault serviceAccountName: slice-controller-controller-manager terminationGracePeriodSeconds: 10 volumes: - name: cert secret: defaultMode: 420 secretName: slice-controller-webhook-server-cert --- apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: labels: control-plane: controller-manager name: slice-controller-mutating-webhook-configuration webhooks: - admissionReviewVersions: - v1 clientConfig: service: name: slice-controller-webhook-service namespace: slice-controller-system path: /mutate-batch-v1-job failurePolicy: Fail name: mjob.kb.io rules: - apiGroups: - batch apiVersions: - v1 operations: - CREATE resources: - jobs sideEffects: None - admissionReviewVersions: - v1 clientConfig: service: name: slice-controller-webhook-service namespace: slice-controller-system path: /mutate-jobset-x-k8s-io-v1alpha2-jobset failurePolicy: Fail name: mjobset.kb.io rules: - apiGroups: - jobset.x-k8s.io apiVersions: - v1alpha2 operations: - CREATE resources: - jobsets sideEffects: None - admissionReviewVersions: - v1 clientConfig: service: name: slice-controller-webhook-service namespace: slice-controller-system path: /mutate-leaderworkerset-x-k8s-io-v1-leaderworkerset failurePolicy: Fail name: mleaderworkerset.kb.io rules: - apiGroups: - leaderworkerset.x-k8s.io apiVersions: - v1 operations: - CREATE resources: - leaderworkersets sideEffects: Noneslice-controller.yaml매니페스트를 적용합니다.kubectl apply -f slice-controller.yaml동적 슬라이싱을 위해 Kueue를 구성하려면 다음 매니페스트를
dynamic-slice-topology.yaml로 저장합니다.apiVersion: kueue.x-k8s.io/v1beta1 kind: Topology metadata: name: superslice-topology spec: levels: # Label to identify the physical block a sub-block belongs to. # Only sub-blocks from the same block can form a slice. - nodeLabel: cloud.google.com/gce-topology-block # Label to identify individual TPU sub-blocks (4x4x4 topology). - nodeLabel: cloud.google.com/gke-tpu-partition-4x4x4-id # Standard Kubernetes label for individual nodes. # Required to assign Pods to specific VMs. - nodeLabel: kubernetes.io/hostname --- apiVersion: kueue.x-k8s.io/v1beta1 kind: ResourceFlavor metadata: name: superslice-rf spec: nodeLabels: cloud.google.com/gke-tpu-accelerator: tpu7x topologyName: superslice-topology --- apiVersion: kueue.x-k8s.io/v1beta1 kind: AdmissionCheck metadata: name: superslice-ac spec: controllerName: accelerator.gke.io/slice --- apiVersion: kueue.x-k8s.io/v1beta1 kind: ClusterQueue metadata: name: cq spec: namespaceSelector: {} admissionChecks: - superslice-ac resourceGroups: - coveredResources: - google.com/tpu flavors: - name: superslice-rf resources: - name: google.com/tpu nominalQuota: "999999" # modeling unlimited quota --- apiVersion: kueue.x-k8s.io/v1beta1 kind: LocalQueue metadata: name: lq namespace: default spec: clusterQueue: cqdynamic-slice-topology.yaml매니페스트를 적용합니다.kubectl apply -f dynamic-slice-topology.yaml이 매니페스트에서는 다음 리소스를 정의하여 동적 슬라이싱을 위해 Kueue를 구성합니다.
- Ironwood (TPU7x) 동적 슬라이스 토폴로지 (
superslice-topology): 토폴로지는 Kueue가 동적 슬라이스 워크로드를 예약할 때 고려하는 수준을 정의합니다. 이러한 수준은 다음과 같습니다.cloud.google.com/gce-topology-block라벨: 이 수준은 어떤 하위 블록이 어떤 블록에 속하는지 이해하는 데 필요합니다. 동일한 블록의 하위 블록만 슬라이스를 형성할 수 있기 때문입니다.cloud.google.com/gke-tpu-partition-4x4x4-id라벨: 이 수준은 개별 Ironwood (TPU7x) 하위 블록 (4x4x4토폴로지)을 나타냅니다.kubernetes.io/hostname라벨: 이 수준은 포드를 특정 VM에 할당하고 라벨과 테인트를 관찰하는 데 필요합니다.
- Ironwood (TPU7x) SuperSlice ResourceFlavor (
superslice-rf): Ironwood (TPU7x) 하위 블록의 리소스 버전에는 Ironwood (TPU7x) 머신이 있는 노드와 일치하는cloud.google.com/gke-tpu-accelerator: tpu7x라벨이 포함됩니다. - SuperSlice AdmissionCheck (
superslice-ac): 이 허용 확인은 GKE 슬라이스 컨트롤러가 슬라이스가 활성화되었음을 확인할 때까지 Kueue가 워크로드를 예약하지 않도록 합니다. 허용 확인은 먼저 정의된 다음 동적 슬라이싱 워크로드를 처리하는ClusterQueue에 추가됩니다. - ClusterQueue (
cq) 및 LocalQueue (lq): 이러한 필드는google.com/tpu리소스를 관리합니다.cqClusterQueue에는superslice-ac승인 확인이 포함됩니다.google.com/tpu의nominalQuota은 다음 두 가지 방법으로 구성할 수 있습니다.- 특정 할당량: 공정 공유 및 할당량 관리를 위해 기존 용량과 일치하도록
nominalQuota를 설정합니다. - 무제한 할당량:
nominalQuota을"999999"와 같은 매우 높은 값으로 설정하여 무제한 할당량을 모델링합니다. TAS 및 동적 슬라이싱에 집중하기 위해 이 구성은 Kueue의 할당량 관리 기능을 우회합니다.
- 특정 할당량: 공정 공유 및 할당량 관리를 위해 기존 용량과 일치하도록
- Ironwood (TPU7x) 동적 슬라이스 토폴로지 (
하위 블록 상태 선택 정의
표준 노드 상태 및 준비 상태 외에도 GKE는 cloud.google.com/gke-tpu-partition-4x4x4-state 라벨을 사용하여 각 하위 블록의 특정 상태를 노출합니다.
이 라벨을 사용하면 GKE에서 TPU 링크 상태와 같은 슬라이스 형성에 영향을 미치는 요인을 고려할 수 있습니다.
cloud.google.com/gke-tpu-partition-4x4x4-state 라벨의 값은 다음과 같이 정의할 수 있습니다.
HEALTHY: 인프라가 정상입니다.DEGRADED: OCS 링크 저하 등으로 인해 하위 블록의 인프라가 저하된 상태입니다. 하위 블록은 여전히 슬라이스를 형성할 수 있지만 전반적인 성능은 정상적인 하위 블록에 비해 낮을 수 있습니다.UNHEALTHY: 하위 블록이 비정상이며 슬라이스를 형성할 수 없습니다.
Kueue 슬라이스 컨트롤러 웹훅은 워크로드에 특정 하위 블록 상태 요구사항이 포함되어 있는지 확인합니다. 선호도가 표시되지 않으면 웹훅이 기본 노드 어피니티를 삽입합니다.
동작은 다음과 같습니다.
cloud.google.com/gke-tpu-partition-4x4x4-state라벨을 타겟팅하는nodeSelector또는nodeAffinity이 있으면 변경되지 않습니다.이러한 라벨 구성이 없으면 웹훅은 사용 가능한 하위 블록만 사용되도록 다음 기본 노드 어피니티를 삽입합니다.
nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: cloud.google.com/gke-tpu-partition-4x4x4-state operator: In values: - "HEALTHY" - "DEGRADED"
다음 섹션에는 서로 다른 하위 블록 상태 구성을 지정하도록 cloud.google.com/gke-tpu-partition-4x4x4-state 라벨이 구성된 예가 포함되어 있습니다.
Kueue를 사용하여 동적 슬라이싱에서 테스트 워크로드 실행
이 섹션에서는 Kueue 및 TAS를 사용하여 동적 슬라이싱에 워크로드를 배포하는 방법을 설명합니다. 여기에는 동적 슬라이스 워크로드와 여러 슬라이스로 구성된 워크로드를 만드는 방법을 보여주는 예가 포함되어 있습니다. 워크로드는 JobSet으로 제출됩니다.
예 1: 단일 워크로드가 단일 동적 슬라이스를 사용함
다음 예에서는 12개의 하위 블록으로 구성된 4x12x16 토폴로지가 있는 슬라이스를 사용하여 워크로드를 만드는 방법을 설명합니다. 포드 수는 노드당 4개의 칩을 기준으로 (4 * 12 * 16) / 4 = 192개로 계산되었습니다.
다음 매니페스트를
big-super-slice.yaml로 저장합니다.apiVersion: jobset.x-k8s.io/v1alpha2 kind: JobSet metadata: name: big-super-slice labels: kueue.x-k8s.io/queue-name: lq annotations: spec: replicatedJobs: - name: job-jax replicas: 1 template: spec: parallelism: 192 # pods per slice calculation: 4*12*16 / 4 = 192 completions: 192 backoffLimit: 10 template: metadata: annotations: cloud.google.com/gke-tpu-slice-topology: 4x12x16 spec: tolerations: - key: "google.com/tpu" operator: "Equal" value: "present" effect: "NoSchedule" nodeSelector: cloud.google.com/gke-tpu-accelerator: tpu7x containers: - name: jax image: python:latest command: - bash - -c - | printenv pip install "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html python -c 'import jax; print("Global device count:", jax.device_count(), "Local device count:", jax.local_device_count())' resources: limits: google.com/tpu: 4 restartPolicy: Never이 매니페스트에서 다음 주석은 Kueue에 다음을 구성할 슬라이스 특성과 토폴로지를 알려줍니다.
cloud.google.com/gke-tpu-slice-topology:"4x12x16"을 동적 슬라이스 토폴로지로 지정합니다.tpu7x가속기 토폴로지 요구사항에는 다음 규칙이 포함됩니다.- 최소 토폴로지는
4x4x4입니다. - 토폴로지는
AxBxC형식의 3차원 문자열이어야 합니다. 예를 들면4x8x8입니다. - 각 치수 (A, B, C)는 4의 배수여야 합니다.
- 차원은 비감소 순서(A <= B <= C)로 정렬해야 합니다. 예를 들어
4x8x4은 유효하지 않으며4x4x8이어야 합니다. - 크기의 곱 (ABC)은 9,216을 초과해서는 안 됩니다.
- 지원되는 가장 큰 슬라이스 토폴로지에는 최대 32개의 하위 블록이 포함될 수 있습니다. 예를 들어 하위 블록이 32개인
8x16x16, 하위 블록이 30개인8x12x20, 하위 블록이 27개인12x12x12는 허용된 한도 내에 있습니다.
- 최소 토폴로지는
cloud.google.com/gke-tpu-accelerator: tpu7x: Ironwood (TPU7x)을 실행하는 VM에 Pod를 예약합니다.kueue.x-k8s.io/queue-name: JobSet을 Kueue LocalQueue에 할당합니다.- 웹훅은
HEALTHY및DEGRADED노드가 사용되도록 기본 노드 어피니티를 삽입합니다.
big-super-slice.yaml매니페스트를 적용합니다.kubectl apply -f big-super-slice.yaml매니페스트를 적용하면 Kueue가
big-super-slice라는JobSet를 만듭니다. 그런 다음 Kueue는4x12x16토폴로지를 사용하여 단일 동적 슬라이스를 형성하려고 시도합니다. 슬라이스가 활성화되면 Kueue가 워크로드를 허용하고 192개의 포드가 노드에 예약되어 워크로드를 실행하는 동적 슬라이스를 형성합니다.
예 2: 복제본이 두 개 이상인 워크로드
다음 예에서는 각각 HEALTHY 노드만 타겟팅하는 4개의 하위 블록으로 구성된 동적 슬라이스 2개를 사용하는 워크로드를 만드는 방법을 보여줍니다.
다음 매니페스트를
two-super-slices.yaml로 저장합니다.apiVersion: jobset.x-k8s.io/v1alpha2 kind: JobSet metadata: name: two-super-slices labels: kueue.x-k8s.io/queue-name: lq annotations: spec: replicatedJobs: - name: job-jax replicas: 2 template: spec: parallelism: 64 # Pods per slice calculation: (4*8*8) / 4 = 64 completions: 64 backoffLimit: 10 template: metadata: annotations: cloud.google.com/gke-tpu-slice-topology: 4x8x8 spec: tolerations: - key: "google.com/tpu" operator: "Equal" value: "present" effect: "NoSchedule" nodeSelector: cloud.google.com/gke-tpu-accelerator: tpu7x cloud.google.com/gke-tpu-partition-4x4x4-state: "HEALTHY" containers: - name: jax image: python:latest command: - bash - -c - | printenv pip install "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html python -c 'import jax; print("Global device count:", jax.device_count(), "Local device count:", jax.local_device_count())' resources: limits: google.com/tpu: 4 restartPolicy: Nevertwo-super-slices.yaml매니페스트를 적용합니다.kubectl apply -f two-super-slices.yaml
이 매니페스트에서는 replicatedJobs 필드에 replicas: 2를 설정합니다.
매니페스트를 적용하면 Kueue는 4x8x8 토폴로지를 사용하여 두 개의 별도 슬라이스를 형성하려고 시도합니다. Kueue는 jobset.spec.replicatedJobs[].replicas에 정의된 각 복제본에 대해 동적 슬라이스를 만듭니다.
n 복제본이 지정되면 Kueue는 워크로드에 대해 n 동적 슬라이스를 만들고 모든 슬라이스가 활성화될 때까지 기다린 후 워크로드를 허용합니다.
슬라이스 모니터링
GKE 시스템 측정항목을 사용하여 슬라이스 상태를 확인하고 슬라이스 측정항목을 모니터링할 수 있습니다.
슬라이스 상태 모니터링
동적 슬라이스의 상태를 확인하려면 다음 명령어를 실행하세요.
kubectl describe slice SLICE_NAME
SLICE_NAME을 슬라이스 이름으로 바꿉니다. 슬라이스 이름은 일반적으로 JobSet 이름과 복제본 색인에서 파생됩니다. 예 1의 경우 Kueue에서 생성된 슬라이스의 이름은 default-jobset-big-super-slice-yyyyy-job-jax-0과 유사합니다.
출력은 다음과 비슷합니다.
Name: test-slice
Namespace:
Labels: <none>
Annotations: <none>
API Version: accelerator.gke.io/v1beta1
Kind: Slice
Metadata:
Creation Timestamp: 2026-02-12T23:44:28Z
Finalizers:
accelerator.gke.io/slice-finalizer
Generation: 1
Resource Version: 1770939905695871008
UID: 6dbbfe14-4486-4462-864d-e078d0ca8b5b
Spec:
Partition Ids:
5eae6a4f59d59cf30a9bf49de618eb2b
Topology: 4x4x4
Type: tpu7x
Status:
Conditions:
Last Transition Time: 2026-02-12T23:45:05Z
Message:
Reason: ACTIVE
Status: True
Type: Ready
Last Transition Time: 2026-02-12T23:45:05Z
Message: NodeLabelingCompleted
Reason: NodeLabelIsAdded
Status: True
Type: NodeLabeled
Events: <none>
슬라이스 이름은 기본 Compute Engine 리소스 이름 지정 규칙과의 호환성을 보장하기 위해 다음 규칙을 준수합니다.
- 템플릿:
{namespace}-jobset-{jobset.metadata.name}-kueueHash[5-character]-{jobset.spec.replicatedJobs[].name}-sliceIndex. - 길이: 이름이 49자 이하여야 합니다. 컨트롤러는 하이픈과 8자리 클러스터 해시를 추가하여 63자 제한이 있는 Compute Engine 리소스 이름을 만듭니다.
- 형식: 이름이 정규 표현식
^[a-z]([-a-z0-9]*[a-z0-9])?$와 일치합니다. 이름에는 다음과 같은 특성이 있습니다.- 소문자로 시작합니다.
- 소문자, 숫자, 하이픈 (-)만 포함합니다.
- 소문자 또는 숫자로 끝나야 합니다 (하이픈으로 끝나면 안 됨).
슬라이스의 측정항목 모니터링
슬라이스의 상태를 노출하는 다음 GKE 시스템 측정항목을 모니터링할 수 있습니다.
kubernetes.io/accelerator/slice/statekubernetes.io/accelerator/partition/statekubernetes.io/accelerator/slice/deformation_durationskubernetes.io/accelerator/slice/formation_durations
측정항목에 대한 자세한 내용은 GKE 시스템 측정항목을 참고하세요.
삭제
예기치 않은 요금이 청구되지 않도록 하려면 노드 풀을 삭제하기 전에 슬라이스를 삭제하세요.
JobSet을 삭제합니다. 이 작업은 Kueue가 연결된 슬라이스 커스텀 리소스를 삭제하도록 트리거합니다.
kubectl delete jobset JOBSET_NAMEJOBSET_NAME을 JobSet 이름(예:big-super-slice)으로 바꿉니다.TPU 노드 풀을 삭제합니다.
gcloud container node-pools delete NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location=LOCATION
(선택사항) 자체 스케줄러로 동적 슬라이싱 사용
이 문서에서는 Kueue 및 TAS 사용에 중점을 둡니다. 하지만 자체 맞춤 스케줄러로 동적 슬라이싱을 관리할 수도 있습니다. 다른 스케줄러를 사용하려면 슬라이스 커스텀 리소스 참조 정보를 따르세요.
다음 단계
- TPU Cluster Director에 대해 자세히 알아보세요.
- 모든 용량 모드의 TPU로 유지보수 이벤트를 관리하는 방법을 알아보세요.