5.4. CSI ボリュームスナップショット

本書では、サポートされる Container Storage Interface (CSI) ドライバーでボリュームスナップショットを使用して、OpenShift Container Platform でデータ損失から保護する方法について説明します。永続ボリューム についてある程度理解していることが推奨されます。

5.4.1. CSI ボリュームスナップショットの概要

スナップショット は、特定の時点におけるクラスター内のストレージボリュームの状態を表します。ボリュームスナップショットは新規ボリュームのプロビジョニングに使用できます。

OpenShift Container Platform は、デフォルトで Container Storage Interface (CSI) ボリュームスナップショットをサポートします。ただし、特定の CSI ドライバーが必要です。

CSI ボリュームのスナップショットを使用して、クラスター管理者は以下を行うことができます。

  • スナップショットをサポートするサードパーティーの CSI ドライバーをデプロイします。
  • 既存のボリュームスナップショットから永続ボリューム要求 (PVC) を新たに作成します。
  • 既存の PVC のスナップショットを作成します。
  • スナップショットを別の PVC として復元します。
  • 既存のボリュームスナップショットを削除します。

CSI ボリュームスナップショットを使用すると、アプリケーション開発者は以下を行うことができます。

  • ボリュームスナップショットは、アプリケーションレベルまたはクラスターレベルのストレージバックアップソリューションを開発するためのビルディングブロックとして使用します。
  • 迅速に直前の開発バージョンにロールバックします。
  • 毎回フルコピーを作成する必要がないため、ストレージをより効率的に使用できます。

ボリュームスナップショットを使用する場合は、以下の点に注意してください。

  • サポートは CSI ドライバーでのみ利用可能です。in-tree (インツリー) および FlexVolumes はサポートされません。
  • OpenShift Container Platform には一部の CSI ドライバーのみが同梱されます。OpenShift Container Platform ドライバー Operator によって提供されない CSI ドライバーについては、コミュニティーまたはストレージベンダー が提供する CSI ドライバーを使用することが推奨されます。CSI ドライバーのプロバイダーが提供するインストール手順に従います。
  • CSI ドライバーは、ボリュームのスナップショット機能を実装している場合もあれば、実装していない場合もあります。ボリュームスナップショットのサポートを提供している CSI ドライバーは、csi-external-snapshotter サイドカーコンテナーを使用する可能性があります。詳細は、CSI ドライバーで提供されるドキュメントを参照してください。

5.4.2. CSI スナップショットコントローラーおよびサイドカー

OpenShift Container Platform は、コントロールプレーンにデプロイされるスナップショットコントローラーを提供します。さらに、CSI ドライバーベンダーは、CSI ドライバーのインストール時にインストールされるヘルパーコンテナーとして CSI スナップショットサイドカーコンテナーを提供します。

CSI スナップショットコントローラーおよびサイドカーは、OpenShift Container Platform API を使用してボリュームのスナップショットを提供します。これらの外部コンポーネントはクラスターで実行されます。

外部コントローラーは CSI スナップショットコントローラー Operator によってデプロイされます。

5.4.2.1. 外部コントローラー

CSI スナップショットコントローラーは VolumeSnapshot および VolumeSnapshotContent オブジェクトをバインドします。コントローラーは、VolumeSnapshotContent オブジェクトを作成し、削除して動的プロビジョニングを管理します。

5.4.2.2. 外部サイドカー

CSI ドライバーベンダーは、csi-external-snapshotter サイドカーを提供します。これは、CSI ドライバーでデプロイされる別のヘルパーコンテナーです。サイドカーは、CreateSnapshot および DeleteSnapshot 操作をトリガーしてスナップショットを管理します。ベンダーが提供するインストールの手順に従います。

5.4.3. CSI スナップショットコントローラー Operator について

CSI スナップショットコントローラー Operator は openshift-cluster-storage-operator namespace で実行されます。これは、デフォルトですべてのクラスターの Cluster Version Operator (CVO) によってインストールされます。

CSI スナップショットコントローラー Operator は、openshift-cluster-storage-operator namespace で実行される CSI スナップショットコントローラーをインストールします。

