mcpField
G
gpu-kubernetes-operations

gpu-kubernetes-operations

github.com/bagelholeクラウド・DevOps1.2k330 回インストール23 週間前に更新
リポジトリ

gpu-kubernetes-operations について

gpu-kubernetes-operationsは、GPUクラスターを管理するKubernetes運用者向けのスキルです。デバイス設定、共有、監視、自動スケーリング、障害対応を扱います。

主な機能

  1. 01NVIDIA GPU Operatorまたはデバイスプラグインの導入
  2. 02MIG分割とGPUタイムスライシングの設定
  3. 03GPUの健全性とメトリクスの監視
  4. 04GPUノードプールと自動スケーリングの設定
  5. 05スケジューリング、ドライバー、メモリ問題の調査

活用シーン

  1. 01AI推論やトレーニング用GPUノードプールの構築
  2. 02ワークロード間でのGPU共有
  3. 03本番GPUクラスターの監視とアラート設定
  4. 04Podの未スケジュールやGPU障害の診断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bagelhole/devops-security-agent-skills --skill gpu-kubernetes-operations

インストール後、Claude Code で/gpu-kubernetes-operationsを入力して読み込まれたか確認します。

詳細

GPU Kubernetes 運用

本番 AI ワークロード向けに、回復力が高く費用対効果に優れた GPU クラスターを運用します。

このスキルを使用する場面

  • AI の推論やトレーニング向けに Kubernetes で GPU ノードプールを設定する
  • NVIDIA デバイスプラグインと GPU オペレーターを構成する
  • MIG パーティショニングを実装して、複数のワークロードで GPU を共有する
  • GPU を考慮したオートスケーリングポリシーを構築する
  • DCGM と Prometheus で GPU の健全性を監視する
  • GPU のスケジューリング、ドライバー、OOM の問題をトラブルシューティングする

前提条件

  • GPU 対応ノードを備えた Kubernetes 1.28+ クラスター
  • NVIDIA GPU(A10、L4、A100、H100 など)
  • ノードに NVIDIA ドライバーがインストール済み(535+ を推奨)
  • オペレーターとプラグインのインストール用の Helm 3
  • メトリクス収集用の Prometheus スタック

NVIDIA GPU Operator のインストール

GPU Operator はドライバー、ツールキット、デバイスプラグイン、DCGM のデプロイを自動化します。

# Add NVIDIA Helm repo
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update

# Install GPU Operator
helm install gpu-operator nvidia/gpu-operator \
  --namespace gpu-operator \
  --create-namespace \
  --set driver.enabled=true \
  --set toolkit.enabled=true \
  --set devicePlugin.enabled=true \
  --set dcgmExporter.enabled=true \
  --set migManager.enabled=true \
  --set nodeStatusExporter.enabled=true \
  --version v24.3.0

# Verify installation
kubectl get pods -n gpu-operator
kubectl get nodes -o json | jq '.items[].status.allocatable["nvidia.com/gpu"]'

NVIDIA Device Plugin(スタンドアロン)

GPU Operator を使用しない場合は、デバイスプラグインを直接デプロイします。

# nvidia-device-plugin.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nvidia-device-plugin
  namespace: kube-system
spec:
  selector:
    matchLabels:
      name: nvidia-device-plugin
  template:
    metadata:
      labels:
        name: nvidia-device-plugin
    spec:
      tolerations:
        - key: nvidia.com/gpu
          operator: Exists
          effect: NoSchedule
      priorityClassName: system-node-critical
      containers:
        - name: nvidia-device-plugin
          image: nvcr.io/nvidia/k8s-device-plugin:v0.15.0
          securityContext:
            privileged: true
          env:
            - name: FAIL_ON_INIT_ERROR
              value: "false"
            - name: DEVICE_SPLIT_COUNT
              value: "1"
            - name: DEVICE_LIST_STRATEGY
              value: "envvar"
          volumeMounts:
            - name: device-plugin
              mountPath: /var/lib/kubelet/device-plugins
      volumes:
        - name: device-plugin
          hostPath:
            path: /var/lib/kubelet/device-plugins

MIG(Multi-Instance GPU)パーティショニング

MIG を使用すると、1 台の A100 または H100 を、分離された GPU インスタンスに分割できます。

# mig-config.yaml - ConfigMap for MIG Manager
apiVersion: v1
kind: ConfigMap
metadata:
  name: mig-parted-config
  namespace: gpu-operator
