2.16. ボリュームスナップショットを使用した永続ストレージ

重要

ボリュームスナップショットは OpenShift Container Platform 4.2 で非推奨となりました。

本書では、OpenShift Container Platform で VolumeSnapshot を使用してデータ損失から保護する方法を説明します。永続ボリュームについてある程度理解していることが推奨されます。

重要

ボリュームのスナップショットはテクノロジープレビュー機能です。テクノロジープレビュー機能は Red Hat の実稼働環境でのサービスレベルアグリーメント (SLA) ではサポートされていないため、Red Hat では実稼働環境での使用を推奨していません。Red Hat は実稼働環境でこれらを使用することを推奨していません。これらの機能は、近々発表予定の製品機能をリリースに先駆けてご提供することにより、お客様は機能性をテストし、開発プロセス中にフィードバックをお寄せいただくことができます。

Red Hat のテクノロジープレビュー機能のサポート範囲についての詳細は、https://access.redhat.com/ja/support/offerings/techpreview/ を参照してください。

2.16.1. スナップショット

ボリュームスナップショットは、クラスター内のストレージボリュームから作成されたスナップショットです。外部のスナップショットコントローラーおよびプロビジョナーは、この機能を OpenShift Container Platform クラスターで使用して OpenShift Container Platform API を使用してボリュームスナップショットを処理します。

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

  • PersistentVolumeClaim にバインドされる PersistentVolume のスナップショットを作成します。
  • 既存の VolumeSnapshot を一覧表示します。
  • 既存の VolumeSnapshot を削除します。
  • 既存の VolumeSnapshot から PersistentVolume を新たに作成します。

サポートされている PersistentVolume タイプ:

  • AWS Elastic Block Store (EBS)
  • Google Compute Engine (GCE) Persistent Disk (PD)

2.16.2. 外部のコントローラーおよびプロビジョナー

コントローラーおよびプロビジョナーは、ボリュームのスナップショットを提供します。これらの外部コンポーネントはクラスターで実行されます。

ボリュームのスナップショットを提供する外部コンポーネントが 2 つあります。

外部コントローラー
ボリュームスナップショットのイベントを作成、削除、および報告します。
外部プロビジョナー
VolumeSnapshot から新規の PersistentVolume を作成します。

外部のコントローラーおよびプロビジョナーサービスはコンテナーイメージとして配布され、OpenShift Container Platform クラスターで通常どおり実行できます。

2.16.2.1. 外部のコントローラーおよびプロビジョナーの実行

クラスター管理者は、外部コントローラーおよびプロビジョナーを実行するようにアクセスを設定する必要があります。

手順

API オブジェクトを管理しているコンテナーを許可するには、以下の手順を実行します。

  1. ServiceAccount と ClusterRole を作成します。

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: snapshot-controller-runner
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: snapshot-controller-role
    rules:
      - apiGroups: [""]
        resources: ["persistentvolumes"]
        verbs: ["get", "list", "watch", "create", "delete"]
      - apiGroups: [""]
        resources: ["persistentvolumeclaims"]
        verbs: ["get", "list", "watch", "update"]
      - apiGroups: ["storage.k8s.io"]
        resources: ["storageclasses"]
        verbs: ["get", "list", "watch"]
      - apiGroups: [""]
        resources: ["events"]
        verbs: ["list", "watch", "create", "update", "patch"]
      - apiGroups: ["apiextensions.k8s.io"]
        resources: ["customresourcedefinitions"]
        verbs: ["create", "list", "watch", "delete"]
      - apiGroups: ["volumesnapshot.external-storage.k8s.io"]
        resources: ["volumesnapshots"]
        verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
      - apiGroups: ["volumesnapshot.external-storage.k8s.io"]
        resources: ["volumesnapshotdatas"]
        verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  2. クラスター管理者として、hostNetwork SCC (security context constraint) を提供します。

    # oc adm policy add-scc-to-user hostnetwork -z snapshot-controller-runner

    この SCC は、Pod が使用している snapshot-controller-runner サービスアカウントへのアクセスを制御します。

  3. ClusterRoleBinding でルールをバインドします。

    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRoleBinding
    metadata:
      name: snapshot-controller
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: snapshot-controller-role
    subjects:
    - kind: ServiceAccount
      name: snapshot-controller-runner
      namespace: default 1
    1
    snapshot-controller が置かれているプロジェクト名を指定します。

2.16.2.2. AWS および GCE 認証

