Container Service for Kubernetes (ACK) Pro クラスター上で AI/ML コンポーネントをインストールし、GPU リソースを監視し、チームのクォータを管理します。
3 つのコアタスク:スイートのインストール、リソースダッシュボードの表示、キャパシティスケジューリングを使用したユーザーとクォータの管理。
前提条件
開始する前に、以下をご確認ください:
-
Kubernetes 1.18 以降を実行している ACK Pro クラスター
-
クラスター作成時に、[コンポーネント設定] ページでモニタリングアドオンと Simple Log Service が有効化されていること
基本概念
セキュリティ境界
Kubernetes はシングルテナントのオーケストレーターです。1 つのコントロールプレーンがクラスター内のすべてのテナントにサービスを提供します。クラスターは唯一の厳格なセキュリティ境界です。クォータツリー、ユーザーグループ、名前空間は、組織的なガードレールと論理的な分離を提供しますが、クラスターレベルの分離と同じセキュリティ保証を提供するものではありません。これに応じてマルチテナントアーキテクチャを設計してください。
キャパシティスケジューリングの仕組み
クォータツリー内の各クォータノードには 2 つのパラメーターがあります:
-
最小:クラスターに負荷がかかっている場合でも、名前空間が常に要求できる保証された最小リソース
-
最大:アイドルキャパシティが利用可能な場合に、名前空間が使用できる最大リソース
他の名前空間は、自身の最大値までアイドルキャパシティを借用できます。リソースを所有する名前空間が最小リソースを必要とするとき、スケジューラはワークロードの優先度、可用性、作成時間を考慮してリソースを回収します。
リソースオブジェクト
| オブジェクト | 役割 |
|---|---|
| クォータツリー | 階層的なリソース割り当て構造 |
| クォータノード | ツリー内のノード。各リーフノードは 1 つ以上の名前空間にマッピングされます |
| ユーザーグループ | 最小の割り当て単位。リーフクォータノードにマッピングされます |
| ユーザー | ジョブのサブミットやコンソールへのアクセスのために Kubernetes サービスアカウントを保持します |
| 名前空間 | リーフクォータノードにバインドされた Kubernetes 名前空間 |
ユーザーロール
| ロール | 権限 |
|---|---|
| admin | AI ダッシュボードへのログイン、クラスターコンポーネントの管理が可能で、researcher のすべての権限を持ちます。 |
| researcher | ジョブのサブミット、クラスターリソースの使用、AI 開発者コンソールへのログイン |
ステップ 1:クラウドネイティブ AI スイートのインストール
このスイートには 6 つのコンポーネントカテゴリがあります。ワークロードに必要なものだけをインストールしてください。Arena はデフォルトで選択されており、必須です。
| コンポーネントカテゴリ | 目的 | 個別インストール |
|---|---|---|
| タスクの弾力性 | AI ワークロードの動的なスケーリング | いいえ |
| データ高速化 | データセットへのアクセスを高速化 | いいえ |
| AI タスクスケジューリング | キャパシティを考慮したポリシーで AI ワークロードをスケジューリング | いいえ |
| AI タスクライフサイクル管理 | トレーニングジョブのライフサイクルを管理 | いいえ |
| AI ダッシュボード | GPU リソースとクォータを監視 | はい (RAM 権限が必要) |
| AI 開発者コンソール | AI ジョブのサブミットと管理 | はい (RAM 権限が必要) |
スイートのデプロイ
-
ACK コンソールにログインし、左側メニューで [クラスター] をクリックします。
-
クラスター名をクリックし、左側のペインで [アプリケーション] > [クラウドネイティブ AI スイート] を選択します。
-
[デプロイ] をクリックします。
-
コンポーネントを選択し、[クラウドネイティブ AI スイートのデプロイ] をクリックします。デプロイ前にシステムが依存関係をチェックします。インストール後、[コンポーネント] リストから個々のコンポーネントを [デプロイ]、[アップグレード]、または [アンインストール] できます。
-
ack-ai-dashboardとack-ai-dev-consoleをインストールした後、[クラウドネイティブ AI スイート] ページに [AI ダッシュボード] と [AI 開発者コンソール] へのリンクが表示されます。
AI ダッシュボードの設定
2025 年 1 月 22 日以降、AI コンソール (AI ダッシュボードおよび AI 開発者コンソール) の利用にはホワイトリストへの登録が必要になります。それ以前のデプロイは影響を受けません。ホワイトリストに登録されていないユーザーは、代わりに オープンソース AI コンソール を使用できます。
ワーカーロールへの RAM 権限の付与
AI ダッシュボードがクラスターデータにアクセスする前に、クラスターのワーカーロールにカスタム RAM ポリシーをアタッチします。
-
カスタムポリシーを作成します。
-
RAM コンソールにログインし、左側メニューで [権限] > [ポリシー] を選択します。
-
[ポリシーの作成] をクリックし、[JSON] タブを選択して、次のポリシーを追加します:
{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "cs:*", "log:GetProject", "log:GetLogStore", "log:GetConfig", "log:GetMachineGroup", "log:GetAppliedMachineGroups", "log:GetAppliedConfigs", "log:GetIndex", "log:GetSavedSearch", "log:GetDashboard", "log:GetJob", "ecs:DescribeInstances", "ecs:DescribeSpotPriceHistory", "ecs:DescribePrice", "eci:DescribeContainerGroups", "eci:DescribeContainerGroupPrice", "log:GetLogStoreLogs", "ims:CreateApplication", "ims:UpdateApplication", "ims:GetApplication", "ims:ListApplications", "ims:DeleteApplication", "ims:CreateAppSecret", "ims:GetAppSecret", "ims:ListAppSecretIds", "ims:ListUsers" ], "Resource": "*" } ] } -
ポリシーに
k8sWorkerRolePolicy-{ClusterID}という名前を付け、[OK] をクリックします。
-
-
ポリシーをクラスターのワーカーロールにアタッチします。
-
RAM コンソールで、[ID] > [ロール] を選択し、
KubernetesWorkerRole-{ClusterID}を検索します。 -
[権限付与] をクリックします。
-
[ポリシーの選択] で [カスタムポリシー] をクリックし、
k8sWorkerRolePolicy-{ClusterID}を検索して選択し、[OK] をクリックします。
-
AI ダッシュボードのセットアップの完了
-
[クラウドネイティブ AI スイート] ページで、[インタラクションモード] に [サンプルコンソール] を選択します。[注意] ダイアログボックスが表示されます。
-
[承認済み] と表示されている場合は、ステップ 3 に進みます。
-
[未承認] が赤色で表示されている場合は、上記の RAM 権限の設定を完了し、[承認チェック] をクリックします。承認後、[承認済み] が表示されます。

