メインコンテンツへスキップ

Kubernetes ボリュームの 5 種類と活用方法

Table of Contents

このページを共有

Yifat Perry
Yifat Perry

Kubernetes のボリュームは、Kubernetes の Pod 内でコンテナーがアクセスできるデータ用ディレクトリです。ディレクトリの場所、基盤となるストレージ媒体、および内容は、ボリュームの種類によって異なります。

Pod 内のコンテナーで実行されるプロセスは、次の要素で構成されるファイルシステムを参照します。

  • コンテナー イメージの内容に一致する ルート ファイルシステム
  • (定義されていれば)コンテナーにマウントされた ボリューム。各ボリュームは、コンテナーのファイルシステム内の特定のパスにマウントされます。

ボリュームは Pod テンプレートの .spec.containers[*].volumeMounts で定義します。各 Pod とその中の各コンテナー イメージについて、どのボリュームをどのパスにマウントするか(パスはコンテナーごとに異なって構いません)を指定する必要があります。

Kubernetes にはさまざまなボリュームの種類があります。主なものは、Kubernetes ノード上にローカル保存され Pod の再起動で削除される「一時(エフェメラル)ボリューム」 と、Pod の停止後もデータを保持する「永続ボリューム(PV)」 です。

Kubernetes ボリュームの 5 種類

Kubernetes は複数種のボリュームをサポートしており、各 Pod は同時に複数のボリューム タイプを利用できます。エフェメラル(短命)ボリュームは Pod のライフサイクルに連動し、永続ボリュームはそのライフサイクルを超えて存続します。つまり、Pod が消滅すると一時ボリュームは破棄されますが、永続ボリュームのデータは保持されます。

永続ボリューム

Kubernetes には、ストレージのプロビジョニングと利用を抽象化する PersistentVolume(永続ボリューム)サブシステム があり、API として PersistentVolume(PV)PersistentVolumeClaim(PVC) の 2 つのリソースで構成されています。

PersistentVolume(PV)

PV はクラスター内のストレージ リソースです。管理者が手動で用意することも、Kubernetes が StorageClass を用いて動的にプロビジョニングすることもできます。PV はボリュームと同様に「プラグイン」ですが、そのライフサイクルはそれを利用する Pod から独立しています。

 PV は API オブジェクトとして、iSCSINFS、クラウド ベンダーのストレージ システムなど、ストレージ実装の詳細を保持します。ノードに似た概念ですが、提供するのは計算資源ではなくストレージ資源です。

PersistentVolumeClaim(PVC)

PVC はユーザーによるストレージ要求です。Pod がノード資源を消費するのと同様に、PVC は PV 資源を消費します。PVC では、必要なストレージ特性を指定でき、サイズやアクセス モード(ReadWriteOnce / ReadWriteMany / ReadOnlyMany)を明示できます。

 PVC により、ユーザーは抽象化されたストレージ資源を利用できますが、ユースケースごとに異なる特性の PV が求められることが一般的です。そこでクラスター管理者は、サイズやアクセス モードだけでなく特性の異なる複数の PV を用意する必要があります。これは、ユーザーに実装詳細を意識させることなく、StorageClass リソースを通じて実現できます。

関連コンテンツ: Kubernetes PVC ガイド

一時(エフェメラル)ボリューム

一時(エフェメラル)ボリュームは、再起動をまたいでデータを恒久的に保持しません。これらのボリュームは Pod のライフサイクルに連動しており、Pod と同時に作成・削除されます。これにより、永続ボリュームの可用性に制約されることなく、Pod を停止して再起動できます。

一時ボリュームは、プロビジョニングと管理が容易で、Pod の仕様内にインラインで指定できます。永続ストレージを必要としないアプリケーション(例:キャッシュ サービス)に最適です。

EmptyDir ボリューム

EmptyDir ボリュームは、Kubernetes が Pod をノードに割り当てたときに作成されます。このボリュームの存続期間は、その特定ノード上で動作する Pod のライフサイクルに連動します。コンテナーが再起動したりクラッシュした場合、EmptyDir ボリューム自体は再作成されますが、Pod がノードから削除・クラッシュ・障害で失われると、このボリューム内のデータは消去され、失われます。

