ブログのしゅーくりーむ

技術的なメモとかライフログとか。

Kubernetes と CSI(Container Storage Interface) について

この記事は Kubernetes2 Advent Calendar 4 日目の記事です。

本記事は CSI(Container Storage Interface) と Kubernetes での CSI のサポートについて触れます。 執筆に時間があまり割けなかった為、後でもう少し加筆する、あるいは別途続きの記事を書くかもしれません。

CSI(Container Storage Interface) とは

CSI(Container Storage Interface, 以下 CSI) は Kubernetes など複数の Container Orchestration (CO) から共通のプラグインを使って SP (Storage Provider) とやり取りするためのインタフェース仕様です。 より具体的には、 CO からストレージを抽象化した Volume をアタッチ・デタッチしたりスナップショットを取ったりする機能のためのインタフェースを提供します。 CSIKubernetes とは独立したプロジェクトで進行しております。

github.com

また Kubernetes のプロジェクト以下で、 Kubernetes から SP が提供する CSI プラグインへ通信するための CSIDriver と関連実装を以下プロジェクトで進行しています。

github.com

Kubertenes としては CSI は 1.9 で Alpha 、 1.10 で Beta サポート対象になっています また Kubernetes での CSI 利用については他に既に試されている方もいるようです。 こちらの記事は詳細に踏み込んだ構成説明などもされており、オススメできる内容になっています。

qiita.com

CSI の仕様

CSI のインタフェース仕様は Protocol Buffer で定義されており、以下リポジトリで管理されています。 またこのリポジトリ内の lib/go/ ディレクトリには .proto ファイルの定義に従ったライブラリの Go 実装が配置されています。

github.com

CSIプラグインは Controller plugin, Node plugin の二種類が想定されております。 また CO とこれら CSI プラグイン間は gRPC で通信することが想定されています。

CSI のサービス

CSI のサービスとして以下三種類が想定されています。 構成によっては実装しなくても良いサービスやメソッドがありますが、少なくとも Node Service の NodePublishVolume, NodeUnpublishVolume は実装する必要があります。 (でないと Node から Volume を参照できないはず)

  • Identity Service
    • CO から Plugin のケーパビリティ (後述) やヘルスチェック、メタデータ参照を可能にするサービス
  • Controller Service
    • Node をまたいで Volume の構成を管理するためのサービス
    • Volume のスナップショット操作もサポートする
  • Node Service
    • 各 Node から Volume の操作を可能にするためのサービス

CSI における Volume の状態遷移

CSI で Node から Volume を利用されるまでに、 Volume は基本的に以下のような状態遷移をしていきます。 幾つかの状態は、プラグインが示す後述の CSI ケーパビリティによって存在しなかったりします。

   CreateVolume +------------+ DeleteVolume
 +------------->|  CREATED   +--------------+
 |              +---+----+---+              |
 |       Controller |    | Controller       v
+++         Publish |    | Unpublish       +++
|X|          Volume |    | Volume          | |
+-+             +---v----+---+             +-+
                | NODE_READY |
                +---+----^---+
               Node |    | Node
              Stage |    | Unstage
             Volume |    | Volume
                +---v----+---+
                |  VOL_READY |
                +------------+
               Node |    | Node
            Publish |    | Unpublish
             Volume |    | Volume
                +---v----+---+
                | PUBLISHED  |
                +------------+

ref. https://github.com/container-storage-interface/spec/blob/master/spec.md#volume-lifecycle

CSI のケーパビリティ

CSI プラグインでどのような操作をサポートするかの情報です。 CSI の仕様としては以下 4 種類のケーパビリティをサポートします。

  • PluginCapability
    • CSI プラグイン全体でサポートする機能
    • Controller Service を提供するか、オンラインボリューム拡張をサポートするかなどの情報を含む
    • CO は GetPluginCapabilities メソッドで取得可能
  • VolumeCapability
    • Volume のファイルシステムのタイプやアクセス制御(リードオンリーなのかなど)、容量などの情報を含む
    • CO は CreateVolume, ControllerPublishVolume などのメソッドで指定や値の検証が可能
  • ControllerServiceCapability
    • Create/Delete , Publish/Unpublish などの操作をサポートするかの情報を含む
    • CO は ControllerGetCapabilities メソッドで取得可能
  • NodeServiceCapability
    • Stage/Unstage などの操作をサポートするかの情報を含む
    • CO は NodeGetCapabilities メソッドで取得可能

CSI の利用用途

CSI プラグインとしてはすでに、 NFSiSCSI などの公式のサンプルプラグインを含め、 AWSGCP のストレージサービスの利用を可能とするプラグインが存在します。 以下の公式ドキュメントに既に存在する CSI プラグインに関する記述があります。

kubernetes-csi.github.io

簡単な CSI Plugin の実装を追ってみる

以上だけだと CSI プラグインの動作が把握し難いので、 kubernetes-csi の drivers リポジトリにある HostPath plugin の動作を追ってみます。 このプラグインリポジトリkubernetes への deploy 用 yaml ファイルも同梱されており動作を追うのに便利です。

HostPath plugin では CSI の Identity, Controller, Node 三種類の gRPC サービスを提供します。 その実装は github.com/kubernetes-csi/drivers/tree/master/pkg/hostpath に存在します。

Identity Server は特に特殊な実装をしていません。 github.com/kubernetes-csi/drivers/blob/master/pkg/csi-common に存在する、他の Driver と共通のデフォルトメソッド実装をそのまま使用しています。

Controller Server では CreateVolume, DeleteVolume , CreateSnapshot, DeleteSnapshot, ListSnapshots を実装します。 CreateVolume, DeleteVolume では複雑なことをしておらず、 UUID 付きの名前のディレクトリを掘って Volume に見立て、 map で Volume の管理を行います。 CreateSnapshot, DeleteSnapshot はそれに似て、 Volume のディレクトリを tar czf で固めて同じく UUID 付きのファイルに保存・管理します。

Node Server では NodePublishVolume, NodeUnpublishVolume, NodeStageVolume , NodeUnstageVolume を実装します。 NodePublishVolume, NodeUnpublishVolume は作成された Volume のディレクトリを k8s.io/kubernetes/pkg/util/mount パッケージを介して mount/unmount します。 NodeStageVolume , NodeUnstageVolume は単にリクエストパラメータ中の Volume や ターゲットパスが空でないことをチェックしているだけになります。 HostPath プラグインでは他に複雑なチェックをする必要が無いためこうなっているのではと思われます。

kubernetes 上で想定される構成は以下の通りになっているようです。

おわりに

以上、 CSI とその Kubernetes へのインテグレーションに関する記事でした。 CSI は可搬性を担保しつつ Kubernetes での利用を重要視されて作られているようですが、 CSI の仕様含めエコシステムもまだ枯れているとは言えず、機能も多くはありません。 Kubernetes 用の単なるサンプルとはいえ HostPath プラグインで tar コマンドを実行してスナップショットを作成したりなど、もう少し抽象化されてほしい箇所もまだ存在します。

しかしながら個人的には Kubernetes での柔軟なストレージ利用には、以前の記事で挙げた通りまだまだ課題があると思っており、今後の発展を期待したいと考えています。

syucream.hatenablog.jp