メニュー

Kubernetes CSI: CSI ボリュームの基礎と CSI ドライバーの作成

 : Kubernetes CSI とは何ですか?

目次

このページを共有

Yifat Perry
Yifat Perry

Kubernetes CSI は、Container Storage Interface (CSI) の Kubernetes 固有の実装です。

 CSI 仕様は、ストレージ システムとコンテナー オーケストレーション プラットフォーム (CO) 間の接続を可能にする標準を提供し、Kubernetes におけるストレージ管理の基盤を形成します。

CSI 標準は、任意のブロックおよびファイル ストレージ システムを、Kubernetes のようなコンテナー システム上のワークロードにどのように公開するかを規定しています。ストレージ ソリューションのサードパーティ ベンダーは、CSI を利用してプラグインを作成・提供することができ、Kubernetes のコア コードを変更することなく、新しいストレージ システムと連携させることが可能です。

CSI が必要とされる理由

Container Storage Interface (CSI) が登場する以前、Kubernetes は In-Tree K8S ボリューム プラグイン のみをサポートしており、これらは Kubernetes コア バイナリ内で作成・提供する必要がありました。つまり、ストレージ ベンダーは新しいストレージ システムをサポートするために、自社の K8S プラグインを Kubernetes のコア コードに組み込む必要があったのです。

この課題を解決しようとしたのが、FlexVolume というプラグインベースのソリューションです。FlexVolume では、サードパーティ プラグイン向けに実行可能な API を公開しました。この仕組みは、CSI と同様に k8s バイナリからの分離を実現しましたが、いくつかの問題がありました。

  1. ドライバー ファイルを配置するために、マスターおよびホストのファイルシステムへの root アクセスが必要であったこと。
  2. ホスト側で存在することを前提とした、OS 依存性および事前要件が多かったこと。

CSI はこれらの問題を、コンテナ化と K8S ストレージ プリミティブの活用によって解決しました。CSI は、Out-of-Tree ストレージ プラグインを利用するための事実上の標準的なソリューションとなっています。これにより、ストレージ ベンダーは StorageClass、PersistentVolume (PV)、PersistentVolumeClaim (PVC) といった標準的な K8S プリミティブを用いて、プラグインを提供できるようになりました。

CSI の主な目的は、あらゆるコンテナー オーケストレーターにおいて、あらゆる種類のストレージ システムを提供する仕組みを標準化すること です。

 関連コンテンツ: [Kubernetes 永続ボリューム (Persistent Volumes) ガイド]

CSI ボリュームはどのように使用しますか?

CSI ボリュームは、Kubernetes ワークロードで利用できる PersistentVolume リソースを提供するために使用できます。PersistentVolume は、ワークロードによって要求されたときに 動的に、または手動で提供することが可能です。

動的プロビジョニング

CSI ストレージ プラグインを参照する StorageClass を作成することができます。これにより、Kubernetes ワークロードは動的に PersistentVolume を作成できるようになります。これらの PersistentVolume に保存されたデータは、CSI プラグインで定義されたストレージ デバイス上に保持されます。

たとえば、次の StorageClass は、csi-driver.example.com という CSI プラグインを使用して「Fast-Storage」タイプのストレージ ボリュームをプロビジョニングできるようにします。

(この例および以下の他の例は、公式の Kubernetes CSI ブログ記事で公開されています。)

Kubernetes エンティティが、この StorageClass を要求する PersistentVolumeClaim (PVC) オブジェクトを作成すると、その StorageClass に対応する PersistentVolume が動的にプロビジョニングされます。

次の図は、Fast-Storage StorageClass を参照する PVC の例を示しています。

上記の StorageClass 定義には、タイプ、および mysecret と mynamespace という 2 つのシークレットを含む 3 つのパラメーターがある点にご注意ください。PVC が宣言されると、バックグラウンドで次の処理が行われます。

  1. StorageClass は、CSI プラグイン (csi-driver.example.com) に対して CreateVolume 呼び出しを実行し、ストレージ デバイスへのアクセスを可能にするシークレットを含むパラメーターを渡します。
  2. Kubernetes は、自動的に PersistentVolume (PV) オブジェクトを作成します。これは、CSI プラグイン デバイス上に物理的に保存されるストレージ ボリュームを表します。
  3. Kubernetes は、その PersistentVolume (PV) オブジェクトを対応する PersistentVolumeClaim (PVC) にバインドします。
  4. 以降、要求した Pod またはコンテナーは、そのストレージ ボリュームを利用できるようになります。

 関連ブログ記事: NetApp Trident と Cloud Volumes ONTAP を用いた Kubernetes 永続ボリュームの動的プロビジョニング

手動プロビジョニング

PVC メカニズムを使用せずに、Kubernetes でボリュームを手動でプロビジョニングし、ワークロードで利用可能にすることができます。

次の図は、existingVolumeName という名前のストレージ ボリュームをワークロードで使用できるようにする PV オブジェクトの例を示しています。前述のとおり、CSI ボリュームはストレージ プラグイン csi-driver.example.com を参照しています。

ボリュームのアタッチとマウント

次の図は、Kubernetes Pod テンプレートが PVC を参照して CSI ボリュームにアクセスする方法の一例を示しています。

Pod テンプレートに PersistentVolumeClaim が含まれている場合、Kubernetes は Pod をスケジュールする際に CSI プラグイン内で ControllerPublishVolume、NodeStageVolume、NodePublishVolume を含む複数の処理を実行します。これにより、ストレージ ボリュームが作成・マウントされ、Pod 内で実行されるコンテナーが利用できるようになります。

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

CSI ドライバーのコンポーネント

Kubernetes における CSI ドライバーは、通常、コントローラー コンポーネントとノード コンポーネントで構成されます。