5.4.3.1. ボリュームスナップショット CRD

OpenShift Container Platform のインストール時に、CSI スナップショットコントローラー Operator は、snapshot.storage.k8s.io/v1 API グループに以下のスナップショットのカスタムリソース定義 (CRD) を作成します。

VolumeSnapshotContent

クラスター管理者がプロビジョニングしたクラスター内のボリュームのスナップショット。

PersistentVolume オブジェクトと同様に、VolumeSnapshotContent CRD はストレージバックエンドの実際のスナップショットを参照するクラスターリソースです。

手動でプロビジョニングされたスナップショットの場合、クラスター管理者は多くの VolumeSnapshotContent CRD を作成します。これらには、ストレージシステム内の実際のボリュームスナップショットの詳細が含まれます。

VolumeSnapshotContent CRD には namespace が使用されず、これはクラスター管理者によって使用されるものです。

VolumeSnapshot

PersistentVolumeClaim オブジェクトと同様に、VolumeSnapshot CRD はスナップショットの開発者要求を定義します。CSI スナップショットコントローラー Operator は、適切な VolumeSnapshotContent CRD で VolumeSnapshot CRD のバインディングを処理する CSI スナップショットコントローラーを実行します。バインディングは 1 対 1 のマッピングです。

VolumeSnapshot CRD には namespace が使用されます。開発者は、CRD をスナップショットの個別の要求として使用します。

VolumeSnapshotClass

クラスター管理者は、VolumeSnapshot オブジェクトに属する異なる属性を指定できます。これらの属性は、ストレージシステムの同じボリュームで作成されるスナップショット間で異なる場合があります。この場合、それらは永続ボリューム要求 (PVC) の同じストレージクラスを使用して表現できません。

VolumeSnapshotClass CRD は、スナップショットの作成時に使用する csi-external-snapshotter サイドカーのパラメーターを定義します。これにより、ストレージバックエンドは、複数のオプションがサポートされる場合に動的に作成するスナップショットの種類を認識できます。

動的にプロビジョニングされるスナップショットは VolumeSnapshotClass CRD を使用して、スナップショットの作成時に使用するストレージプロバイダー固有のパラメーターを指定します。

VolumeSnapshotContentClass CRD には namespace が使用されず、クラスター管理者がストレージバックエンドのグローバル設定オプションを有効にするために使用します。

5.4.4. ボリュームスナップショットのプロビジョニング

スナップショットをプロビジョニングする方法は、動的な方法と手動による方法の 2 種類があります。

5.4.4.1. 動的プロビジョニング

既存のスナップショットを使用する代わりに、スナップショットを永続ボリューム要求 (PVC) から動的に取得するように要求できます。パラメーターは VolumeSnapshotClass CRD を使用して指定されます。

5.4.4.2. 手動プロビジョニング

クラスター管理者は、多数の VolumeSnapshotContent オブジェクトを手動で事前にプロビジョニングできます。これらは、クラスターユーザーが利用できる実際のボリュームのスナップショットの詳細を保持します。

5.4.5. ボリュームスナップショットの作成

VolumeSnapshot オブジェクトを作成すると、OpenShift Container Platform はボリュームスナップショットを作成します。

前提条件

  • 実行中の OpenShift Container Platform クラスターにログインしている。
  • VolumeSnapshot オブジェクトをサポートする CSI ドライバーを使用して作成される PVC。
  • ストレージバックエンドをプロビジョニングするストレージクラス。
  • スナップショットの作成に使用する必要のある永続ボリューム要求 (PVC) を使用している Pod はありません。

    警告

    Pod によって使用されている PVC のボリュームスナップショットを作成すると、書き込まれていないデータやキャッシュされたデータがスナップショットから除外される可能性があります。すべてのデータがディスクに確実に書き込まれるようにするには、PVC を使用している Pod を削除してから、スナップショットを作成してください。

手順

