Kubernetes のボリュームは、Kubernetes の Pod 内でコンテナーがアクセスできるデータ用ディレクトリです。ディレクトリの場所、基盤となるストレージ媒体、および内容は、ボリュームの種類によって異なります。
Pod 内のコンテナーで実行されるプロセスは、次の要素で構成されるファイルシステムを参照します。
ボリュームは Pod テンプレートの .spec.containers[*].volumeMounts で定義します。各 Pod とその中の各コンテナー イメージについて、どのボリュームをどのパスにマウントするか(パスはコンテナーごとに異なって構いません)を指定する必要があります。
Kubernetes にはさまざまなボリュームの種類があります。主なものは、Kubernetes ノード上にローカル保存され Pod の再起動で削除される「一時(エフェメラル)ボリューム」 と、Pod の停止後もデータを保持する「永続ボリューム(PV)」 です。
Kubernetes は複数種のボリュームをサポートしており、各 Pod は同時に複数のボリューム タイプを利用できます。エフェメラル(短命)ボリュームは Pod のライフサイクルに連動し、永続ボリュームはそのライフサイクルを超えて存続します。つまり、Pod が消滅すると一時ボリュームは破棄されますが、永続ボリュームのデータは保持されます。
Kubernetes には、ストレージのプロビジョニングと利用を抽象化する PersistentVolume(永続ボリューム)サブシステム があり、API として PersistentVolume(PV) と PersistentVolumeClaim(PVC) の 2 つのリソースで構成されています。
PersistentVolume(PV)
PV はクラスター内のストレージ リソースです。管理者が手動で用意することも、Kubernetes が StorageClass を用いて動的にプロビジョニングすることもできます。PV はボリュームと同様に「プラグイン」ですが、そのライフサイクルはそれを利用する Pod から独立しています。
PV は API オブジェクトとして、iSCSI、NFS、クラウド ベンダーのストレージ システムなど、ストレージ実装の詳細を保持します。ノードに似た概念ですが、提供するのは計算資源ではなくストレージ資源です。
PersistentVolumeClaim(PVC)
PVC はユーザーによるストレージ要求です。Pod がノード資源を消費するのと同様に、PVC は PV 資源を消費します。PVC では、必要なストレージ特性を指定でき、サイズやアクセス モード(ReadWriteOnce / ReadWriteMany / ReadOnlyMany)を明示できます。
PVC により、ユーザーは抽象化されたストレージ資源を利用できますが、ユースケースごとに異なる特性の PV が求められることが一般的です。そこでクラスター管理者は、サイズやアクセス モードだけでなく特性の異なる複数の PV を用意する必要があります。これは、ユーザーに実装詳細を意識させることなく、StorageClass リソースを通じて実現できます。
関連コンテンツ: Kubernetes PVC ガイド
一時(エフェメラル)ボリュームは、再起動をまたいでデータを恒久的に保持しません。これらのボリュームは Pod のライフサイクルに連動しており、Pod と同時に作成・削除されます。これにより、永続ボリュームの可用性に制約されることなく、Pod を停止して再起動できます。
一時ボリュームは、プロビジョニングと管理が容易で、Pod の仕様内にインラインで指定できます。永続ストレージを必要としないアプリケーション(例:キャッシュ サービス)に最適です。
EmptyDir ボリュームは、Kubernetes が Pod をノードに割り当てたときに作成されます。このボリュームの存続期間は、その特定ノード上で動作する Pod のライフサイクルに連動します。コンテナーが再起動したりクラッシュした場合、EmptyDir ボリューム自体は再作成されますが、Pod がノードから削除・クラッシュ・障害で失われると、このボリューム内のデータは消去され、失われます。
EmptyDir ボリュームを作成した後は、Pod マニフェストでボリューム種別名をフィールドとして宣言できます。ボリュームのプロパティ セクションで、値が空の中括弧 {} として表示されます。EmptyDir ボリュームは主に一時的なデータ保存に適しており、たとえばディスクベースのマージ処理などの一時作業領域として利用できます。
EmptyDir ボリュームは、そのノードの基盤ストレージ上(例:ネットワーク ストレージや SSD)に保存できます。あるいは、emptyDir.medium フィールドで "memory" を指定することも可能です。この場合、Kubernetes は RAM を裏付けとするファイルシステム(tmpfs)をマウントします。なお、ノードが再起動されると Kubernetes は tmpfs を消去する点に注意してください。
hostPath ボリュームは、ホスト ノードのファイルシステム上のディレクトリまたはファイルを Pod にマウントします。
主なユースケース
hostPath ボリュームのセキュリティ
hostPath は多くのセキュリティ リスクを伴います。可能な限り使用を避け、やむを得ず使用する場合は、必要最小限のディレクトリ/ファイルのみに限定し、読み取り専用 でマウントしてください。
主なリスク:
AdmissionPolicy を用いて、hostPath のアクセス先を特定ディレクトリに制限できます。ただし、このポリシーは、VolumeMounts に読み取り専用マウントの使用を求める 場合にのみ有効性が高まります。
ConfigMap は、Pod に設定データを挿入するための仕組みです。ConfigMap に保存したデータは ConfigMap ボリューム タイプ で参照でき、Pod 内で動作するコンテナー化アプリケーションから利用できます。ConfigMap を参照する際は、ボリューム定義内でその ConfigMap 名 を指定する必要があります。Kubernetes では、ConfigMap 内の特定エントリに対して マウント先パスをカスタマイズ することも可能です。
Kubernetes には、クラスター内で提供されるストレージ デバイスへアクセスするための複数のストレージ プラグインが用意されており、これらは StorageClass オブジェクトを用いて実装されます。
現在 Kubernetes がサポートする代表的なプラグインには、GCEPersistentDisk、AWSElasticBlockStore、AzureDisk、GlusterFS、NFS、iSCSI などがあります。各プラグインの詳細は StorageClass のドキュメント を参照してください。
ここでは、注目すべき 2 つのストレージ プラグインを詳しく見ていきます。
Network File System (NFS) は、ストレージ デバイスをローカル ドライブとしてマウントするための標準プロトコルです。Kubernetes では、NFS ボリュームをコンテナー内のローカル ドライブとしてマウントできます。レガシー コードが NFS 経由でデータへアクセスするケースが多いため、レガシー ワークロードを Kubernetes へ移行する際に非常に有用なプラグインです。
NFS と Kubernetes でデータへアクセスする方法は主に 2 つあります。
Container Storage Interface (CSI) は、コンテナー オーケストレーターが管理下のコンテナーに対してストレージ システムを利用可能にするための標準インターフェースです。CSI により、ストレージ ベンダーは「アウト・オブ・ツリー」のプラグインを作成できます。これは、プラグインを Kubernetes のコード リポジトリに組み込む必要がなく、Kubernetes 本体に同梱されないことを意味します。
CSI に基づくアウト・オブ・ツリー プラグインは数多く存在し、ストレージ ベンダーから直接提供されています。CSI の導入により、ストレージ技術による Kubernetes への対応は大幅に容易になりました。
関連コンテンツ: Container Storage Interface ガイド
ボリュームを作成し、Pod から利用可能にするには、次の 2 つの手順が必要です。
これらの手順は常にセットで行います。ボリュームを作成したら、必ずコンテナーにマウントする必要があります。逆に、Pod テンプレートで宣言せずにボリュームをマウントすることはできません。
以下は、Pod テンプレートの YAML 構成で、ボリュームの作成とマウントの両方を示す例です。
spec: containers: —name: my-app image: nginx volumeMounts: —name: my-volume mountPath: /app/config volumes: —name: my-volume
このコードでは次のとおりです。
重要点:ボリューム名は、volumes の宣言と volumeMounts の指定で同一にする必要があります。
Kubernetes のボリュームを作成するには、そのボリュームを宣言した 1 つ以上の Pod をデプロイします。一般的な方法として、Deployment オブジェクトを使用します。以下は、次の内容を実行する Deployment マニフェストの例です。
apiVersion: apps/v1 kind: Deployment metadata: name: pods-with-volumes spec: replicas: 3 selector: matchLabels: app: demo template: metadata: labels: app: demo spec: containers: —name: my-container image: nginx:1.14.2 volumeMounts: —mountPath: / name: my-volume volumes: —name: my-volume emptyDir: {}
このデプロイメントの名前は「Pods mit Volumes」として定義されています。Kubernetes 環境ではこの名称で参照されます。
前節で見たとおり、この Deployment オブジェクトはボリューム作成に必要な 2 つの処理を行います。
この YAML ファイルを my-deployment.yaml という名前で保存したとします。次のコマンドで、Kubernetes クラスターにデプロイメントを作成できます。
kubectl apply -f my-deployment.yaml
デプロイメントが期待どおりのボリューム構成で正常に動作しているか確認するには、次のコマンドを実行します。
kubectl describe pods pods-with-volumes
すべてが正しく機能していれば、出力には各 Pod に my-container という名前のコンテナーが存在し、指定したマウントポイントが設定されていることが示されます。
Mounts: / from my-volume (rw)
出力には、各 Pod で使用中のボリュームも表示されます。
Volumes: my-volume: Type: EmptyDir (a temporary directory that shares a pod's lifetime)
NetApp Cloud Volumes ONTAP は、エンタープライズ向けのリーディング ストレージ管理ソリューションであり、AWS、Azure、Google Cloud 上で安全かつ実績あるストレージ管理サービスを提供します。容量はペタバイト級までスケール可能で、ファイル サービス、データベース、DevOps、その他のエンタープライズ ワークロードなど幅広いユースケースをサポートします。さらに、高可用性、データ保護、ストレージ効率化、Kubernetes 連携など強力な機能を備えています。
特に Cloud Volumes ONTAP は、コンテナ化ワークロード向けの Kubernetes Persistent Volume のプロビジョニングおよび管理要件 をサポートします。
また、Cloud Volumes ONTAP を活用した Kubernetes ワークロードの事例研究 では、コンテナ化アプリケーションの課題解決に Cloud Volumes ONTAP がどのように貢献するかを詳しく紹介しています。