このページでは、Google Kubernetes Engine(GKE)でセカンダリ ブートディスクを使用して、新しいノードにデータまたはコンテナ イメージをプリロードし、ワークロードの起動レイテンシを改善する方法について説明します。これにより、ワークロードではコールド スタートの高速化と、プロビジョニングされたリソースの全体的な使用率の向上が実現します。
このページを読む前に、Google Cloud、Kubernetes、コンテナ、YAML、containerd ランタイム、Google Cloud CLI について理解しておいてください。
概要
Standard クラスタの GKE バージョン 1.28.3-gke.1067000 以降と Autopilot クラスタの GKE バージョン 1.30.1-gke.1329000 以降では、セカンダリ ブートディスクを使用してノードプールを構成できます。GKE には、ノードをプロビジョニングして、ML モデルやコンテナ イメージなどのデータをプリロードするように指示できます。プリロードされたコンテナ イメージやセカンダリ ディスクのデータを使用すると、ワークロードに次のようなメリットがあります。
- 大規模なコンテナ イメージの pull やデータのダウンロード時のレイテンシの短縮
- 自動スケーリングの高速化
- メンテナンス イベントやシステムエラーなどの中断からの迅速な復元
以降のセクションでは、GKE Autopilot クラスタと Standard クラスタでセカンダリ ブートディスクを構成する方法について説明します。
セカンダリ ブートディスクの仕組み
セカンダリ ブートディスクにプリロードされたコンテナ イメージまたはデータを使用することで、ワークロードの起動を高速化できます。セカンダリ ブートディスクには次の特性があります。
- セカンダリ ブートディスクは、分散ブロック ストレージを基盤とする Persistent Disk です。ディスク イメージがゾーンですでに使用されている場合、同じディスク イメージから作成される後続のディスクの作成時間は短くなります。
- セカンダリ ブートディスクのタイプは、ノードのブートディスクと同じです。
- セカンダリ ブートディスクのサイズは、ディスク イメージのサイズによって決まります。
ノードプールにセカンダリ ブートディスクを追加しても、ノードのプロビジョニング時間は増加しません。GKE は、ノードのプロビジョニング プロセスと並行して、ディスク イメージからセカンダリ ブートディスクをプロビジョニングします。
プリロードされたコンテナ イメージをサポートするため、GKE は、セカンダリ ブートディスクからコンテナ イメージを読み取るプラグインを使用して containerd ランタイムを拡張します。コンテナ イメージはベースレイヤで再利用されます。
大きなベースレイヤはセカンダリ ブートディスクにプリロードし、小さな上位レイヤをコンテナ レジストリから pull できます。
始める前に
始める前に、次の作業が完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、
gcloud components update
を実行して最新のバージョンを取得する。
Container File System API を有効にします。
要件
セカンダリ ブートディスクの使用には、次の要件が適用されます。
- クラスタが GKE Standard で、GKE バージョン 1.28.3-gke.1067000 または GKE Autopilot でバージョン 1.30.1-gke.1329000 を実行している。
- ディスク イメージを変更するときは、新しいノードプールを作成する必要があります。既存のノードのディスク イメージの更新はサポートされていません。
- セカンダリ ブートディスク機能を使用するようにイメージ ストリーミングを構成します。
- containerd ノードイメージで Container-Optimized OS を使用します。Autopilot ノードはデフォルトでこのノードイメージを使用します。
ビルド時にデータが準備されたディスク イメージを準備するか、プリロードされたコンテナ イメージを使用してディスク イメージを準備します。クラスタがディスク イメージにアクセスしてノードに読み込まれるようにします。
ベスト プラクティス: CI / CD パイプラインでディスク イメージを自動化します。
制限事項
セカンダリ ブートディスクには次の制限があります。
- 既存ノードのセカンダリ ブートディスクを更新することはできません。新しいディスク イメージを接続するには、新しいノードプールを作成します。
セカンダリ ブートディスクを準備する
セカンダリ ブートディスクを準備するときに、コンテナ イメージをプリロードする場合は [イメージ] タブを選択し、データをプリロードする場合は [データ] タブを選択して、次の手順を完了します。
画像
GKE には、仮想マシン(VM)を作成してディスク上のコンテナ イメージを pull し、そのディスクからディスク イメージを作成する gke-disk-image-builder
というツールが用意されています。
複数のプリロードされたコンテナ イメージを含むディスク イメージを作成するには、次の操作を行います。
gke-disk-image-builder
の実行ログを保存する Cloud Storage バケットを作成します。gke-disk-image-builder
を使用してディスク イメージを作成します。
go run ./cli \
--project-name=PROJECT_ID \
--image-name=DISK_IMAGE_NAME \
--zone=LOCATION \
--gcs-path=gs://LOG_BUCKET_NAME \
--disk-size-gb=10 \
--container-image=docker.io/library/python:latest \
--container-image=docker.io/library/nginx:latest
次のように置き換えます。
- PROJECT_ID: Google Cloud プロジェクトの名前。
- DISK_IMAGE_NAME: ディスクのイメージの名前。例:
nginx-python-image
- LOCATION: クラスタのロケーション。
- LOG_BUCKET_NAME: 実行ログを保存する Cloud Storage バケットの名前。例:
gke-secondary-disk-image-logs/
gke-disk-image-builder
を使用してディスク イメージを作成すると、Google Cloud によってプロセスを完了するために複数のリソース(VM インスタンス、一時ディスク、永続ディスクなど)が作成されます。実行後、イメージ ビルダーは、作成したディスク イメージを除くすべてのリソースをクリーンアップします。
データ
次の手順で、データソースとしてカスタム ディスク イメージを作成します。
セカンダリ ブートディスクを構成する
セカンダリ ブートディスクは、GKE Autopilot クラスタまたは GKE Standard クラスタで構成できます。
フルマネージドの Kubernetes エクスペリエンスを実現するには、Autopilot クラスタを使用します。ワークロードに最適な GKE の運用モードを選択するには、GKE の運用モードを選択するをご覧ください。
GKE Autopilot を使用する
このセクションでは、ディスク イメージの許可リストを作成し、既存の GKE Autopilot クラスタでディスク イメージを許可します。次に、セカンダリ ブートディスクを使用するように Pod ノードセレクタを変更します。
プロジェクトでディスク イメージを許可する
このセクションでは、GKE が Google Cloud プロジェクトのディスク イメージからセカンダリ ブートディスクを含むノードを作成できるように GCPResourceAllowlist
を作成します。
次のマニフェストを
allowlist-disk.yaml
として保存します。apiVersion: "node.gke.io/v1" kind: GCPResourceAllowlist metadata: name: gke-secondary-boot-disk-allowlist spec: allowedResourcePatterns: - "projects/PROJECT_ID/global/images/.*"
PROJECT_ID は、ディスク イメージをホストするプロジェクト ID に置き換えます。
次のようにマニフェストを適用します。
kubectl apply -f allowlist-disk.yaml
GKE は、プロジェクト内のすべてのディスク イメージからセカンダリ ブートディスクを含むノードを作成します。
セカンダリ ブートディスクを使用するように Pod ノードセレクタを更新する
このセクションでは、GKE がセカンダリ ブートディスクを使用してノードを作成するように Pod 仕様を変更します。
Pod テンプレートに
nodeSelector
を追加します。nodeSelector: cloud.google.com.node-restriction.kubernetes.io/gke-secondary-boot-disk-DISK_IMAGE_NAME=CONTAINER_IMAGE_CACHE.PROJECT_ID
次のように置き換えます。
- DISK_IMAGE_NAME: ディスク イメージの名前。
- PROJECT_ID: ディスク イメージをホストするプロジェクト ID。
kubectl apply
コマンドを使用して、Pod テンプレートを使用して Kubernetes 仕様を適用します。セカンダリ ブートディスク キャッシュが使用中であることを確認します。
kubectl get events --all-namespaces
出力は次のようになります。
75s Normal SecondaryDiskCachin node/gke-pd-cache-demo-default-pool-75e78709-zjfm Image gcr.io/k8s-staging-jobsejt/pytorch-mnist:latest is backed by secondary disk cache
イメージ pull のレイテンシを確認します。
kubectl describe pod POD_NAME
POD_NAME は、Pod の名前で置き換えます。
出力は次のようになります。
… Normal Pulled 15m kubelet Successfully pulled image "docker.io/library/nginx:latest" in 0.879149587s …
キャッシュに保存されたコンテナ イメージに想定されるイメージ pull のレイテンシは、イメージサイズに関係なく大幅に短縮されます。
GKE Standard を使用する
GKE Standard クラスタとノードプールを作成するには、次の手順を完了します。セカンダリ ブートディスクにコンテナ イメージをプリロードするのか、データをプリロードするかに応じて、[イメージ] タブまたは [データ] タブを選択します。
画像
セカンダリ ブートディスクを構成するには、Google Cloud CLI または Terraform を使用します。
gcloud
イメージ ストリーミングを有効にして GKE Standard クラスタを作成します。
gcloud container clusters create CLUSTER_NAME \ --location=LOCATION \ --cluster-version=VERSION \ --enable-image-streaming
次のように置き換えます。
- CLUSTER_NAME: クラスタの名前。
- LOCATION: クラスタのロケーション。
- VERSION: 使用する GKE のバージョン。GKE のバージョンは
1.28.3-gke.1067000
以降にする必要があります。
同じプロジェクトにセカンダリ ブートディスクを含むノードプールを作成します。
gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location LOCATION \ --enable-image-streaming \ --secondary-boot-disk=disk-image=global/images/DISK_IMAGE_NAME,mode=CONTAINER_IMAGE_CACHE
次のように置き換えます。
- NODE_POOL_NAME: ノードプールの名前。
- CLUSTER_NAME: 既存のクラスタの名前。
- LOCATION: クラスタのコンピューティング ゾーン(カンマ区切り)。
- DISK_IMAGE_NAME: ディスク イメージの名前。
別のプロジェクトのディスク イメージからセカンダリ ブートディスクを含むノードプールを作成するには、別のプロジェクトでセカンダリ ブートディスクを使用するの手順を完了します。
Pod テンプレートに
nodeSelector
を追加します。nodeSelector: cloud.google.com/gke-nodepool: NODE_POOL_NAME
セカンダリ ブートディスク キャッシュが使用中であることを確認します。
kubectl get events --all-namespaces
出力は次のようになります。
75s Normal SecondaryDiskCachin node/gke-pd-cache-demo-default-pool-75e78709-zjfm Image gcr.io/k8s-staging-jobsejt/pytorch-mnist:latest is backed by secondary disk cache
次のコマンドを実行して、イメージ pull レイテンシを確認します。
kubectl describe pod POD_NAME
POD_NAME
は、Pod の名前で置き換えます。出力は次のようになります。
… Normal Pulled 15m kubelet Successfully pulled image "docker.io/library/nginx:latest" in 0.879149587s …
キャッシュに保存されたコンテナ イメージの想定されるイメージ pull レイテンシは、イメージサイズに関係なく数秒以内にする必要があります。
Terraform
Terraform を使用してデフォルト ノードプールを持つクラスタを作成するには、次の例をご覧ください。
同じプロジェクトにセカンダリ ブートディスクを含むノードプールを作成します。
Terraform の使用方法の詳細については、GKE での Terraform のサポートをご覧ください。
Pod テンプレートに
nodeSelector
を追加します。nodeSelector: cloud.google.com/gke-nodepool: NODE_POOL_NAME
セカンダリ ブートディスク キャッシュが使用中であることを確認します。
kubectl get events --all-namespaces
出力は次のようになります。
75s Normal SecondaryDiskCachin node/gke-pd-cache-demo-default-pool-75e78709-zjfm Image gcr.io/k8s-staging-jobsejt/pytorch-mnist:latest is backed by secondary disk cache
次のコマンドを実行して、イメージ pull レイテンシを確認します。
kubectl describe pod POD_NAME
POD_NAME は、Pod の名前で置き換えます。
出力は次のようになります。
… Normal Pulled 15m kubelet Successfully pulled image "docker.io/library/nginx:latest" in 0.879149587s …
キャッシュに保存されたコンテナ イメージの想定されるイメージ pull レイテンシは、イメージサイズに関係なく数秒以内にする必要があります。
Terraform の使用方法の詳細については、GKE での Terraform のサポートをご覧ください。
データ
セカンダリ ブートディスクとプリロード データを構成するには、Google Cloud CLI または Terraform を使用します。
gcloud
イメージ ストリーミングを有効にして GKE Standard クラスタを作成します。
gcloud container clusters create CLUSTER_NAME \ --location=LOCATION \ --cluster-version=VERSION \ --enable-image-streaming
次のように置き換えます。
- CLUSTER_NAME: クラスタの名前。
- LOCATION: クラスタのロケーション。
- VERSION: 使用する GKE のバージョン。GKE バージョンは、1.28.3-gke.1067000 以降である必要があります。
--secondary-boot-disk
フラグを使用して、セカンダリ ブートディスクを含むノードプールを作成します。gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location LOCATION \ --enable-image-streaming \ --secondary-boot-disk=disk-image=global/images/DISK_IMAGE_NAME
次のように置き換えます。
- NODE_POOL_NAME: ノードプールの名前。
- CLUSTER_NAME: 既存のクラスタの名前。
- LOCATION: クラスタのコンピューティング ゾーン(カンマ区切り)。
- DISK_IMAGE_NAME: ディスク イメージの名前。
別のプロジェクトのディスク イメージからセカンダリ ブートディスクを含むノードプールを作成するには、別のプロジェクトでセカンダリ ブートディスクを使用するの手順を完了します。
プリロードされたデータを含むセカンダリ ディスクが各ノードに存在するノードプールが作成されます。GKE は、セカンダリ ブートディスクをノードにアタッチしてマウントします。
必要に応じて、hostPath ボリューム マウントを使用して、Pod コンテナにセカンダリ ディスク イメージをマウントできます。次のマニフェストを使用して Pod リソースを定義し、hostPath ボリューム マウントを使用してそのコンテナにデータディスクをプリロードします。
apiVersion: v1 kind: Pod metadata: name: pod-name spec: containers: ... volumeMounts: - mountPath: /usr/local/data_path_sbd name: data_path_sbd ... volumes: - name: data_path_sbd hostPath: path: /mnt/disks/gke-secondary-disks/gke-DISK_IMAGE_NAME-disk
DISK_IMAGE_NAME は、ディスク イメージの名前に置き換えます。
Terraform
Terraform を使用してデフォルト ノードプールを持つクラスタを作成するには、次の例をご覧ください。
同じプロジェクトにセカンダリ ブートディスクを含むノードプールを作成します。
Terraform の使用方法の詳細については、GKE での Terraform のサポートをご覧ください。
必要に応じて、hostPath ボリューム マウントを使用して、Pod コンテナにセカンダリ ディスク イメージをマウントできます。次のマニフェストを使用して Pod リソースを定義し、hostPath ボリューム マウントを使用してそのコンテナにデータディスクをプリロードします。
apiVersion: v1 kind: Pod metadata: name: pod-name spec: containers: ... volumeMounts: - mountPath: /usr/local/data_path_sbd name: data_path_sbd ... volumes: - name: data_path_sbd hostPath: path: /mnt/disks/gke-secondary-disks/gke-DISK_IMAGE_NAME-disk
DISK_IMAGE_NAME は、ディスク イメージの名前に置き換えます。
セカンダリ ブートディスクを使用したクラスタの自動スケーリング
ノードプールを作成し、セカンダリ ブートディスクでクラスタの自動スケーリングを構成するには、Google Cloud CLI を使用します。
gcloud container node-pools create NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--location LOCATION \
--enable-image-streaming \
--secondary-boot-disk=disk-image=global/images/DISK_IMAGE_NAME,mode=CONTAINER_IMAGE_CACHE \
--enable-autoscaling \
--num-nodes NUM_NODES \
--min-nodes MIN_NODES \
--max-nodes MAX_NODES
次のように置き換えます。
- NODE_POOL_NAME: ノードプールの名前。
- CLUSTER_NAME: 既存のクラスタの名前。
- LOCATION: クラスタのコンピューティング ゾーン(カンマ区切り)。
- DISK_IMAGE_NAME: ディスク イメージの名前。
- MIN_NODES: 指定したノードプールで自動的にスケーリングするゾーンの最小ノード数。GKE バージョン 1.24 以降でノードプール全体の最小ノード数を指定するには、
--total-min-nodes
を使用します。フラグ--total-min-nodes
、--total-max-nodes
は、フラグ--min-nodes
、--max-nodes
と相互に排他的です。 - MAX_NODES: 指定したノードプールで自動的にスケーリングするゾーンの最大ノード数。GKE バージョン 1.24 以降でノードプール全体のノードの最大数を指定するには、
--total-max-nodes
を使用します。フラグ--total-min-nodes
、--total-max-nodes
は、フラグ--min-nodes
、--max-nodes
と相互に排他的です。
セカンダリ ブートディスクを使用したノードの自動プロビジョニング
GKE 1.30.1-gke.1329000 以降では、ワークロードのリソース需要を満たすためにノードプールを自動的に作成および削除するよう、ノードの自動プロビジョニングを構成できます。
次のように、GKE ノードの自動プロビジョニング用のセカンダリ ブートディスクにディスク イメージ許可リスト カスタム リソースを作成します。
apiVersion: "node.gke.io/v1" kind: GCPResourceAllowlist metadata: name: gke-secondary-boot-disk-allowlist spec: allowedResourcePatterns: - "projects/<PROJECT_ID>/global/images/.*"
PROJECT_ID は、ディスク イメージをホストするプロジェクト ID に置き換えます。
クラスタに許可リスト カスタム リソースをデプロイするには、次のコマンドを実行します。
kubectl apply -f ALLOWLIST_FILE
ALLOWLIST_FILE は、マニフェスト ファイル名に置き換えます。
セカンダリ ブートディスクを使用するように Pod ノードセレクタを更新します。
nodeSelector: cloud.google.com.node-restriction.kubernetes.io/gke-secondary-boot-disk-DISK_IMAGE_NAME=CONTAINER_IMAGE_CACHE.PROJECT_ID
次のように置き換えます。
- DISK_IMAGE_NAME: ディスク イメージの名前。
- PROJECT_ID: ディスク イメージをホストするプロジェクト ID。
別のプロジェクトでセカンダリ ブートディスクを使用する
セカンダリ ブートディスクを含むノードプールを作成する場合は、--secondary-boot-disk
フラグを使用して、別のプロジェクトのディスク イメージを使用するように GKE に指示できます。
別のプロジェクトのディスク イメージから、セカンダリ ブートディスクを含むノードプールを作成するには、
--secondary-boot-disk
フラグを使用します。例:gcloud beta container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location LOCATION \ --enable-image-streaming \ --secondary-boot-disk=disk-image=projects/IMAGE_PROJECT_ID/global/images/DISK_IMAGE_NAME,mode=CONTAINER_IMAGE_CACHE
次のように置き換えます。
- DISK_IMAGE_NAME: ディスク イメージの名前。
- IMAGE_PROJECT_ID: ディスク イメージが属するプロジェクトの名前。
プリロードされたデータを含むセカンダリ ディスクが各ノードに存在するノードプールが作成されます。これにより、セカンダリ ブートディスクがノードにアタッチされ、マウントされます。
クラスタ サービス アカウントに Compute イメージ ユーザーのロールを追加して、別のプロジェクトに属するディスク イメージへのアクセス権を付与します。
- デフォルトのコンピューティング サービス アカウント: CLUSTER_PROJECT_NUMBER@cloudservices.gserviceaccount.com
- GKE サービス アカウント: service-CLUSTER_PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com
gcloud projects add-iam-policy-binding IMAGE_PROJECT_ID \ --member serviceAccount:CLUSTER_PROJECT_NUMBER@cloudservices.gserviceaccount.com \ --role roles/compute.imageUser gcloud projects add-iam-policy-binding IMAGE_PROJECT_ID \ --member serviceAccount:service-CLUSTER_PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com \ --role roles/compute.imageUser
次のステップ
- イメージ ストリーミングを使用してコンテナ イメージを pull するで、ワークロードで必要なイメージデータをストリーミングしてコンテナ イメージを pull します。
- NVIDIA Collective Communication Library(NCCL)Fast Socket プラグインの使用方法については、NCCL Fast Socket を使用してワークロードの効率を向上させるをご覧ください。