ボリュームのスナップショットを動的に作成するには、以下を実行します。

  1. 以下の YAML によって記述される VolumeSnapshotClass オブジェクトを使用してファイルを作成します。

    volumesnapshotclass.yaml

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshotClass
    metadata:
      name: csi-hostpath-snap
    driver: hostpath.csi.k8s.io 1
    deletionPolicy: Delete

    1
    この VolumeSnapshotClass オブジェクトのスナップショットを作成するために使用される CSI ドライバーの名前。名前は、スナップショットが作成される PVC に対応するストレージクラスの Provisioner フィールドと同じである必要があります。
    注記

    永続ストレージの設定に使用したドライバーによっては、追加のパラメーターが必要になる場合があります。既存の VolumeSnapshotClass オブジェクトを使用することもできます。

  2. 以下のコマンドを実行して、直前の手順で保存されたオブジェクトを作成します。

    $ oc create -f volumesnapshotclass.yaml
  3. VolumeSnapshot オブジェクトを作成します。

    volumesnapshot-dynamic.yaml

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshot
    metadata:
      name: mysnap
    spec:
      volumeSnapshotClassName: csi-hostpath-snap 1
      source:
        persistentVolumeClaimName: myclaim 2

    1
    ボリュームスナップショットによる特定クラスの要求。volumeSnapshotClassName 設定がなく、デフォルトのボリュームスナップショットクラスがある場合、スナップショットはデフォルトのボリュームスナップショットクラス名で作成されます。ただし、フィールドがなく、デフォルトのボリュームスナップショットクラスが存在しない場合には、スナップショットは作成されません。
    2
    永続ボリュームにバインドされる PersistentVolumeClaim オブジェクトの名前。これは、スナップショットの作成に使用する内容を定義します。スナップショットの動的プロビジョニングに必要です。
  4. 以下のコマンドを実行して、直前の手順で保存されたオブジェクトを作成します。

    $ oc create -f volumesnapshot-dynamic.yaml

スナップショットを手動でプロビジョニングするには、以下を実行します。

  1. 上記のようにボリュームスナップショットクラスを定義するだけでなく、volumeSnapshotContentName パラメーターの値をスナップショットのソースとして指定します。

    volumesnapshot-manual.yaml

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshot
    metadata:
      name: snapshot-demo
    spec:
      source:
        volumeSnapshotContentName: mycontent 1

    1
    事前にプロビジョニングされたスナップショットには、volumeSnapshotContentName パラメーターが必要です。
  2. 以下のコマンドを実行して、直前の手順で保存されたオブジェクトを作成します。

    $ oc create -f volumesnapshot-manual.yaml

検証

スナップショットがクラスターで作成されると、スナップショットに関する追加情報が利用可能になります。

  1. 作成したボリュームスナップショットの詳細を表示するには、以下のコマンドを実行します。

    $ oc describe volumesnapshot mysnap

    以下の例は、mysnap ボリュームスナップショットについての詳細を表示します。

    volumesnapshot.yaml

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshot
    metadata:
      name: mysnap
    spec:
      source:
        persistentVolumeClaimName: myclaim
      volumeSnapshotClassName: csi-hostpath-snap
    status:
      boundVolumeSnapshotContentName: snapcontent-1af4989e-a365-4286-96f8-d5dcd65d78d6 1
      creationTime: "2020-01-29T12:24:30Z" 2
      readyToUse: true 3
      restoreSize: 500Mi

    1
    コントローラーによって作成された実際のストレージコンテンツへのポインター。
    2
    スナップショットが作成された時間。スナップショットには、このタイミングで利用できるボリュームコンテンツが含まれます。
    3
    値が true に設定されている場合、スナップショットを使用して新規 PVC として復元できます。
    値が false に設定されている場合、スナップショットが作成されています。ただし、ストレージバックエンドは、スナップショットを新規ボリュームとして復元できるようにするために、追加のタスクを実行してスナップショットを使用できる状態にする必要があります。たとえば、Amazon Elastic Block Store データを別の低コストの場所に移動する場合があり、これには数分の時間がかかる可能性があります。
  2. ボリュームのスナップショットが作成されたことを確認するには、以下のコマンドを実行します。

    $ oc get volumesnapshotcontent

    実際のコンテンツへのポインターが表示されます。boundVolumeSnapshotContentName フィールドにデータが設定される場合、VolumeSnapshotContent オブジェクトが存在し、スナップショットが作成されています。

  3. スナップショットの準備が完了していることを確認するには、VolumeSnapshot オブジェクトに readyToUse: true があることを確認します。