コントローラー コンポーネント

コントローラー プラグインは、Deployment または StatefulSet としてデプロイされ、クラスター内の任意のノードにマウントできます。これには、CSI コントローラー サービス を実装する CSI ドライバーと、1 つまたは複数の サイドカー コンテナー が含まれます。コントローラー サイドカー コンテナーは、通常、Kubernetes オブジェクトとやり取りし、CSI コントローラー サービスを呼び出します。

コントローラーはホストへの直接アクセスを必要とせず、外部のコントロール プレーン サービスおよび Kubernetes API を介してすべての操作を実行できます。高可用性 (HA) を実現するために、複数のコントローラー コンポーネントをデプロイすることも可能ですが、同時に 1 つのコントローラーだけがアクティブになるよう リーダー選出 (Leader Election) を実装する必要があります。

コントローラー サイドカーには、以下が含まれます。

  • external-provisioner
  • external-attacher
  • external-snapshotter
  • external-resizer

どのサイドカーをデプロイメントに含めるかは、サイドカー側で定義された仕様によって異なり、必須ではなく任意です。

コントローラーは、Kubernetes イベントを管理するサイドカー コンテナーと通信し、その後、CSI ドライバーに適切な呼び出しを送信します。呼び出しは EmptyDir ボリューム を介して共有される UNIX ドメイン ソケット によってサイドカーとドライバー間でやり取りされます。

また、コントローラー サイドカーは RBAC (役割ベースのアクセス制御) ルール を使用して Kubernetes オブジェクトとの相互作用を制御します。サイドカーのリポジトリには、RBAC ポリシーに統合できる RBAC 設定の例が提供されています。

ノード コンポーネント

ノード プラグインは、クラスター内のすべてのノードに DaemonSet としてデプロイされます。これには、CSI ノード サービス を実装する CSI ドライバーと、ノード ドライバー レジストラ として機能するサイドカー コンテナーが含まれます。

ノード コンポーネントは、すべてのノード上で動作する kubelet と通信し、CSI ノード サービスへの呼び出しを処理します。これらの呼び出しは、ストレージ システム内のボリュームをマウントまたはアンマウントし、Pod が利用できるようにします。kubelet は、ホスト上で HostPath ボリューム を介して共有される UNIX ドメイン ソケット を使用して CSI ドライバーに呼び出しを行います。さらに、ノード ドライバー レジストラは別の UNIX ドメイン ソケットを利用して、ドライバーを kubelet に登録します。

ノード プラグインは、ドライバー ボリュームをマウントするためにホストへの直接アクセスを必要とします。ファイルシステム マウントやブロック デバイスを kubelet で利用可能にするために、CSI ドライバーには 双方向のマウント ポイント が必要です。これにより、kubelet はドライバー コンテナーによって作成されたマウントを認識できるようになります。

デプロイ

Kubernetes は CSI ボリューム ドライバーのパッケージング方法を規定してはいませんが、Kubernetes 上でコンテナ化された CSI ドライバーを容易にデプロイするための推奨事項を提供しています。

ストレージ ベンダーは、コンテナ化された CSI ボリューム ドライバーを導入する際に、次の手順を実行することが推奨されます。

  • ボリューム プラグインの動作を実装し、UNIX ドメイン ソケットを介して gRPC インターフェースを提供するコンテナーを作成します。このコンテナーは「CSI ボリューム ドライバー」と呼ばれ、CSI 仕様に従って(コントローラー、ノード、アイデンティティ サービスを含む)構成される必要があります。
  • ボリューム ドライバー コンテナーを、Kubernetes チームが提供する追加コンテナー(External-Attacher、External-Provisioner、Cluster-Driver-Registrar、Node-Driver-Registrar、External-Resizer、External-Snapshotter、LivenessProbe など)とグループ化します。これらのコンテナーは、ドライバー コンテナーと Kubernetes の間のやり取りを容易にします。
  • クラスター管理者に、対応する DaemonSet および StatefulSet をデプロイし、Kubernetes クラスターにベンダーのストレージ システムのサポートを追加するよう指示します。

もう 1 つの選択肢として、外部プロビジョナーや外部アタッチャーを含むすべてのコンポーネントを 1 つの DaemonSet にまとめる方法もあります。ただし、この方法はより多くのリソースを消費し、External-Attacher および External-Provisioner コンポーネントのためにリーダー選出プロトコル(例: https://git.k8s.io/contrib/election)を使用する必要があります。

特権 Pod の有効化

Kubernetes クラスターは、CSI ドライバーを使用できるようにするために 特権 Pod を有効化する必要があります。

 たとえば、kubelet および API サーバーに対して --allow-privileged フラグを「true」に設定する必要があります。kubeadm、GCE、GKE などの一部の環境では、これがデフォルト設定となっています。

API サーバーは、次の特権フラグを付けて起動する必要があります。

$ ./kube-apiserver ... --allow-privileged=true ... $ ./kubelet ... --allow-privileged=true …

マウント伝播の有効化

Container Storage Interface (CSI) では、同一ノードまたは Pod 内のコンテナー間でマウント済みボリュームを共有できるようにする マウント伝播機能 が必要です。クラスターの Docker デーモンは、マウント伝播を有効にするためにマウント共有を許可する必要があります。

NetApp Cloud Volumes ONTAP による Kubernetes CSI

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

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

詳しくはこちら:

  • Cloud Volumes ONTAP と Trident を活用した Kubernetes NFS プロビジョニング ファイル サービス
  • Cloud Volumes ONTAP を用いた Kubernetes ワークロードの事例研究 — コンテナ化アプリケーションの課題解決にどのように貢献するかをご紹介します。
Drift chat loading