このページでは、Kubernetes の永続ボリュームおよび永続ボリュームのクレームの概要と、Google Kubernetes Engine(GKE)での使用について説明します。このページでは、Compute Engine の永続ディスクを使用してバックアップされたストレージについて重点的に説明します。
PersistentVolume
PersistentVolume
リソースは、クラスタ内の耐久性に優れたストレージの管理に使用されます。GKE では通常、PersistentVolume
には永続ディスクが使用されます。
代わりに、NFS などの他のストレージ ソリューションを使用できます。Google Cloud 上の NFS ソリューションは Filestore です。GKE クラスタの NFS PV ソリューションとして Filestore インスタンスを設定する方法については、Filestore のドキュメントの Filestore CSI ドライバを使用して Filestore インスタンスにアクセスするをご覧ください。
ストレージに関するもう一つの選択肢は、Cloud Volumes Service です。このプロダクトは、高度なデータ マネジメント機能とスケーラビリティに優れたパフォーマンスを提供する、フルマネージド型のクラウドベースのデータ ストレージ サービスです。
PersistentVolume
ライフサイクルは Kubernetes によって管理されます。PersistentVolume
は動的にプロビジョニングすることが可能であるため、バックアップ ストレージの作成や削除を手動で行う必要はありません。
PersistentVolume
は、Pod とは独立して存在するクラスタ リソースです。このため、PersistentVolume
で表されるディスクとデータは、クラスタを変更した後や Pod の削除後に再作成した後も引き続き存在します。PersistentVolume
リソースは、PersistentVolumeClaims
で動的にプロビジョニングすることも、クラスタ管理者が明示的に作成することもできます。
PersistentVolume
リソースの詳細については、Kubernetes の Persistent Volumes のドキュメントと Persistent Volumes API リファレンスをご覧ください。
PersistentVolumeClaim
PersistentVolumeClaim
は PersistentVolume
リソースに対するリクエスト(クレーム)です。PersistentVolumeClaim
オブジェクトによって、PersistentVolume
の具体的なサイズ、アクセスモード、StorageClass
がリクエストされます。リクエストを満たす PersistentVolume
が存在する場合やプロビジョニング可能な場合、PersistentVolumeClaim
はその PersistentVolume
にバインドされます。
Pod はクレームを Volume として使用します。クラスタはクレームを検査して、バインドされた Volume を検出し、その Volume を Pod 用にマウントします。
PersistentVolumes
と PersistentVolumeClaims
を使用する場合、移植性というメリットも得られます。PersistentVolume
は実際のバックアップ ストレージのインターフェースであるため、さまざまなクラスタや環境で同じ Pod 仕様を簡単に使用できます。
StorageClass
Compute Engine 永続ディスク Container Storage Interface(CSI)ドライバなどの Volume 実装は、StorageClass
リソースで構成されます。
GKE は、バランス永続ディスクタイプ(ext4)を使用するデフォルトの StorageClass
を作成します。PersistentVolumeClaim
が StorageClassName
を指定していない場合、デフォルトの StorageClass
が使用されます。デフォルトで指定されている StorageClass
は、独自のものに置き換えることができます。手順については、デフォルトの StorageClass を変更するをご覧ください。
独自の StorageClass
リソースを作成して、さまざまなストレージ クラスを記述できます。たとえば、クラスをサービス品質レベルやバックアップ ポリシーにマッピングできます。このコンセプトは、他のストレージ システムでは「プロファイル」と呼ばれることもあります。
クラスタを Windows ノードプールとともに使用する場合、デフォルトの fstype(ext4)は Windows でサポートされていないため、StorageClass
を作成し、PersistentVolumeClaim
で StorageClassName
を指定する必要があります。Compute Engine 永続ディスクを使用している場合は、ファイル ストレージ タイプとして NTFS を使用する必要があります。
StorageClass
を定義する場合は、プロビジョナーを指定する必要があります。GKE では、次のいずれかのプロビジョナーを使用することをおすすめします。
PersistentVolume を動的にプロビジョニングする
ほとんどの場合、PersistentVolume
オブジェクトを直接構成することや、Compute Engine の永続ディスクを作成する必要はありません。代わりに、PersistentVolumeClaim
を作成して、Kubernetes により自動で永続ディスクをプロビジョニングします。
次のマニフェストでは 30 ギガバイト(GiB)の保存容量のディスクをリクエストし、単一のノードによる読み取り / 書き込みモードでマウントするようにアクセスモードを指定しています。また、PersistentVolumeClaim
を Volume として使用する Pod も作成されます。
# pvc-pod-demo.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-demo
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 30Gi
storageClassName: standard-rwo
---
kind: Pod
apiVersion: v1
metadata:
name: pod-demo
spec:
volumes:
- name: pvc-demo-vol
persistentVolumeClaim:
claimName: pvc-demo
containers:
- name: pod-demo
image: nginx
resources:
limits:
cpu: 10m
memory: 80Mi
requests:
cpu: 10m
memory: 80Mi
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: pvc-demo-vol
kubectl apply -f
pvc-pod-demo.yaml
を使用してこの PersistentVolumeClaim
オブジェクトを作成すると、Kubernetes は対応する PersistentVolume
オブジェクトを動的に作成します。
ストレージ クラス standard-rwo
はボリューム バインディング モード WaitForFirstConsumer
を使用するため、Pod が Volume を使用するようにスケジュールされるまで、PersistentVolume
は作成されません。
次の例は、作成された PersistentVolume
を示しています。
apiVersion: v1
kind: PersistentVolume
metadata:
annotations:
pv.kubernetes.io/provisioned-by: pd.csi.storage.gke.io
finalizers:
- kubernetes.io/pv-protection
- external-attacher/pd-csi-storage-gke-io
name: pvc-c9a44c07-cffa-4cd8-b92b-15bac9a9b984
uid: d52af557-edf5-4f96-8e89-42a3008209e6
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 30Gi
claimRef:
apiVersion: v1
kind: PersistentVolumeClaim
name: pvc-demo
namespace: default
uid: c9a44c07-cffa-4cd8-b92b-15bac9a9b984
csi:
driver: pd.csi.storage.gke.io
csi.storage.k8s.io/fstype: ext4
volumeAttributes:
storage.kubernetes.io/csiProvisionerIdentity: 1660085000920-8081-pd.csi.storage.gke.io
volumeHandle: projects/xxx/zones/us-central1-c/disks/pvc-c9a44c07-cffa-4cd8-b92b-15bac9a9b984
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: topology.gke.io/zone
operator: In
values:
- us-central1-c
persistentVolumeReclaimPolicy: Delete
storageClassName: standard-rwo
volumeMode: Filesystem
status:
phase: Bound
ストレージ クラス standard-rwo
を置き換えていないと仮定すると、この PersistentVolume
には新しい空の Compute Engine 永続ディスクが使用されます。
永続ストレージの削除
デフォルトでは、Compute Engine 永続ディスクのように動的にプロビジョニングされた Volume の PersistentVolumeClaim を削除すると、PersistentVolume オブジェクトと実際のバッキング ディスクの両方が削除されます。この動作は、StorageClass と PersistentVolume の再利用ポリシーによって制御されます。これは、デフォルトの Delete
または Retain
に設定できます。詳細については、Kubernetes のドキュメントの再利用をご覧ください。
永続ストレージの削除時にデータの損失を防ぐか軽減するには、Backup for GKE を有効にして、デプロイされたワークロードとそのデータを含む GKE クラスタの定期的なバックアップをスケジューリングすることをおすすめします。
クラスタ削除時の永続ストレージの管理
GKE クラスタが削除されると、GKE は Delete
または Retain
の再利用ポリシーで PersistentVolume
リソースを保持します。
クラスタを削除するときに PersistentVolume
リソースを削除するには、PersistentVolumeClaim
リソースの Namespace を手動で削除します。これにより、Delete
ポリシーで PersistentVolume
オブジェクトの削除がトリガーされます。また、PersistentVolumeClaim
リソースを個別に削除することもできます。ただし、GKE は、これらの削除アクティビティが完了するまで待ってからクラスタの削除を開始するわけではありません。そのため、Namespace を削除してからクラスタをすぐに削除すると、Delete
ポリシーを含む PersistentVolume
リソースが削除されない場合があります。
クラスタの削除後、Google Cloud コンソールで残りの PersistentVolume
リソースを確認できます。
未使用の PersistentVolume
リソースなど、未使用のリソースを確認するには、アイドル状態のリソースに関する推奨事項を表示します。
アクセスモード
PersistentVolume
リソースでは、次のアクセスモードがサポートされています。
- ReadWriteOnce: ボリュームを単一のノードで読み取り書き込み可能としてマウントできます。
- ReadOnlyMany: ボリュームを多数のノードで読み取り専用としてマウントできます。
- ReadWriteMany: ボリュームを多数のノードで読み取り書き込み可能としてマウントできます。Compute Engine の永続ディスクを使用する
PersistentVolume
リソースでは、このアクセスモードはサポートされていません。
Compute Engine の永続ディスクを ReadOnlyMany として使用する
永続ディスクは通常は ReadWriteOnce として使用され、ほとんどのアプリケーションでデフォルトのアクセスモードとなっています。Compute Engine の永続ディスクでは ReadOnlyMany モードもサポートされているため、同じアプリケーションで多数のアプリケーションや多数のレプリカが同じディスクを同時に使用できます。その例として、複数のレプリカ間での静的コンテンツの提供があります。
手順については、複数のリーダーを持つ永続ディスクの使用をご覧ください。
既存の永続ディスクを PersistentVolume として使用する
動的にプロビジョニングされた PersistentVolume
リソースは、作成時は空の状態です。既存の Compute Engine 永続ディスクにデータが格納されている場合は、対応する PersistentVolume
リソースを手動で作成してクラスタに導入できます。永続ディスクはクラスタノードと同じゾーンに存在する必要があります。
詳細については、既存の永続ディスクを使用する永続ボリュームの作成方法をご覧ください。
Deployment と StatefulSet の比較
PersistentVolumeClaim
テンプレートや VolumeClaim
テンプレートは、それぞれ Deployments や StatefulSets など、上位レベルのコントローラで使用できます。
Deployment はステートレス アプリケーション用に設計されているため、Deployment のすべてのレプリカで同じ PersistentVolumeClaim
が共有されます。作成されたレプリカ Pod はそれぞれ同一であるため、この設定では ReadWrite Many モードの Volume のみが機能します。
ReadWriteOnce ボリュームを使用するレプリカが 1 つしか存在しない Deployment は推奨されません。これは、デフォルトの Deployment 戦略では、再作成時に最初の Pod を停止する前に 2 番目の Pod を作成するためです。ReadWriteOnce ボリュームがすでに使用中であると 2 番目の Pod を起動できず、2 番目の Pod が起動しないと最初の Pod が削除されないため、Deployment はデッドロックで失敗する可能性があります。この場合は ReadWriteOnce ボリュームで StatefulSet を使用します。
レプリカごとに一意のボリュームが必要なステートフル アプリケーションを展開する場合は、StatefulSet を使用することを推奨します。StatefulSet で PersistentVolumeClaim テンプレートを使用することで、各レプリカ Pod に関連付けられた一意の PersistentVolumesClaims を使用して自動的にスケールアップできるアプリケーションを作成できます。
リージョン永続ディスク
リージョン永続ディスクは、同じリージョン内の 2 つのゾーン間でデータを複製するマルチゾーン リソースであり、ゾーン永続ディスクと同様に使用できます。ゾーン全体が停止した場合や、1 つのゾーン内の複数のクラスタノードがスケジュール不可になった場合、Kubernetes がこのボリュームを使用して他のゾーンにワークロードをフェイルオーバーできます。リージョン永続ディスクを使用して、GKE 上のステートフル ワークロード用の高可用性ソリューションを構築できます。プライマリ ゾーンとフェイルオーバー ゾーンの両方が、ワークロードを実行するのに十分なリソース容量で構成されていることを確認する必要があります。
リージョン SSD 永続ディスクは、高可用性とハイ パフォーマンスの両方が必要とされるデータベースなどのアプリケーションに適しています。詳細については、ブロック ストレージのパフォーマンスの比較をご覧ください。
リージョン永続ディスクは、ゾーン永続ディスクと同様に、必要に応じて動的にプロビジョニングすることも、クラスタ管理者が事前に手動でプロビジョニングすることもできます。リージョン永続ディスクを追加する方法については、リージョン永続ディスクのプロビジョニングをご覧ください。
永続ディスクのゾーン
ゾーン永続ディスクはゾーンリソースであり、リージョン永続ディスクはマルチゾーン リソースです。クラスタに永続ストレージを追加するとき、ゾーンが指定されない限り、GKE はディスクを単一のゾーンに割り当てます。その際、GKE はゾーンをランダムに選択します。永続ディスクがプロビジョニングされると、そのディスクを参照するすべての Pod が、永続ディスクと同じゾーンにスケジューリングされます。ただし、Pod または Deployment は、既存の永続ディスクのゾーンを認識しません。既存の永続ディスクで Pod が正しくスケジューリングされるようにするには、Pod 仕様または Deployment 仕様で nodeAffinity などのゾーン配置方法を使用して、適切なゾーンをターゲットにします。
ボリューム バインディング モード WaitForFirstConsumer
クラスタ内の永続ディスクを動的にプロビジョニングする場合は、StorageClass で WaitForFirstConsumer
ボリューム バインディング モードを設定することをおすすめします。この設定により、Kubernetes は Pod がスケジュールされているのと同じゾーンに永続ディスクをプロビジョニングします。反アフィニティやノードセレクタなどの Pod のスケジューリング制約が考慮されます。ゾーンの反アフィニティにより、StatefulSet Pod がゾーンとそれに対応するディスクに分散されます。
WaitForFirstConsumer
を設定するゾーン永続ディスクをプロビジョニングするための StorageClass
の例を、次に示します。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-balanced
csi.storage.k8s.io/fstype: ext4
volumeBindingMode: WaitForFirstConsumer
リージョン永続ディスクの使用例については、リージョン永続ディスクのプロビジョニングをご覧ください。
次のステップ
- ステートフル アプリケーションをデプロイする場合に推奨される StatefulSet について学習する
- StatefulSet を使用してステートフル アプリケーションをデプロイする方法を学習する
- クラスタ内の永続ディスクの使用方法を学習する
- 複数のノードから読み取り可能なディスクの作成方法を学習する
- SSD でバックアップされる永続ディスクの作成方法を学習する
- リージョン永続ディスクをプロビジョニングする方法を学習する