data:
  config.yaml: |
    version: v1
    mig-configs:
      # 7 small instances for inference microservices
      all-1g.10gb:
        - devices: all
          mig-enabled: true
          mig-devices:
            "1g.10gb": 7

      # 3 medium instances for mid-size models
      all-2g.20gb:
        - devices: all
          mig-enabled: true
          mig-devices:
            "2g.20gb": 3

      # Mixed: 1 large + 2 small
      mixed-inference:
        - devices: all
          mig-enabled: true
          mig-devices:
            "3g.40gb": 1
            "1g.10gb": 4

      # Full GPU for training (no partitioning)
      all-disabled:
        - devices: all
          mig-enabled: false
# Apply MIG profile to a node
kubectl label nodes gpu-node-01 nvidia.com/mig.config=all-1g.10gb --overwrite

# Verify MIG instances
kubectl exec -it nvidia-device-plugin-xxxxx -n kube-system -- nvidia-smi mig -lgi

# Check available MIG resources
kubectl get nodes gpu-node-01 -o json | jq '.status.allocatable | with_entries(select(.key | startswith("nvidia.com")))'
Pod での MIG スライスの要求
# pod-with-mig.yaml
apiVersion: v1
kind: Pod
metadata:
  name: inference-small
spec:
  containers:
    - name: model
      image: registry.internal/vllm-server:latest
      resources:
        limits:
          nvidia.com/mig-1g.10gb: 1
      # For medium slice:
      # nvidia.com/mig-2g.20gb: 1
      # For large slice:
      # nvidia.com/mig-3g.40gb: 1

GPU タイムスライシング

MIG に対応していない GPU(A10、L4)では、タイムスライシングを使って GPU を共有します。

# time-slicing-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: time-slicing-config
  namespace: gpu-operator
data:
  any: |-
    version: v1
    flags:
      migStrategy: none
    sharing:
      timeSlicing:
        renameByDefault: false
        failRequestsGreaterThanOne: false
        resources:
          - name: nvidia.com/gpu
            replicas: 4
# Apply time-slicing config
kubectl patch clusterpolicy/cluster-policy \
  --type merge \
  -p '{"spec":{"devicePlugin":{"config":{"name":"time-slicing-config","default":"any"}}}}'

# After applying, each physical GPU appears as 4 virtual GPUs
kubectl get nodes -o json | jq '.items[].status.allocatable["nvidia.com/gpu"]'
# Output: "4" per physical GPU

DCGM の監視

# dcgm-servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: dcgm-exporter
  namespace: gpu-operator
  labels:
    release: prometheus
spec:
  selector:
    matchLabels:
      app: nvidia-dcgm-exporter
  endpoints:
    - port: gpu-metrics
      interval: 15s
      path: /metrics
主な DCGM メトリクスとアラートルール
# gpu-alerts.yaml
groups:
  - name: gpu-health
    rules:
      - alert: GPUHighTemperature
        expr: DCGM_FI_DEV_GPU_TEMP > 85
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "GPU {{ $labels.gpu }} temperature above 85C on {{ $labels.node }}"

      - alert: GPUMemoryPressure
        expr: (DCGM_FI_DEV_FB_USED / DCGM_FI_DEV_FB_FREE) > 0.90
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "GPU memory above 90% on {{ $labels.node }} GPU {{ $labels.gpu }}"

      - alert: GPUECCErrors
        expr: increase(DCGM_FI_DEV_ECC_DBE_VOL_TOTAL[1h]) > 0
        labels:
          severity: critical
        annotations:
          summary: "Double-bit ECC errors detected on {{ $labels.node }} GPU {{ $labels.gpu }}"

      - alert: GPUXidErrors
        expr: increase(DCGM_FI_DEV_XID_ERRORS[5m]) > 0
        labels:
          severity: warning
        annotations:
          summary: "Xid error on {{ $labels.node }} GPU {{ $labels.gpu }}: {{ $labels.xid }}"

      - alert: GPULowUtilization
        expr: DCGM_FI_DEV_GPU_UTIL < 10 and on(pod) kube_pod_status_phase{phase="Running"} == 1
        for: 30m
        labels:
          severity: info
        annotations:
          summary: "GPU underutilized on {{ $labels.node }} - consider rightsizing"

      - alert: GPUDriverMismatch
        expr: count(count by (driver_version)(DCGM_FI_DRIVER_VERSION)) > 1
        labels:
          severity: warning
        annotations:
          summary: "Multiple GPU driver versions detected across cluster"