5.4.6. ボリュームスナップショットの削除

OpenShift Container Platform によるボリュームスナップショットの削除方法を設定できます。

手順

  1. 以下の例のように、VolumeSnapshotClass オブジェクトで必要な削除ポリシーを指定します。

    volumesnapshotclass.yaml

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshotClass
    metadata:
      name: csi-hostpath-snap
    driver: hostpath.csi.k8s.io
    deletionPolicy: Delete 1

    1
    ボリュームスナップショットの削除時に Delete 値を設定すると、VolumeSnapshotContent オブジェクトと共に基礎となるスナップショットが削除されます。Retain 値を設定すると、基礎となるスナップショットと VolumeSnapshotContent オブジェクトの両方が残ります。
    Retain 値を設定し、対応する VolumeSnapshotContent オブジェクトを削除せずに VolumeSnapshot オブジェクトを削除すると、コンテンツは残ります。スナップショット自体はストレージバックエンドにも保持されます。
  2. 以下のコマンドを入力してボリュームスナップショットを削除します。

    $ oc delete volumesnapshot <volumesnapshot_name>

    出力例

    volumesnapshot.snapshot.storage.k8s.io "mysnapshot" deleted

  3. 削除ポリシーが Retain に設定されている場合は、以下のコマンドを入力してボリュームスナップショットのコンテンツを削除します。

    $ oc delete volumesnapshotcontent <volumesnapshotcontent_name>
  4. オプション: VolumeSnapshot オブジェクトが正常に削除されていない場合は、以下のコマンドを実行して残されているリソースのファイナライザーを削除し、削除操作を続行できるようにします。

    重要

    永続ボリューム要求 (PVC) またはボリュームスナップショットのコンテンツのいずれかから VolumeSnapshot オブジェクトへの既存の参照がない場合にのみファイナライザーを削除します。--force オプションを使用する場合でも、すべてのファイナライザーが削除されるまで削除操作でスナップショットオブジェクトは削除されません。

    $ oc patch -n $PROJECT volumesnapshot/$NAME --type=merge -p '{"metadata": {"finalizers":null}}'

    出力例

    volumesnapshotclass.snapshot.storage.k8s.io "csi-ocs-rbd-snapclass" deleted

    ファイナライザーが削除され、ボリュームスナップショットが削除されます。

5.4.7. ボリュームスナップショットの復元

VolumeSnapshot CRD コンテンツは、既存のボリュームを以前の状態に復元するために使用されます。

VolumeSnapshot CRD がバインドされ、readyToUse 値が true に設定された後に、そのリソースを使用して、スナップショットからのデータが事前に設定されている新規ボリュームをプロビジョニングできます。前提条件: * 実行中の OpenShift Container Platform クラスターにログインしている。ボリュームスナップショットをサポートする Container Storage Interface (CSI) ドライバーを使用して作成される永続ボリューム要求 (PVC)。* ストレージバックエンドをプロビジョニングするストレージクラス。* ボリュームスナップショットが作成され、使用できる状態である。

手順

  1. 以下のように PVC に VolumeSnapshot データソースを指定します。

    pvc-restore.yaml

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: myclaim-restore
    spec:
      storageClassName: csi-hostpath-sc
      dataSource:
        name: mysnap 1
        kind: VolumeSnapshot 2
        apiGroup: snapshot.storage.k8s.io 3
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi

    1
    ソースとして使用するスナップショットを表す VolumeSnapshot オブジェクトの名前。
    2
    VolumeSnapshot の値に設定する必要があります。
    3
    snapshot.storage.k8s.io の値に設定する必要があります。
  2. 以下のコマンドを実行して PVC を作成します。

    $ oc create -f pvc-restore.yaml
  3. 以下のコマンドを実行して、復元された PVC が作成されていることを確認します。

    $ oc get pvc

    myclaim-restore などの新規 PVC が表示されます。