このページでは、Google Kubernetes Engine(GKE)クラスタにローカル SSD ストレージをプロビジョニングする方法と、クラスタ内のノードにアタッチされたローカル SSD を使用する raw ブロック ストレージのデータを消費するようにワークロードを構成する方法について説明します。
このローカル SSD オプションを使用すると、基盤となるストレージをより詳細に管理でき、Pod 用の独自のノードレベルのキャッシュを構築して、アプリケーションのパフォーマンスを向上させることができます。このオプションはカスタマイズすることも可能で、その場合は必要に応じて DaemonSet を実行して RAID を構成し、ディスクをフォーマットして、ローカル SSD ディスクにファイル システムをインストールします。
GKE での raw ブロック アクセスに対するローカル SSD のサポートの詳細については、ローカル SSD についてをご覧ください。
準備
作業を始める前に、次のことを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、
gcloud components update
を実行して最新のバージョンを取得する。
ローカル SSD を使用する raw ブロック ストレージを持つクラスタまたはノードプールを作成する
--local-nvme-ssd-block
オプションを指定して gcloud CLI を使用し、ローカル SSD を使用する raw ブロック ストレージを持つクラスタを作成します。
クラスタまたはノードプールを作成するために実行する gcloud CLI コマンドは、使用しているマシンタイプが属しているマシンシリーズの世代によって異なります。たとえば、N1 マシンタイプと N2 マシンタイプはそれぞれ第 1 世代と第 2 世代のマシンシリーズに属していますが、C3 マシンタイプは第 3 世代のマシンシリーズに属しています。
ローカル SSD を使用するクラスタを作成する
第 1 世代または第 2 世代
第 1 世代または第 2 世代のマシンシリーズのマシンタイプを使用する場合は、--local-nvme-ssd-block count=NUMBER_OF_DISKS
オプションを指定してクラスタを作成します。このオプションは、各ノードにアタッチするローカル SSD ディスクの数を指定します。最大数は、マシンタイプとリージョンによって異なります。
クラスタを作成するには、次の手順を行います。
gcloud container clusters create CLUSTER_NAME \
--local-nvme-ssd-block count=NUMBER_OF_DISKS \
--machine-type=MACHINE_TYPE \
--release-channel CHANNEL_NAME
次のように置き換えます。
CLUSTER_NAME
: クラスタの名前。NUMBER_OF_DISKS
: 各ノードでプロビジョニングするローカル SSD ディスクの数。ディスクの最大数はマシンタイプとリージョンによって異なります。MACHINE_TYPE
: 使用する第 1 世代または第 2 世代のマシンタイプ。デフォルトのe2-medium
タイプではローカル SSD を使用できないため、このフィールドを指定する必要があります。CHANNEL_NAME
: 1.25.3-gke.1800 より後の GKE バージョンを含むリリース チャンネル。
第 3 世代
第 3 世代のマシンシリーズのマシンタイプを使用する場合、count フィールドを指定せずに --local-nvme-ssd-block
オプションを使用してクラスタを作成します。GKE は、VM シェイプに基づいてクラスタのローカル SSD 容量を自動的にプロビジョニングします。最大数は、マシンタイプとリージョンによって異なります。
gcloud container clusters create CLUSTER_NAME \
--machine-type=MACHINE_TYPE \
--cluster-version CLUSTER_VERSION \
--local-nvme-ssd-block
次のように置き換えます。
CLUSTER_NAME
: クラスタの名前。MACHINE_TYPE
: 使用する第 3 世代のマシンシリーズのマシンタイプ。CLUSTER_VERSION
: 第 3 世代のマシンシリーズのマシンタイプでローカル SSD をサポートする GKE クラスタ バージョン。
ローカル SSD でノードプールを作成する
第 1 世代または第 2 世代
raw ブロック アクセス用にローカル SSD ディスクを使用するノードプールを作成するには、次のコマンドを実行します。
gcloud container node-pools create POOL_NAME \
--cluster=CLUSTER_NAME \
--machine-type=MACHINE_TYPE \
--local-nvme-ssd-block count=NUMBER_OF_DISKS
次のように置き換えます。
POOL_NAME
: 新しいノードプールの名前。CLUSTER_NAME
: クラスタの名前。MACHINE_TYPE
: 使用する第 1 世代または第 2 世代のマシンタイプ。ローカル SSD はデフォルトのe2-medium
タイプでは使用できないため、このフィールドを指定する必要があります。NUMBER_OF_DISKS
: 各ノードでプロビジョニングするローカル SSD ディスクの数。ディスクの最大数はマシンタイプとリージョンによって異なります。
第 3 世代
第 3 世代のマシンシリーズのマシンタイプを使用する場合、count フィールドを指定せずに --local-nvme-ssd-block
オプションを使用してクラスタを作成します。
gcloud container node-pools create POOL_NAME \
--cluster=CLUSTER_NAME \
--machine-type=MACHINE_TYPE \
--node-version NODE_VERSION \
--local-nvme-ssd-block
次のように置き換えます。
POOL_NAME
: 新しいノードプールの名前。CLUSTER_NAME
: クラスタの名前。MACHINE_TYPE
: 使用する第 3 世代のマシンシリーズのマシンタイプ。NODE_VERSION
: 第 3 世代のマシンシリーズのマシンタイプでローカル SSD をサポートする GKE ノードプールのバージョン。
ノードプール内のノードは cloud.google.com/gke-local-nvme-ssd=true
ラベル付きで作成されます。ラベルは、次のコマンドを実行して確認できます。
kubectl describe node NODE_NAME
ノードプールにアタッチされたローカル SSD ごとに、ホスト OS は、順序を表すフォルダの下のディスクにアクセスするためのシンボリック リンク(シムリンク)とユニバーサリー ユニーク アイデンティファイア(UUID)を使用するシンボリック リンクを作成します。たとえば、--local-nvme-ssd-block
オプションを使用して 3 つのローカル SSD を使用するノードプールを作成する場合、ホスト OS はディスクに次のシンボリック リンクを作成します。
/dev/disk/by-id/google-local-ssd-block0
/dev/disk/by-id/google-local-ssd-block1
/dev/disk/by-id/google-local-ssd-block2
それに応じて、ホスト OS はディスク用の UUID を使用して次のシンボリック リンクも作成します。
/dev/disk/by-uuid/google-local-ssds-nvme-block/local-ssd-GENERATED_UUID1
/dev/disk/by-uuid/google-local-ssds-nvme-block/local-ssd-GENERATED_UUID2
/dev/disk/by-uuid/google-local-ssds-nvme-block/local-ssd-GENERATED_UUID3
これにより、一意の ID を使用してディスクに確実にアクセスできるようになります。
ローカル SSD ボリュームにアクセスする
次の例は、ローカル SSD を使用する raw ブロック ストレージにアクセスする方法を示しています。
ローカル PersistentVolumes
ローカル SSD ボリュームは、PersistentVolume を使用して Pod としてマウントできます。
ローカル SSD から PersistentVolume を作成するには、PersistentVolume を手動で作成するか、ローカル Volume の静的プロビジョナーを実行します。
ローカル PersistentVolumes の制限事項
ローカル PersistentVolumes では、クラスタの自動スケーリングと動的プロビジョニングはサポートされていません。
GKE クラスタのアップグレードやノードの修復を行うと Compute Engine インスタンスが削除され、これによってローカル SSD ディスクのデータもすべて削除されます。
ローカル SSD を永続データに使用するクラスタやノードプールでは、ノードの自動アップグレードやノードの自動修復を有効にしないでください。まずアプリケーション データをバックアップしてから、データを新しいクラスタやノードプールに復元する必要があります。
- ノードの削除、アップグレード、修復、スケールダウンが行われても、ローカル PersistentVolume オブジェクトは自動的にクリーンアップされません。削除されたノードに関連付けられている古いローカル PersistentVolume オブジェクトを定期的にスキャンし、削除することをおすすめします。
PersistentVolume を手動で作成する
クラスタ内の各ノードで、ローカル SSD ごとに PersistentVolume を手動で作成できます。
特定ノードのローカル SSD を参照するには、PersistentVolume オブジェクトの nodeAffinity
フィールドを使用します。次の例は、Linux を実行するノードのローカル SSD の PersistentVolume 仕様を示しています。
apiVersion: v1
kind: PersistentVolume
metadata:
name: "example-local-pv"
spec:
capacity:
storage: 375Gi
accessModes:
- "ReadWriteOnce"
persistentVolumeReclaimPolicy: "Retain"
storageClassName: "local-storage"
local:
path: "/mnt/disks/ssd0"
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: "kubernetes.io/hostname"
operator: "In"
values:
- "gke-test-cluster-default-pool-926ddf80-f166"
この例では、ローカル SSD ディスクが RAID 用に手動で構成され、フォーマットされて、ノード gke-test-cluster-default-pool-926ddf80-f166
の /mnt/disks/ssd0
にマウントされます。nodeAffinity フィールドは、ローカル SSD が RAID 用に手動で構成されているノードにワークロードを割り当てるために使用されます。クラスタにノードが 1 つしかない場合、またはすべてのノードで RAID を構成している場合、nodeAffinity フィールドは必要ありません。
対応する PersistenVolumeClaim の仕様は次のようになります。
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: ssd-local-claim
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-storage
resources:
requests:
storage: 37Gi
PersistentVolume を削除する場合は、手動でディスクからデータを消去する必要があります。
ローカル Volume の静的プロビジョナーを実行する
ローカル ボリュームの静的プロビジョナーを使用して、ローカル SSD の PersistentVolume を自動的に作成できます。プロビジョナーは、各ノードのローカル SSD ディスクの管理、それらの PersistentVolume の作成と削除、PersistentVolume の消去時のローカル SSD ディスク上のデータのクリーンアップを行う DaemonSet です。
ローカル ボリュームの静的プロビジョナーを実行する手順は次のとおりです。
DaemonSet を使用して RAID を構成し、ディスクをフォーマットします。
gke-daemonset-raid-disks.yaml
仕様をダウンロードします。RAID ディスクの DaemonSet をデプロイします。DaemonSet は、すべてのローカル SSD ディスクに RAID 0 アレイを設定し、デバイスを
ext4
ファイルシステムにフォーマットします。kubectl create -f gke-daemonset-raid-disks.yaml
gke-nvme-ssd-block-raid.yaml
仕様をダウンロードし、必要に応じて仕様の namespace フィールドを変更します。この仕様には、次のリソースが含まれています。
- プロビジョナーの ServiceAccount
- 次を行う権限の ClusterRole と ClusterRoleBindings
- PersistentVolume オブジェクトの作成と削除
- Node オブジェクトの取得
- GKE のプロビジョナー設定の ConfigMap
- プロビジョナーを実行するための DaemonSet
プロビジョナーをデプロイします。
kubectl create -f gke-nvme-ssd-block-raid.yaml
プロビジョナーが正常に実行されると、クラスタ内の RAID ローカル SSD デバイスに PersistentVolume オブジェクトが作成されます。
次の PersistentVolumeClaim マニフェストを
provisioner-pvc-example.yaml
として保存します。kind: PersistentVolumeClaim apiVersion: v1 metadata: name: PVC_NAME spec: accessModes: - ReadWriteOnce resources: requests: storage: 50Gi storageClassName: nvme-ssd-block
PVC_NAME
は、PersistentVolumeClaim の名前に置き換えます。PersistentVolumeClaim を作成します。
kubectl create -f provisioner-pvc-example.yaml
次の Pod マニフェストを
provisioner-pod-example.yaml
として保存します。apiVersion: v1 kind: Pod metadata: name: POD_NAME spec: containers: - name: "shell" image: "ubuntu:14.04" command: ["/bin/sh", "-c"] args: ["echo 'hello world' > /cache/test.txt && sleep 1 && cat /cache/test.txt && sleep 3600"] volumeMounts: - mountPath: /cache name: local-ssd-storage volumes: - name: local-ssd-storage persistentVolumeClaim: claimName: PVC_NAME
POD_NAME
は、Pod の名前に置き換えます。Pod を作成します。
kubectl create -f provisioner-pod-example.yaml
遅延ボリューム バインディングを有効にする
スケジューリングを改善するには、volumeBindingMode: WaitForFirstConsumer
を使用して StorageClass を作成することもおすすめします。これにより、Pod のスケジューリング時点まで PersistentVolumeClaim バインディングが遅延され、Pod を実行できる適切なノードからローカル SSD が選択されるようになります。この強化されたスケジューリング動作により、実行可能な Pod 用のノードの選択時に、どのノードに使用可能なローカル SSD があるかを踏まえて、Pod の CPU とメモリのリクエスト、ノード アフィニティ、Pod アフィニティと反アフィニティ、複数の PersistentVolumeClaim リクエストが考慮されます。
次の例では、遅延ボリュームのバインディング モードを使用します。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: "local-nvme"
provisioner: "kubernetes.io/no-provisioner"
volumeBindingMode: "WaitForFirstConsumer"
遅延バインディングを使用して StorageClass を作成するには、YAML マニフェストをローカル ファイルに保存して、次のコマンドを使用してクラスタに適用します。
kubectl apply -f filename
トラブルシューティング
トラブルシューティングの手順については、GKE のストレージのトラブルシューティングをご覧ください。