GPU ノードプールの構成

# gpu-nodepool.yaml
apiVersion: v1
kind: Node
metadata:
  labels:
    gpu-type: a100
    gpu-memory: "80gb"
    gpu-mig-capable: "true"
    node-role: gpu-inference
spec:
  taints:
    - key: nvidia.com/gpu
      value: "true"
      effect: NoSchedule
---
# Inference deployment with GPU scheduling
apiVersion: apps/v1
kind: Deployment
metadata:
  name: llm-inference
  namespace: ai-serving
spec:
  replicas: 3
  selector:
    matchLabels:
      app: llm-inference
  template:
    metadata:
      labels:
        app: llm-inference
    spec:
      tolerations:
        - key: nvidia.com/gpu
          operator: Exists
          effect: NoSchedule
      nodeSelector:
        gpu-type: a100
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchLabels:
                    app: llm-inference
                topologyKey: kubernetes.io/hostname
      containers:
        - name: vllm
          image: registry.internal/vllm-server:0.4.1
          resources:
            requests:
              nvidia.com/gpu: 1
              cpu: "4"
              memory: "32Gi"
            limits:
              nvidia.com/gpu: 1
              cpu: "8"
              memory: "64Gi"
          env:
            - name: CUDA_VISIBLE_DEVICES
              value: "all"

GPU オートスケーリング

# gpu-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: llm-inference-hpa
  namespace: ai-serving
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: llm-inference
  minReplicas: 2
  maxReplicas: 8
  metrics:
    - type: Pods
      pods:
        metric:
          name: DCGM_FI_DEV_GPU_UTIL
        target:
          type: AverageValue
          averageValue: "75"
    - type: Pods
      pods:
        metric:
          name: inference_queue_depth
        target:
          type: AverageValue
          averageValue: "10"
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 60
      policies:
        - type: Pods
          value: 2
          periodSeconds: 120
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Pods
          value: 1
          periodSeconds: 300
---
# Cluster Autoscaler config for GPU node pools
apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-autoscaler-config
  namespace: kube-system
data:
  config: |
    expander: priority
    scale-down-delay-after-add: 10m
    scale-down-unneeded-time: 10m
    skip-nodes-with-local-storage: false
    balance-similar-node-groups: true
    expendable-pods-priority-cutoff: -10
    gpu-total:
      - min: 2
        max: 16
        gpu: nvidia.com/gpu

スケジューリングのパターン

  • GPU の種類(A10/L4/A100/H100)に応じてノードアフィニティを使用します。
  • レイテンシが重要な推論とバッチトレーニングを分離します。
  • 可用性を確保するため、アンチアフィニティを設定してモデルレプリカを固定します。
  • フェイルオーバーとローリングアップデートに備えて余裕を確保します。

コストの最適化

  • 小規模な推論サービスには MIG スライスを優先します。
  • オフピークの時間帯にバッチジョブをスケジュールします。
  • 優先度の低いトラフィックを、より低コストのモデル階層にルーティングします。
  • トレーニングワークロードにはスポットインスタンスまたはプリエンプティブルインスタンスを使用します。
  • GPU 使用率を監視し、デプロイメントのリソースサイズを適正化します。

トラブルシューティング

症状確認項目対処方法
Pod が Pending のままGPU リソースに関するイベントを kubectl describe pod で確認するノードに割り当て可能な GPU があることを確認し、taint と toleration を確認します
推論中に CUDA OOM が発生するモデルが GPU メモリに対して大きすぎますバッチサイズを減らす、量子化を使用する、または MIG スライスを使用します
DCGM メトリクスがないServiceMonitor のラベルが一致しているかDCGM exporter Pod が実行中であることと、スクレイプ設定を確認します
アップグレード後にドライバーの不一致が発生する各ノードで nvidia-smi を実行するノードを cordon し、drain してからドライバーをアップグレードし、cordon を解除します
GPU が検出されないデバイスプラグイン Pod のログデバイスプラグインを再起動し、NVIDIA Container Toolkit を確認します
タイムスライシングが機能しないConfigMap は適用済みだが、GPU が増えていない設定変更後にデバイスプラグイン Pod を再起動します
ECC エラーが増加しているnvidia-smi -q -d ECCノードのドレインとハードウェア交換を手配します

関連スキル

コメント