-
-
[コンソールデータストレージ] を設定します。テスト用には [プリインストールされた MySQL]、本番環境用には [ApsaraDB RDS] を選択します。詳細については、「AI ダッシュボードと AI 開発者コンソールのインストールと設定」をご参照ください。
-
[クラウドネイティブ AI スイートのデプロイ] をクリックします。AI ダッシュボードのステータスが [準備完了] と表示されたら、準備完了です。
(オプション) データセットの作成と高速化
Object Storage Service (OSS) のデータセットを永続ボリューム (PV) としてマウントし、AI ダッシュボードでアクセスを高速化します。
PV と PVC の作成
-
名前空間を作成します:
kubectl create ns demo-ns -
fashion-mnist.yamlという名前のファイルを作成します:プレースホルダー 説明 例 fashion-mnistOSS バケット名 my-dataset-bucket oss-cn-beijing.aliyuncs.comバケットのリージョンに対応する OSS エンドポイント oss-cn-hangzhou.aliyuncs.com AKIDAccessKey ID LTAI5tXxx AKSECRETAccessKey シークレット xXxXxXx apiVersion: v1 kind: PersistentVolume metadata: name: fashion-demo-pv spec: accessModes: - ReadWriteMany capacity: storage: 10Gi csi: driver: ossplugin.csi.alibabacloud.com volumeAttributes: bucket: fashion-mnist otherOpts: "-o max_stat_cache_size=0 -o allow_other" url: oss-cn-hangzhou.aliyuncs.com akId: "AKID" akSecret: "AKSECRET" volumeHandle: fashion-demo-pv persistentVolumeReclaimPolicy: Retain storageClassName: oss volumeMode: Filesystem --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: fashion-demo-pvc namespace: demo-ns spec: accessModes: - ReadWriteMany resources: requests: storage: 10Gi selector: matchLabels: alicloud-pvname: fashion-demo-pv storageClassName: oss volumeMode: Filesystem volumeName: fashion-demo-pvこれらのプレースホルダーを置き換えます:
-
マニフェストを適用します:
kubectl create -f fashion-mnist.yaml -
PV と PVC がバインドされていることを確認します:
kubectl get pv fashion-demo-pv kubectl get pvc fashion-demo-pvc -n demo-nsPV の期待される出力:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS AGE fashion-demo-pv 10 Gi RWX Retain Bound demo-ns/fashion-demo-pvc oss 8hPVC の期待される出力:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE fashion-demo-pvc Bound fashion-demo-pv 10 Gi RWX oss 8h
[データセットの高速化]
-
管理者としてAI ダッシュボードにログインします。
-
左側メニューで [データセット] > [データセットリスト] を選択します。
-
データセット (
fashion-demo-pvc) を見つけ、[操作] 列の [高速化] をクリックします。高速化されたデータセットは新しいレコードとして表示されます。名前は fashion-demo-pvc-acc、名前空間は demo-ns、データソースは
pvc://fashion-demo-pvc、[高速化済み] 列には [はい]、ステータスは [NotReady]、[操作] 列には [高速化のキャンセル] ボタンが表示されます。
ステップ 2:リソースダッシュボードの表示
AI ダッシュボードは 4 つのビューを提供し、それぞれが異なる側面から GPU リソースの健全性を示しています。
ここでは AI コンソールのホワイトリスト制限が適用されます。ホワイトリストに登録されていないユーザーは、オープンソース AI コンソール を通じてダッシュボードにアクセスできます。
クラスターダッシュボード
AI ダッシュボードはデフォルトでクラスターダッシュボードを開き、クラスター全体の GPU の健全性と割り当て状況を表示します。
| メトリック | 表示内容 |
|---|---|
| クラスターの GPU 概要 | 合計 GPU ノード、割り当て済み GPU ノード、不健全な GPU ノード |
| 合計 GPU ノード | GPU アクセラレーション対応ノードの総数 |
| 不健全な GPU ノード | 問題が検出された GPU ノード |
| GPU メモリ (使用量/合計) | 使用中の GPU メモリ / 合計 GPU メモリ |
| GPU メモリ (割り当て済み/合計) | 割り当て済み / 合計 GPU メモリ |
| GPU 使用率 | クラスター全体の平均 GPU 使用率 |
| GPU (割り当て済み/合計) | 割り当て済み / 合計 GPU |
| クラスターのトレーニングジョブ概要 | ステータス別のトレーニングジョブ:実行中、保留中、成功、失敗 |
GPU 使用率は、GPU がサンプル期間中に何らかの処理を実行したかどうかを示し、その効率を示すものではありません。100% のノードでも、重い並列ワークロードではなく、軽量なカーネルを実行している可能性があります。全体像をより正確に把握するためには、GPU メモリ (使用量/合計) と合わせて確認してください。
ノードダッシュボード
クラスターページの右上隅にある [ノード] をクリックすると、ノードごとおよび GPU デバイスごとの GPU メトリックを表示できます。
| メトリック | 表示内容 |
|---|---|
| GPU ノード詳細 | ノードごとのテーブル:名前、IP、ロール、GPU モード (排他または共有)、GPU 数、合計 GPU メモリ、割り当て済み GPU、割り当て済み GPU メモリ、使用済み GPU メモリ、平均 GPU 使用率 |
| GPU デューティサイクル | ノードごとの GPU デバイスごとの使用率 |
| GPU メモリ使用量 | ノードごとの GPU デバイスごとの使用メモリ |
| GPU メモリ使用率 | ノードごとの GPU ごとのメモリ使用率 |
| ノードごとの割り当て済み GPU | ノードごとの割り当て済み GPU |
| ノードごとの GPU 数 | ノードごとの合計 GPU 数 |
| ノードごとの合計 GPU メモリ | ノードごとの合計 GPU メモリ |
トレーニングジョブダッシュボード
ノードページの右上隅にある [TrainingJobs] をクリックすると、ジョブごとのリソース消費量と GPU 効率を表示できます。
| メトリック | 表示内容 |
|---|---|
| トレーニングジョブ | ジョブごとのテーブル:名前空間、名前、タイプ、ステータス、期間、要求 GPU、要求 GPU メモリ、使用 GPU メモリ、平均 GPU 使用率 |
| ジョブインスタンスの使用 GPU メモリ | ジョブインスタンスごとに使用された GPU メモリ |
| ジョブインスタンスの使用 GPU メモリ率 | ジョブインスタンスごとに使用された GPU メモリの割合 |
| ジョブインスタンスの GPU デューティサイクル | ジョブインスタンスごとの GPU 使用率 |
リソースクォータダッシュボード
トレーニングジョブページの右上隅にある [クォータ] をクリックすると、リソースタイプ (CPU、メモリ、nvidia.com/gpu、aliyun.com/gpu-mem、aliyun.com/gpu) 別のクォータ消費量を表示できます。
| 列 | 表示内容 |
|---|---|
| エラスティッククォータ名 | クォータグループ名 |
| 名前空間 | クォータが適用される名前空間 |
| リソース名 | リソースタイプ |
| 最大クォータ | 利用可能な最大リソース |
| 最小クォータ | 保証された最小値。クラスターの負荷が高い場合でも保証されます |
| 使用済みクォータ | 現在使用されているリソース |
ステップ 3:ユーザーとクォータの管理
クラウドネイティブ AI スイートは、クォータツリーを使用して階層的なリソース制限を適用し、チーム間でリソースを共有します。
組織構造はクォータツリーにマッピングされます:
各部門またはチームはクォータツリーのブランチにマッピングされ、リーフノードは名前空間にバインドされます。各レベルで最小と最大を設定することで、チームはアイドルリソースを共有しつつ、最小割り当てを保証できます。
クォータツリーと名前空間レベルの制御は、組織的なガードレールを提供するものであり、厳格なセキュリティ境界ではありません。テナントを厳密に分離するには、別々のクラスターを使用してください。「基本概念」のセキュリティ境界に関する注記をご参照ください。
クォータツリーのセットアップ
-
各チームの名前空間を作成します。既存の名前空間をクォータノードに関連付ける前に、実行中の Pod がないことを確認する必要があります。
kubectl create ns namespace1 kubectl create ns namespace2 kubectl create ns namespace3 kubectl create ns namespace4 -
AI ダッシュボードでクォータノードを作成し、各リーフノードを名前空間に関連付けます。各ノードに [最小] と [最大] を設定します。
ユーザーとユーザーグループの作成
1 人のユーザーは複数のグループに所属でき、1 つのグループには複数のユーザーを含めることができます。ユーザーをグループに関連付けて、割り当てられたリソースへのアクセスを許可します。
-
ユーザーを作成します。詳細については、「新規ユーザーの kubeconfig ファイルとログオントークンの生成」をご参照ください。
-
ユーザーグループを作成します。詳細については、「ユーザーグループの追加」をご参照ください。
キャパシティスケジューリングの例
この例では、スケジューラが 4 つの名前空間にまたがって CPU リソースを共有および回収する方法を示します。クォータツリーは次の構造を持っています:
クォータ設定:
| クォータノード | 最小 (CPU コア) | 最大 (CPU コア) |
|---|---|---|
| root | 40 | 40 |
| root.a | 20 | 40 |
| root.b | 20 | 40 |
| root.a.1 | 10 | 20 |
| root.a.2 | 10 | 20 |
| root.b.1 | 10 | 20 |
| root.b.2 | 10 | 20 |
ウォークスルー:
エラスティッククォータがない場合、各リーフ名前空間は自身の最小値 (10 コア = 5 コア / Pod で 2 Pod) のみを使用します。エラスティッククォータと 40 のクラスターコアが利用可能な場合、名前空間は自身の最大値までアイドルキャパシティを借用します。
ステップ 1: namespace1 に 5 つの Pod をデプロイし、それぞれが 5 CPU コア (合計 25 コア) を要求します。
root.a.1 の最大値が 20 コアに設定されているため、4 つの Pod が実行されます (20 コア)。5 つ目の Pod は保留中のままです。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
namespace: namespace1
labels:
app: nginx1
spec:
replicas: 5
selector:
matchLabels:
app: nginx1
template:
metadata:
name: nginx1
labels:
app: nginx1
spec:
containers:
- name: nginx1
image: nginx
resources:
limits:
cpu: 5
requests:
cpu: 5
ステップ 2: namespace2 に 5 つの Pod をデプロイし、それぞれが 5 CPU コアを要求します。
残りの 20 コアで、4 つの Pod が実行されます。5 つ目は保留中のままです。これで namespace1 と namespace2 の両方が、ルートクォータの 40 コアすべてを消費します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx2
namespace: namespace2
labels:
app: nginx2
spec:
replicas: 5
selector:
matchLabels:
app: nginx2
template:
metadata:
name: nginx2
labels:
app: nginx2
spec:
containers:
- name: nginx2
image: nginx
resources:
limits:
cpu: 5
requests:
cpu: 5
ステップ 3: namespace3 に 5 つの Pod をデプロイし、それぞれが 5 CPU コアを要求します。
アイドルキャパシティは残っていません。スケジューラは root.b.1 の最小値を保証するために root.a から 10 コアを回収します。root.a.1 から 5 コア (namespace1 の実行中 Pod を 4 から 3 に減らす) と root.a.2 から 5 コア (namespace2 の実行中 Pod を 4 から 3 に減らす) を回収します。10 コアが回収されたことで、namespace3 で 2 つの Pod が実行されます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx3
namespace: namespace3
labels:
app: nginx3
spec:
replicas: 5
selector:
matchLabels:
app: nginx3
template:
metadata:
name: nginx3
labels:
app: nginx3
spec:
containers:
- name: nginx3
image: nginx
resources:
limits:
cpu: 5
requests:
cpu: 5
ステップ 4: namespace4 に 5 つの Pod をデプロイし、それぞれが 5 CPU コアを要求します。
スケジューラは root.b.2 の最小値を保証するために root.a からさらに 10 コアを回収します。具体的には root.a.1 から 5 コア、root.a.2 から 5 コアです。回収後、namespace1 と namespace2 はそれぞれ 2 つの実行中 Pod (10 コア) を持ち、namespace4 では 2 つの Pod が実行されます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx4
namespace: namespace4
labels:
app: nginx4
spec:
replicas: 5
selector:
matchLabels:
app: nginx4
template:
metadata:
name: nginx4
labels:
app: nginx4
spec:
containers:
- name: nginx4
image: nginx
resources:
limits:
cpu: 5
requests:
cpu: 5
結果:
| 名前空間 | クォータノード | 実行中の Pod | 使用中の CPU コア |
|---|---|---|---|
| namespace1 | root.a.1 | 2 | 10 |
| namespace2 | root.a.2 | 2 | 10 |
| namespace3 | root.b.1 | 2 | 10 |
| namespace4 | root.b.2 | 2 | 10 |
各チームに保証された最小リソースは維持されました。他のチームが最小値を必要としたときに、借用されたキャパシティは回収されました。