EmptyDir ボリュームを作成した後は、Pod マニフェストでボリューム種別名をフィールドとして宣言できます。ボリュームのプロパティ セクションで、値が空の中括弧 {} として表示されます。EmptyDir ボリュームは主に一時的なデータ保存に適しており、たとえばディスクベースのマージ処理などの一時作業領域として利用できます。

EmptyDir ボリュームは、そのノードの基盤ストレージ上(例:ネットワーク ストレージや SSD)に保存できます。あるいは、emptyDir.medium フィールドで "memory" を指定することも可能です。この場合、Kubernetes は RAM を裏付けとするファイルシステム(tmpfs)をマウントします。なお、ノードが再起動されると Kubernetes は tmpfs を消去する点に注意してください。

Kubernetes hostPath ボリューム

hostPath ボリュームは、ホスト ノードのファイルシステム上のディレクトリまたはファイルを Pod にマウントします。

主なユースケース

  • コンテナーから Docker の内部情報へアクセスする必要がある場合、/var/lib/docker の hostPath を使用する。
  • コンテナー内で cAdvisor を実行するために、/sys の hostPath を使用する。
  • Pod 実行前に特定のホスト パスの存在要件や、自動作成の可否を定義できるよう、Pod に hostPath を指定する。
  • hostPath ボリュームにタイプを指定する(必須のパス指定に加えて設定可能)。

hostPath ボリュームのセキュリティ

hostPath は多くのセキュリティ リスクを伴います。可能な限り使用を避け、やむを得ず使用する場合は、必要最小限のディレクトリ/ファイルのみに限定し、読み取り専用 でマウントしてください。

主なリスク:

  • 認証情報の露出: hostPath により、特権的なシステム認証情報や特権 API が露出する可能性があります。攻撃者に悪用されると、クラスターの他領域への攻撃やコンテナーからの脱出につながり得ます。
  • root 権限の問題: 基盤ホスト上で作成されるディレクトリやファイルは、書き込み可能なのが通常 root のみです。hostPath ボリュームに書き込むには、ホスト側のファイル権限を変更するか、特権コンテナー内でプロセスを root として実行する必要があります。

AdmissionPolicy を用いて、hostPath のアクセス先を特定ディレクトリに制限できます。ただし、このポリシーは、VolumeMounts に読み取り専用マウントの使用を求める 場合にのみ有効性が高まります。

Kubernetes の ConfigMap ボリューム

ConfigMap は、Pod に設定データを挿入するための仕組みです。ConfigMap に保存したデータは ConfigMap ボリューム タイプ で参照でき、Pod 内で動作するコンテナー化アプリケーションから利用できます。ConfigMap を参照する際は、ボリューム定義内でその ConfigMap 名 を指定する必要があります。Kubernetes では、ConfigMap 内の特定エントリに対して マウント先パスをカスタマイズ することも可能です。

Kubernetes ボリューム用ストレージ プラグイン

Kubernetes には、クラスター内で提供されるストレージ デバイスへアクセスするための複数のストレージ プラグインが用意されており、これらは StorageClass オブジェクトを用いて実装されます。

 現在 Kubernetes がサポートする代表的なプラグインには、GCEPersistentDisk、AWSElasticBlockStore、AzureDisk、GlusterFS、NFS、iSCSI などがあります。各プラグインの詳細は StorageClass のドキュメント を参照してください。

ここでは、注目すべき 2 つのストレージ プラグインを詳しく見ていきます。

NFS

Network File System (NFS) は、ストレージ デバイスをローカル ドライブとしてマウントするための標準プロトコルです。Kubernetes では、NFS ボリュームをコンテナー内のローカル ドライブとしてマウントできます。レガシー コードが NFS 経由でデータへアクセスするケースが多いため、レガシー ワークロードを Kubernetes へ移行する際に非常に有用なプラグインです。

