永続ディスクを使用した永続ボリューム

このページでは、Kubernetes の PersistentVolumes と PersistentVolumeClaims の概要と、Google Kubernetes Engine(GKE)での使用法について説明します。このページでは、Compute Engine の永続ディスクを使用してバックアップされたストレージについて重点的に説明します。

概要

PersistentVolume リソースは、クラスタ内の永続ストレージの管理に使用されます。通常、GKE では、PersistentVolume は Compute Engine の永続ディスクを使用してバックアップされます。PersistentVolume は、NFS などの他のストレージ タイプでも使用できます。Filestore は、Google Cloud 上の NFS ソリューションです。GKE クラスタの NFS PV ソリューションとして Filestore インスタンスを設定する方法については、Filestore ドキュメントの Google Kubernetes Engine クラスタからのファイル共有へのアクセスをご覧ください。PersistentVolume 全般の概要については、Kubernetes のドキュメントをご覧ください。

Volume とは異なり、PersistentVolume のライフサイクルは Kubernetes によって管理されます。PersistentVolume は動的にプロビジョニングすることが可能であるため、バックアップ ストレージの作成や削除を手動で行う必要はありません。

PersistentVolume は、Pod とは独立して存在するクラスタ リソースです。このため、PersistentVolume で表されるディスクとデータは、クラスタを変更したり Pod を削除してから再作成したりしても、引き続き存在します。PersistentVolume リソースは、PersistentVolumeClaim で動的にプロビジョニングすることも、クラスタ管理者が明示的に作成することもできます。

PersistentVolumeClaim は、PersistentVolume リソースに対するリクエスト(要求)です。PersistentVolumeClaim オブジェクトは、PersistentVolume の具体的なサイズ、アクセスモード、StorageClass をリクエストします。リクエストを満たす PersistentVolume が存在する場合やプロビジョニング可能な場合、PersistentVolumeClaim はその PersistentVolume にバインドされます。

ポッドは要求をボリュームとして使用します。クラスタは要求を検査してバインドされたボリュームを検出し、そのボリュームを Pod にマウントします。

PersistentVolume と PersistentVolumeClaim を使用する場合、ポータビリティというメリットも得られます。PersistentVolume は実際のバックアップ ストレージのインターフェースであるため、さまざまなクラスタや環境で同じ Pod 仕様を簡単に使用できます。

StorageClass

gcePersistentDisk などのボリューム実装は、StorageClass リソースで構成されます。GKE は、標準的な種類の永続ディスク(ext4)を使用するデフォルトの StorageClass を作成します。PersistentVolumeClaim で StorageClassName が指定されていない場合、デフォルトの StorageClass が使用されます。デフォルトで指定されている StorageClass は、独自のものに置き換えることができます。

クラスタを Windows ノードプールとともに使用する場合、デフォルトの fstype である ext4 は Windows でサポートされていないため、StorageClass を作成し、PersistentVolumeClaim で StorageClassName を作成する必要があります。Compute Engine 永続ディスクを使用している場合は、ファイル ストレージ タイプとして NTFS を使用する必要があります。

独自の StorageClass リソースを作成すると、さまざまなクラスのストレージを記述できます。たとえば、クラスをサービス品質レベルやバックアップ ポリシーにマッピングできます。この概念は、他のストレージ システムでは「プロファイル」と呼ばれることもあります。

PersistentVolume の動的プロビジョニング

ほとんどの場合、PersistentVolume オブジェクトを直接構成したり Compute Engine 永続ディスクを作成したりする必要はありません。PersistentVolumeClaim を作成すると、Kubernetes が自動的に永続ディスクをプロビジョニングします。

次のマニフェストでは 30 ギガバイト(GiB)のディスクをリクエストし、単一のノードによる読み取り / 書き込みモードでマウントするようにアクセスモードを指定しています。

# pvc-demo.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-demo
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 30Gi