外部のコントローラーおよびプロビジョナーを認証するには、クラウドプロバイダーの管理者がシークレットを提供する必要があります。

2.16.2.2.1. AWS 認証

外部のコントローラーおよびプロビジョナーを Amazon Web Services (AWS) にデプロイしている場合、AWS はアクセスキーを使用して認証できる必要があります。

認証情報を Pod に提供するために、クラスター管理者は以下のように新規のシークレットを作成します。

apiVersion: v1
kind: Secret
metadata:
  name: awskeys
type: Opaque
data:
  access-key-id: <base64 encoded AWS_ACCESS_KEY_ID>
  secret-access-key: <base64 encoded AWS_SECRET_ACCESS_KEY>
重要

awskeys シークレットに必要な base64 値を生成する際に、以下のように末尾の改行文字を削除します。

$ echo -n "<aws_access_key_id>" | base64
$ echo -n "<aws_secret_access_key>" | base64

以下の例は、外部コントローラーおよびプロビジョナーコンテナーの AWS デプロイメントを表示しています。これら両方の Pod コンテナーはシークレットを使用して AWS API にアクセスします。

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: snapshot-controller
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: snapshot-controller
    spec:
      serviceAccountName: snapshot-controller-runner
      hostNetwork: true
      containers:
        - name: snapshot-controller
          image: "registry.redhat.io/openshift3/snapshot-controller:latest"
          imagePullPolicy: "IfNotPresent"
          args: ["-cloudprovider", "aws"]
          env:
            - name: AWS_ACCESS_KEY_ID
              valueFrom:
                secretKeyRef:
                  name: awskeys
                  key: access-key-id
            - name: AWS_SECRET_ACCESS_KEY
              valueFrom:
                secretKeyRef:
                  name: awskeys
                  key: secret-access-key
        - name: snapshot-provisioner
          image: "registry.redhat.io/openshift3/snapshot-provisioner:latest"
          imagePullPolicy: "IfNotPresent"
          args: ["-cloudprovider", "aws"]
          env:
            - name: AWS_ACCESS_KEY_ID
              valueFrom:
                secretKeyRef:
                  name: awskeys
                  key: access-key-id
            - name: AWS_SECRET_ACCESS_KEY
              valueFrom:
                secretKeyRef:
                  name: awskeys
                  key: secret-access-key
2.16.2.2.2. GCE 認証

Google Compute Engine (GCE) の場合、GCE API にアクセスするためにシークレットを使用する必要はありません。

管理者は、以下の例で示すようにデプロイメントに進むことができます。

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: snapshot-controller
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: snapshot-controller
    spec:
      serviceAccountName: snapshot-controller-runner
      containers:
        - name: snapshot-controller
          image: "registry.redhat.io/openshift3/snapshot-controller:latest"
          imagePullPolicy: "IfNotPresent"
          args: ["-cloudprovider", "gce"]
        - name: snapshot-provisioner
          image: "registry.redhat.io/openshift3/snapshot-provisioner:latest"
          imagePullPolicy: "IfNotPresent"
          args: ["-cloudprovider", "gce"]

2.16.2.3. スナップショットユーザーの管理

クラスターの設定によっては、管理者以外のユーザーが API サーバーで VolumeSnapshot オブジェクトを操作できるようにする必要があります。これは、特定のユーザーまたはグループにバインドされる ClusterRole を作成して実行できます。

たとえば、ユーザー「alice」がクラスター内のスナップショットを操作する必要があるとします。クラスター管理者は以下の手順を実行します。

  1. 新規の ClusterRole を定義します。

    apiVersion: v1
    kind: ClusterRole
    metadata:
      name: volumesnapshot-admin
    rules:
    - apiGroups:
      - "volumesnapshot.external-storage.k8s.io"
      attributeRestrictions: null
      resources:
      - volumesnapshots
      verbs:
      - create
      - delete
      - deletecollection
      - get
      - list
      - patch
      - update
      - watch
  2. ClusterRole バインドオブジェクトを作成してクラスターロールをユーザー「alice」にバインドします。

    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRoleBinding
    metadata:
      name: volumesnapshot-admin
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: volumesnapshot-admin
    subjects:
    - kind: User
      name: alice
注記

これは API アクセス設定の一例にすぎません。VolumeSnapshot オブジェクトは他の OpenShift Container Platform API オブジェクトと同様に動作します。API RBAC の管理についての詳細は、API アクセス制御についてのドキュメントを参照してください。

2.16.3. スナップショットの作成および削除