NFS と Kubernetes でデータへアクセスする方法は主に 2 つあります。

  • 一時的 NFS ボリューム — 既存の NFS ストレージにアタッチして使用。
  • NFS を用いた PersistentVolume — クラスター上に NFS でアクセスする管理対象リソースを設定可能。

CSI

Container Storage Interface (CSI) は、コンテナー オーケストレーターが管理下のコンテナーに対してストレージ システムを利用可能にするための標準インターフェースです。CSI により、ストレージ ベンダーは「アウト・オブ・ツリー」のプラグインを作成できます。これは、プラグインを Kubernetes のコード リポジトリに組み込む必要がなく、Kubernetes 本体に同梱されないことを意味します。

CSI に基づくアウト・オブ・ツリー プラグインは数多く存在し、ストレージ ベンダーから直接提供されています。CSI の導入により、ストレージ技術による Kubernetes への対応は大幅に容易になりました。

関連コンテンツ: Container Storage Interface ガイド

Kubernetes の volumeMounts とは何ですか?

ボリュームを作成し、Pod から利用可能にするには、次の 2 つの手順が必要です。

  1. Pod テンプレートの spec: volumes プロパティで宣言し、Pod をいずれかのノードにデプロイする。
  2. コンテナーの volumeMounts プロパティを用いて、特定のコンテナーにボリュームをマウントする。

これらの手順は常にセットで行います。ボリュームを作成したら、必ずコンテナーにマウントする必要があります。逆に、Pod テンプレートで宣言せずにボリュームをマウントすることはできません。

以下は、Pod テンプレートの YAML 構成で、ボリュームの作成とマウントの両方を示す例です。

spec:
  containers:
 —name: my-app
    image: nginx
    volumeMounts:
   —name: my-volume
      mountPath: /app/config
  volumes:
 —name: my-volume

このコードでは次のとおりです。

  • volumes(下部)は my-volume という名前のボリュームを作成し、Pod にアタッチします。
  • volumeMounts は、ボリュームをどのパスに・どのようにマウントするか(コンテナー内での利用パスを含む)を定義します。

重要点:ボリューム名は、volumes の宣言と volumeMounts の指定で同一にする必要があります。

Pod をデプロイして Kubernetes ボリュームを作成する

Kubernetes のボリュームを作成するには、そのボリュームを宣言した 1 つ以上の Pod をデプロイします。一般的な方法として、Deployment オブジェクトを使用します。以下は、次の内容を実行する Deployment マニフェストの例です。

  • NGINX コンテナーを持つ Pod を 3 つ デプロイする
  • emptyDir ボリューム を宣言する
  • そのボリュームを 3 つの各コンテナーのルート ディレクトリ にマウントする
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 with Volumes」として定義されています。Kubernetes 環境ではこの名称で参照されます。

前節で見たとおり、この Deployment オブジェクトはボリューム作成に必要な 2 つの処理を行います。

  • spec: template: volumes プロパティでボリュームを宣言する。
  • spec: containers: volumeMounts プロパティでボリュームをコンテナーにマウントする。

この 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 による Kubernetes ボリューム管理

NetApp Cloud Volumes ONTAP は、エンタープライズ向けのリーディング ストレージ管理ソリューションであり、AWS、Azure、Google Cloud 上で安全かつ実績あるストレージ管理サービスを提供します。容量はペタバイト級までスケール可能で、ファイル サービス、データベース、DevOps、その他のエンタープライズ ワークロードなど幅広いユースケースをサポートします。さらに、高可用性、データ保護、ストレージ効率化、Kubernetes 連携など強力な機能を備えています。

特に Cloud Volumes ONTAP は、コンテナ化ワークロード向けの Kubernetes Persistent Volume のプロビジョニングおよび管理要件 をサポートします。

また、Cloud Volumes ONTAP を活用した Kubernetes ワークロードの事例研究 では、コンテナ化アプリケーションの課題解決に Cloud Volumes ONTAP がどのように貢献するかを詳しく紹介しています。

Yifat Perry

Yifat Perry

Yifat Perryのすべての投稿を見る
Kubernetes ボリュームの 5 種類と活用方法|NetApp