この PersistentVolumeClaim を kubectl apply -f pvc-demo.yaml で作成すると、Kubernetes によって対応する PersistentVolume オブジェクトが動的に作成されます。次の例は、作成された PersistentVolume を示しています。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pvc-cd3fd5e9-695a-11ea-a3da-42010a800003
  uid: ced478c1-695a-11ea-a3da-42010a800003
  annotations:
    kubernetes.io/createdby: gce-pd-dynamic-provisioner
    pv.kubernetes.io/bound-by-controller: "yes"
    pv.kubernetes.io/provisioned-by: kubernetes.io/gce-pd
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 30Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: pvc-demo
    uid: cd3fd5e9-695a-11ea-a3da-42010a800003
  gcePersistentDisk:
    fsType: ext4
    pdName: gke-cluster-1-pvc-cd3fd5e9-695a-11ea-a3da-42010a800003
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: failure-domain.beta.kubernetes.io/zone
          operator: In
          values:
          - us-central1-c
        - key: failure-domain.beta.kubernetes.io/region
          operator: In
          values:
          - us-central1
  persistentVolumeReclaimPolicy: Delete
  storageClassName: standard
  volumeMode: Filesystem
status:
  phase: Bound

デフォルトのストレージ クラスがそのまま GKE で使用される場合、この PersistentVolume は新しい空の Compute Engine 永続ディスクでバックアップされます。クレームを Volume として使用する場合、このディスクが Pod で使用されます。クレームを削除すると、対応する PersistentVolume オブジェクトとプロビジョニングされた Compute Engine の永続ディスクも削除されます。

動的にプロビジョニングされた永続ディスクが削除されないようにするには、PersistentVolume リソースまたはその StorageClass リソースの再利用ポリシーを Retain に設定します。この場合、PersistentVolumeClaim を使用していなくても、永続ディスクが存在する限り永続ディスクの料金が発生します。再利用ポリシーの変更方法の例については、PersistentVolume の再利用ポリシーの変更StorageClass リソースをご覧ください。

アクセスモード

PersistentVolume では次のアクセスモードがサポートされています。

  • ReadWriteOnce: ボリュームを単一のノードで読み取り書き込み可能としてマウントできます。
  • ReadOnlyMany: ボリュームを多数のノードで読み取り専用としてマウントできます。
  • ReadWriteMany: ボリュームを多数のノードで読み取り書き込み可能としてマウントできます。Compute Engine の永続ディスクを使用する PersistentVolume では、このアクセスモードは使用できません。

Compute Engine の永続ディスクを ReadOnlyMany として使用する

永続ディスクは通常は ReadWriteOnce として使用され、ほとんどのアプリケーションでデフォルトのアクセスモードとなっています。Compute Engine の永続ディスクでは ReadOnlyMany モードもサポートされているため、同じアプリケーションで多数のアプリケーションや多数のレプリカが同じディスクを同時に使用できます。その例として、複数のレプリカ間での静的コンテンツの提供があります。

詳細については、複数のリーダーで使用する永続ディスクの作成方法の記事をご覧ください。

既存の永続ディスクを PersistentVolume として使用する

動的にプロビジョニングされた PersistentVolume は、作成時は空の状態です。既存の Compute Engine 永続ディスクにデータが格納されている場合は、対応する PersistentVolume リソースを手動で作成してクラスタに導入できます。永続ディスクはクラスタノードと同じ [ゾーン] に存在する必要があります。

詳細については、既存の永続ディスクを使用する永続ボリュームの作成方法をご覧ください。

Deployment と StatefulSet の比較

PersistentVolumeClaims テンプレートまたは VolumeClaim テンプレートは、DeploymentsStatefulSets などの上位レベルのコントローラでそれぞれ使用できます。

Deployment はステートレス アプリケーション用に設計されているため、Deployment のすべてのレプリカで同じ PersistentVolumeClaim が共有されます。作成されたレプリカ Pod はそれぞれ同一であるため、この設定では ReadOnlyMany モードと ReadWriteMany モードのボリュームだけが動作します。

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 が、ディスクと同じゾーンにスケジュールされます。

クラスタ内の永続ディスクを動的にプロビジョニングする場合は、StorageClass で WaitForFirstConsumer ボリューム バインディング モードを設定することをおすすめします。この設定により、Kubernetes は Pod がスケジュールされているのと同じゾーンに永続ディスクをプロビジョニングします。反アフィニティやノードセレクタなどの Pod のスケジューリング制約が考慮されます。ゾーンの反アフィニティにより、StatefulSet Pod がゾーンとそれに対応するディスクに分散されます。

WaitForFirstConsumer を設定するゾーン永続ディスクをプロビジョニングするための StorageClass の例を、次に示します。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: slow
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-standard
  fstype: ext4
volumeBindingMode: WaitForFirstConsumer

リージョン永続ディスクの使用例については、リージョン永続ディスクのプロビジョニングをご覧ください。

次のステップ