Contents
1️⃣ GPU スケジューラとリソース割り当ての実装
Point
Kubernetes の GPU デバイスプラグイン と Node Feature Discovery (NFD) を組み合わせることで、ノードごとの GPU 型番・メモリ容量を自動でラベル付与し、スケジューラが正確にリソースを割り当てられます。
Reason
GPU はモデルサイズやバッチ数によって必要なメモリ量が大きく変わります。ノード間のスペック差を認識できないと、Pod が起動直後に OOM キラーに止められるケースが頻発します。
実装例
| 手順 | コマンド / 設定 | 説明 |
|---|---|---|
| 1. NFD のインストール | helm repo add nfd https://kubernetes-sigs.github.io/node-feature-discovery/chartshelm install nfd-node-features nfd/nfd-worker |
GPU のモデル名・メモリ容量を feature.node.kubernetes.io/gpu.* ラベルに変換 |
| 2. NVIDIA GPU Operator の導入(GPU デバイスプラグイン) | helm repo add nvidia https://helm.ngc.nvidia.com/nvidiahelm install gpu-operator nvidia/gpu-operator --set driver.enabled=true |
デバイスプラグイン v1 が自動でデプロイされ、nvidia.com/gpu リソースが利用可能になる |
| 3. カスタムスケジューラ(優先度プラグイン) | yaml<br>apiVersion: scheduling.k8s.io/v1<br>kind: PriorityClass<br>metadata:<br> name: gpu-high-mem<br>value: 1000000<br>globalDefault: false<br>description: "GPU メモリが多いノードを優先"<br> |
PriorityClass と NFD のラベル (feature.node.kubernetes.io/gpu.memory) を組み合わせてスコアリング |
参考リンク
2️⃣ 前提条件と環境構築
| 必要ツール | 推奨バージョン | 入手方法 |
|---|---|---|
kubectl |
≥ 1.28 | curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/$(uname -s | tr '[:upper:]' '[:lower:]')/amd64/kubectl" |
helm |
≥ 3.12 | brew install helm(macOS)/curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash |
| Docker Engine / Podman (BuildKit 推奨) | 最新安定版 | 各 OS の公式インストール手順に従う |
| GitOps ツール | Argo CD または Flux v2 | kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml など |
Tip: 各ツールのインストール手順は公式サイトに最新情報が掲載されています。バージョン管理を行う場合は
asdfやbrewのbrew list --versionsを活用してください。
2‑1️⃣ GPU 対応クラスターの作成
(a) ローカル開発環境(K3s + NVIDIA GPU Operator)
|
1 2 3 4 5 6 7 8 |
# K3s 本体をインストール(Traefik は無効化) curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik" sh - # Helm リポジトリ追加・GPU Operator デプロイ helm repo add nvidia https://helm.ngc.nvidia.com/nvidia helm install gpu-operator nvidia/gpu-operator \ --set driver.version=550.54.14 # ドライバは NVIDIA の LTS バージョンを指定 |
(b) パブリッククラウド(マネージド Kubernetes)
| クラウド | GPU ノード作成例 |
|---|---|
| Amazon EKS | eksctl create nodegroup --cluster=my-cluster --name=gpu-ng --node-type=p4d.24xlarge --nodes=1 --nodes-min=0 --nodes-max=5 |
| Google GKE | gcloud container clusters create my-gke --accelerator type=nvidia-tesla-a100,count=1 --zone us-central1-a --num-nodes 1 |
| Microsoft Azure AKS | az aks create -g rg-ml -n aks-ml --node-vm-size Standard_ND40rs_v2 --enable-addons monitoring --generate-ssh-keys |
注記: 2025/2026 年に予定されている「AI Toolchain Operator」や「Extended Resource Scheduler」は、執筆時点では正式リリースが確認できません。代わりに上記の GPU Operator(v0 系) と デバイスプラグイン v1 を利用してください。
3️⃣ モデルコンテナ化と KServe デプロイ
3‑1️⃣ コンテナベストプラクティス
| フレームワーク | 推奨ベースイメージ | 主なポイント |
|---|---|---|
| ONNX | python:3.11-slim + onnxruntime-server |
マルチステージでビルドし、最終イメージは 150 MB 前後に抑える |
| TensorFlow SavedModel | tensorflow/serving:2.15.0-gpu |
GPU ドライバと CUDA ライブラリが同梱されているため、追加設定不要 |
| PyTorch (TorchServe) | pytorch/torchserve:0.8.1-cpu または -gpu タグ |
torch-model-archiver でモデルアーカイブを作成し、model-store に配置 |
Dockerfile(ONNX の例)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# ---------- Build stage ---------- FROM python:3.11-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # ---------- Runtime stage ---------- FROM python:3.11-slim LABEL org.opencontainers.image.source="https://github.com/yourorg/onnx-model" ENV MODEL_NAME=sentiment.onnx WORKDIR /app COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages COPY . /app RUN pip install --no-cache-dir onnxruntime-server EXPOSE 8080 CMD ["onnxruntime_server", "--model_path", "/app/${MODEL_NAME}", "--http_port", "8080"] |
Tip:
docker buildxと--platform linux/amd64,linux/arm64を併用すれば、CPU のみノードでも同一イメージを利用可能です。
3‑2️⃣ KServe 用 InferenceService マニフェスト(GPU 対応)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
apiVersion: serving.kserve.io/v1beta1 kind: InferenceService metadata: name: sentiment-analysis namespace: ml-prod spec: predictor: minReplicas: 2 maxReplicas: 10 containers: - name: kserve-container image: ghcr.io/yourorg/sentiment-onnx:latest resources: limits: nvidia.com/gpu: 1 # GPU 要求 cpu: "4" memory: "16Gi" env: - name: MODEL_NAME value: sentiment.onnx autoscaling: metrics: - type: Resource resource: name: nvidia.com/gpu target: type: Utilization averageUtilization: 70 |
ポイント解説
| 項目 | 意味 |
|---|---|
minReplicas / maxReplicas |
HPA による自動スケールの上下限 |
nvidia.com/gpu: 1 |
GPU の リソースリクエスト。GPU Operator が提供するデバイスプラグインで認識 |
autoscaling.metrics |
カスタムメトリクス(GPU 使用率)でスケーリングを制御 |
参考: KServe 公式ドキュメントの GPU デプロイガイド [3]
4️⃣ パイプライン実装:Kubeflow Pipelines と Tekton CI/CD
4‑1️⃣ Kubeflow Pipelines(Python SDK)でのワークフロー例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import kfp from kfp import dsl, components @dsl.component(base_image="python:3.11-slim") def preprocess(): # データ取得・前処理ロジックを実装 ... @dsl.component(base_image="tensorflow/tensorflow:2.15.0-gpu") def train(): # 学習スクリプト(train.py)を呼び出す ... @dsl.component(base_image="ghcr.io/yourorg/kserve-cli:latest") def register(): # InferenceService 用 YAML を apply ... @dsl.pipeline(name="sentiment-pipeline", description="前処理→学習→デプロイ") def sentiment_pipeline(): p = preprocess() t = train().after(p) r = register().after(t) if __name__ == "__main__": kfp.Client().create_run_from_pipeline_func( sentiment_pipeline, arguments={}, experiment_name="ml-prod" ) |
- Artifact Store はデフォルトで
MinIOが使用されます。 - 実行結果は Kubeflow UI の「Run Details」で可視化できます。
4‑2️⃣ Tekton による CI/CD パイプライン
(a) ビルドタスク(Kaniko)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: build-image spec: params: - name: IMAGE type: string workspaces: - name: source steps: - name: kaniko image: gcr.io/kaniko-project/executor:latest args: - --destination=$(params.IMAGE) - --context=dir://$(workspaces.source.path) |
(b) デプロイタスク(KServe)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: deploy-kserve spec: params: - name: SERVICE_YAML type: string steps: - name: apply image: bitnami/kubectl:latest script: | #!/usr/bin/env sh kubectl apply -f $(params.SERVICE_YAML) |
(c) パイプライン全体
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: ml-ci-cd spec: params: - name: IMAGE - name: SERVICE_YAML workspaces: - name: source tasks: - name: build taskRef: name: build-image params: - name: IMAGE value: $(params.IMAGE) workspaces: - name: source workspace: source - name: deploy runAfter: [build] taskRef: name: deploy-kserve params: - name: SERVICE_YAML value: $(params.SERVICE_YAML) |
- トリガーは Argo Events、GitHub Actions、または Tekton の
TriggerTemplateとTriggerBindingを組み合わせて実装可能です。 - ビルドイメージは Kaniko(Docker デーモン不要)を使用し、セキュリティ上のリスクを低減します。
5️⃣ 運用・スケーリング・モニタリング・セキュリティ
5‑1️⃣ GPU 用 HPA と Cluster Autoscaler
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: sentiment-hpa spec: scaleTargetRef: apiVersion: serving.kserve.io/v1beta1 kind: InferenceService name: sentiment-analysis minReplicas: 2 maxReplicas: 12 metrics: - type: Pods pods: metric: name: nvidia.com/gpu target: type: AverageValue averageValue: "1" |
- Cluster Autoscaler の設定例(AWS EKS)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
apiVersion: autoscaling.k8s.io/v1 kind: ClusterAutoscaler metadata: name: cluster-autoscaler spec: scaleDownDelayAfterAdd: "10m" balanceSimilarNodeGroups: true nodeGroups: - name: gpu-ng instanceType: p4d.24xlarge # 8 GPU / node minSize: 1 maxSize: 5 |
ポイント: カスタムメトリクス
nvidia.com/gpuは kube‑metrics‑server と Prometheus Adapter が必要です。
5‑2️⃣ 可観測性:Prometheus・Grafana・OpenTelemetry
| コンポーネント | 主な役割 |
|---|---|
| Prometheus | KServe の /metrics を取得し、GPU 使用率・レイテンシを可視化 |
| Grafana | 公式ダッシュボード(ID: 17289)で prediction_latency_seconds, request_total 等を表示 |
| OpenTelemetry Collector | Envoy(KServe のデフォルトプロキシ)からトレース情報を取得し、Jaeger/Tempo に転送 |
Prometheus スクレイプ設定例
|
1 2 3 4 5 6 7 8 9 10 11 12 |
scrape_configs: - job_name: 'kserve' kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_label_serving_kserve_io_inferenceservice] action: keep - source_labels: [__address__] regex: (.+):\d+ target_label: __address__ replacement: $1:8080 # KServe の metrics ポート |
5‑3️⃣ セキュリティ強化策(追加対策)
| 項目 | 実装例 |
|---|---|
| NetworkPolicy | kubectl apply -f - <<EOF<br>apiVersion: networking.k8s.io/v1<br>kind: NetworkPolicy<br>metadata:<br> name: deny-all-egress<br> namespace: ml-prod<br>spec:<br> podSelector: {}<br> policyTypes: [Egress]<br> egress: []<br>EOF |
| イメージスキャン | CI パイプラインで trivy image ghcr.io/yourorg/sentiment-onnx:latest --severity HIGH,CRITICAL を実行し、脆弱性が検出されたらビルドを失敗させる |
| PodSecurity Standards (PSS) | restricted プロファイルを適用し、特権コンテナ・root での実行を防止 |
| RBAC | InferenceService の作成は ml-prod-admin グループのみ許可する RoleBinding を設定 |
| TLS / Mutual TLS | Istio の DestinationRule に mode: MUTUAL を指定し、クライアント証明書で相互認証を実施(上記例参照) |
| OPA Gatekeeper | GPU 使用は特定名前空間に限定する ConstraintTemplate(前述)をデプロイ |
注記: これらの対策はすべて「インフラストラクチャ as Code」(IaC) として管理し、GitOps による変更履歴を残すことがベストプラクティスです。
5‑4️⃣ デバッグ・トラブルシューティング
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# InferenceService の全体ステータス確認 kubectl get inferenceservice sentiment-analysis -n ml-prod -o yaml # GPU コンテナのログ取得(最新 200 行) kubectl logs -l serving.kserve.io/inferenceservice=sentiment-analysis \ -c kserve-container -n ml-prod --tail=200 # イベント情報で失敗理由を抽出 kubectl describe inferenceservice sentiment-analysis -n ml-prod | grep -A5 Events # GPU 使用率のリアルタイム確認(metrics-server が必要) kubectl top pod -l serving.kserve.io/inferenceservice=sentiment-analysis -n ml-prod |
- よくあるエラー
CUDA out of memory→ Pod のresources.limits.nvidia.com/gpuを増やすか、HPA 上限を引き上げる。FailedMount(NVIDIA driver 未インストール)→ GPU Operator が正しくデプロイされているか確認。
6️⃣ まとめ
| カテゴリ | キーになるポイント |
|---|---|
| GPU スケジューラ | デバイスプラグイン + NFD による自動ラベリングで、GPU メモリ容量に応じた優先度付与が可能 |
| 環境構築 | kubectl, helm, Docker, Argo CD/Flux の最新版を用意し、GPU Operator でデバイスプラグインを有効化 |
| コンテナ化 | ONNX / TensorFlow SavedModel / TorchServe をマルチステージビルドで軽量化(200 MB 以下) |
| KServe デプロイ | InferenceService で GPU 要求・オートスケーリングを一括管理 |
| パイプライン | Kubeflow Pipelines がデータ前処理〜モデル登録までをコード化、Tekton が CI/CD(ビルド→デプロイ)を自動化 |
| スケール & 監視 | カスタムメトリクス HPA + Cluster Autoscaler による GPU 動的拡張、Prometheus/Grafana と OpenTelemetry で可観測性確保 |
| セキュリティ | NetworkPolicy・イメージスキャン・PSS・RBAC・OPA Gatekeeper・Mutual TLS の多層防御 |
| トラブルシューティング | kubectl 系コマンドと KServe イベントで迅速に原因特定 |
実践へのステップ
1. 上記「前提条件」セクションのツールをローカル/クラウドにインストール。
2. GPU Operator と NFD をデプロイし、ノードにラベルが付与されていることを確認。
3. ベンチマーク用の ONNX モデルを Docker 化し、InferenceServiceマニフェストでデプロイ。
4. Tekton パイプラインを構築して Git push → 自動ビルド・自動デプロイまでのフローを体感。
5. Prometheus と Grafana で GPU 使用率とレイテンシをモニタリングし、必要に応じて HPA/Autoscaler のパラメータ調整。
これらを順に実装すれば、Kubernetes 上で 安全・高可用性・スケーラブル な AI 推論基盤が構築できます。ぜひリポジトリをクローンし、最新の公式ドキュメントと併せて試してみてください。
参考文献・リンク一覧
- NVIDIA GPU Operator – Official Documentation
https://docs.nvidia.com/datacenter/cloud-native/kubernetes/overview.html - Node Feature Discovery (NFD) – GitHub Repository
https://github.com/kubernetes-sigs/node-feature-discovery - KServe v1beta1 – Model Serving Guide (GPU)
https://kserve.github.io/website/latest/modelserving/v1beta1/ - Tekton Pipelines – Tasks & Pipelines Reference
https://tekton.dev/docs/pipelines/ - Prometheus Adapter for Custom Metrics (GPU)
https://github.com/kubernetes-sigs/prometheus-adapter - OpenTelemetry Collector – Kubernetes Deploy Guide
https://opentelemetry.io/docs/collector/deployment/kubernetes/
本稿は 2024 年 10 月時点の公式情報に基づき作成しています。将来的な機能追加やバージョン変更があった場合は、各ベンダーのリリースノートをご確認ください。