Persistent Volume Claim (永続ボリューム要求、PVC) を永続ボリューム (PV) にバインドしてボリュームをプロビジョニングする方法と同様に、VolumeSnapshotData と VolumeSnapshot はボリュームスナップショットの作成に使用されます。

ボリュームスナップショットは、サポートされる PersistentVolume のタイプを使用する必要があります。

2.16.3.1. スナップショットの作成

PV のスナップショットを作成するには、以下の例のように VolumeSnapshot に基づいて VolumeSnapshotData オブジェクトを作成します。

apiVersion: volumesnapshot.external-storage.k8s.io/v1
kind: VolumeSnapshot 1
metadata:
  name: snapshot-demo
spec:
  persistentVolumeClaimName: ebs-pvc 2
1
VolumeSnapshotData オブジェクトは VolumeSnapshot に基づいて自動的に作成されます。
2
persistentVolumeClaimName は、PersistentVolume にバインドされる PersistentVolumeClaim の名前です。この特定 PV のスナップショットが作成されます。

PV のタイプによっては、反映される VolumeSnapshot の状態に応じ、スナップショットの作成操作は複数の段階にわたる場合があります。

  1. 新規 VolumeSnapshot オブジェクトを作成します。
  2. コントローラーを起動します。スナップショット対象の PersistentVolume をフリーズし、アプリケーションを一時停止する必要が生じる場合があります。
  3. スナップショットを作成します。スナップショット対象の PersistentVolume は通常の操作に戻りますが、スナップショット自体は準備状態ではありません(status=True、type=Pending)。
  4. 実際のスナップショットを表す VolumeSnapshotData オブジェクトを作成します。
  5. スナップショットが完了し、使用できる状態になります(status=True、type=Ready)。
重要

データの整合性はユーザーの責任で確保してください (Pod またはアプリケーションの停止、キャッシュのフラッシュ、ファイルシステムのフリーズなど)。

注記

エラーの場合は、VolumeSnapshot の状態にエラー状態が追加されます。

VolumeSnapshot の状態を表示するには、以下を実行します。

$ oc get volumesnapshot -o yaml

以下の例が示すように、ステータスが表示されます。

apiVersion: volumesnapshot.external-storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  clusterName: ""
  creationTimestamp: 2017-09-19T13:58:28Z
  generation: 0
  labels:
    Timestamp: "1505829508178510973"
  name: snapshot-demo
  namespace: default 1
  resourceVersion: "780"
  selfLink: /apis/volumesnapshot.external-storage.k8s.io/v1/namespaces/default/volumesnapshots/snapshot-demo
  uid: 9cc5da57-9d42-11e7-9b25-90b11c132b3f
spec:
  persistentVolumeClaimName: ebs-pvc
  snapshotDataName: k8s-volume-snapshot-9cc8813e-9d42-11e7-8bed-90b11c132b3f
status:
  conditions:
  - lastTransitionTime: null
    message: Snapshot created successfully
    reason: ""
    status: "True"
    type: Ready
  creationTimestamp: null
1
snapshot-controller が置かれているプロジェクト名を指定します。

2.16.3.2. スナップショットの復元

PVC は、スナップショットの復元に使用されます。最初に、管理者は既存の VolumeSnapshot から PersistentVolume を復元するために StorageClass を作成する必要があります。

  1. StorageClass を作成します。

    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      name: snapshot-promoter
    provisioner: volumesnapshot.external-storage.k8s.io/snapshot-promoter
    parameters: 1
      encrypted: "true"
      type: gp2
    1
    gp2 encryption が設定された状態で AWS EBS ストレージを使用している場合、encrypted および type のパラメーターを設定する必要があります。
  2. PVC を作成します。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: snapshot-pv-provisioning-demo
      annotations:
        snapshot.alpha.kubernetes.io/snapshot: snapshot-demo 1
    spec:
      storageClassName: snapshot-promoter 2
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi 3
    1
    復元する VolumeSnapshot の名前。
    2
    VolumeSnapshot を復元するために管理者によって作成されます。
    3
    復元されたスナップショットのストレージサイズは、元の PV サイズに対応するのに十分な大きさである必要があります。

    新規の PersistentVolume が作成されて PersistentVolumeClaim にバインドされます。PV のタイプによっては処理に数分の時間がかかることがあります。

2.16.3.3. スナップショットの削除

VolumeSnapshot を削除するには、以下を実行します。

$ oc delete volumesnapshot/<snapshot-name>

VolumeSnapshot にバインドされている VolumeSnapshotData が自動的に削除されます。