EFS を使用して PersistentVolume をプロビジョニングする

このページでは、EFS CSI ドライバを使用して GKE on AWS で使用する EFS ベースの PersistentVolume を設定する方法について説明します。Elastic File System(EFS)は、クラスタにネットワーク ファイル システムを提供する基盤の AWS メカニズムです。EFS ベースの PersistentVolume は、EFS アクセス ポイントを介してワークロードがストレージを使用できるようにするクラスタ リソースです。これにより、ワークロードが接続されていない場合でもストレージを維持できます。

GKE on AWS は、PersistentVolume の静的プロビジョニングと動的プロビジョニングの両方をサポートしています。動的プロビジョニングは若干異なる設定を使用しますが、後で行う管理作業が少なくなります。

始める前に

このページで説明する操作を行う前に、次のことを完了しておいてください。

静的プロビジョニングの概要

Elastic File System(EFS)を作成し、静的プロビジョニングを介してクラスタ内のワークロードで使用可能にするプロセスは、次の 4 つのステップから構成されます。

  • EFS リソースを作成する
  • ネットワークを構成する
  • マウント ターゲットを作成する
  • PersistentVolume を作成する

最初のステップは、PersistentVolumeClaim を発行して永続ストレージをリクエストします。この処理はワークロードによって実行されます。

動的プロビジョニングの概要

EFS リソースを作成して、動的プロビジョニングを介して使用可能にするプロセスも、次の 4 つのステップから構成されます。

  • EFS リソースを作成する
  • ネットワークを構成する
  • マウント ターゲットを作成する
  • StorageClass を作成する

StorageClass の作成は 1 回限りのオペレーションです。特定の特性を持つストレージ クラスを定義すると、ワークロードは PersistentVolumeClaim を発行したり、永続ストレージをリクエストできるようになります。これらの特性を持つストレージの PersistentVolumeClaim はすべて同じ StorageClass をリクエストできます。

共通の手順

クラスタで静的プロビジョニングまたは動的プロビジョニングのいずれを使用する場合も、ここで説明する設定を行ってから、静的プロビジョニングまたは動的プロビジョニングの手順に進みます。EFS を作成してアクセス可能にしたら、ワークロードは EFS にアクセスするための最後のステップを実行する必要があります。このステップについては、EFS ストレージを使用するをご覧ください。

AWS EFS リソースを作成する

静的プロビジョニングと動的プロビジョニングのどちらの場合でも EFS リソースが必要です。クラスタで両方を使用する場合は、別々の EFS リソースを作成することも、両方に同じ EFS リソースを使用することもできます。EFS リソースの作成の詳細については、Amazon EFS ファイル システムの作成をご覧ください。

既存の EFS を再利用することもできます。その場合は、このセクションをスキップして、マウント ターゲットを作成するに進んでください。

  1. クラスタが稼働している AWS リージョンを確認します。

    gcloud container aws clusters describe CLUSTER_NAME \
      --location=LOCATION \
      --format="value(awsRegion)"
    

    次のように置き換えます。

    • CLUSTER_NAME: AWS クラスタの名前
    • LOCATION: AWS クラスタの Google Cloud のロケーション
  2. 次のコマンドを使用して、同じ AWS リージョンに EFS リソース システムを作成します。

    aws efs create-file-system \
      --region AWS_REGION \
      --performance-mode generalPurpose \
      --query 'FileSystemId' \
      --output text
    

    次のように置き換えます。

    • AWS_REGION: クラスタが稼働している AWS リージョン

出力には、ファイル システムの ID が含まれます。この値を保存してください。後で必要になります。

マウント ターゲットを作成する

EFS の CSI ドライバは、EFS マウント ターゲットを介してファイル システムにアクセスします。マウント ターゲットは、AWS セキュリティ グループを使用して、基盤となる EFS へのアクセスを制御するプライベート IP アドレスです。

クラスタ内のノードプールが異なるサブネットで実行されている場合は、ノードプールのサブネットごとに個別のマウント ターゲットを作成する必要があります。

この例では、各マウント ターゲットへのアクセスは、マウント ターゲットとノードプール マシンの両方を含む単一のセキュリティ グループによって保護されています。VPC の構成とセキュリティ要件に応じて、この構成を 2 つ以上のセキュリティ グループに分割できます。たとえば、1 つをマウント ターゲット用、もう 1 つをノードプールのワーカーノード用にできます。

  1. EFS へのアクセスを制御する専用のセキュリティ グループを作成します。

    クラスタが稼働している AWS VPC の ID を取得します。

    gcloud container aws clusters describe CLUSTER_NAME \
      --location=LOCATION \
      --format="value(networking.vpcId)"
    

    次のように置き換えます。

    • CLUSTER_NAME
    • LOCATION

    出力には、VPC の ID が含まれます。この値を保存してください。後で必要になります。

  2. EFS マウント ターゲットへのアクセスを制御するセキュリティ グループを作成します。

    aws ec2 create-security-group \
      --group-name gke-efs-security-group \
      --description "EFS security group" \
      --vpc-id VPC_ID \
      --output text
    

    VPC_ID は、クラスタが稼働している AWS VPC の ID に置き換えます。

    出力には、新しいセキュリティ グループの ID が含まれます。この値を保存してください。後で必要になります。

  3. デフォルトでは、AWS は、すべてのアウトバウンド トラフィックを許可するデフォルト ルールでセキュリティ グループを作成します。デフォルトのアウトバウンド ルールを削除します。

    aws ec2 revoke-security-group-egress \
      --group-id SECURITY_GROUP_ID
      --ip-permissions '[{"IpProtocol":"-1","FromPort":-1,"ToPort":-1,"IpRanges":[{"CidrIp":"0.0.0.0/0"}]}]'
    

    SECURITY_GROUP_ID は、AWS セキュリティ グループの ID に置き換えます。

  4. EFS(ポート 2049)のインバウンド トラフィックとアウトバウンド トラフィックを許可します。

    aws ec2 authorize-security-group-ingress \
        --group-id SECURITY_GROUP_ID \
        --protocol tcp \
        --port 2049 \
        --source-group SECURITY_GROUP_ID
    
    aws ec2 authorize-security-group-egress \
        --group-id SECURITY_GROUP_ID \
        --protocol tcp \
        --port 2049 \
        --source-group SECURITY_GROUP_ID
    
  5. 各ノードプールのサブネットに EFS マウント ターゲットを作成します。

    すべてのノードプールに関連付けられているサブネットを一覧表示します。

    gcloud container aws node-pools list \
      --cluster=CLUSTER_NAME \
      --location=LOCATION \
      --format="value(subnetId)"
    

    次のように置き換えます。

    • CLUSTER_NAME
    • LOCATION

    出力はサブネット ID のリストです。この値を保存してください。後で必要になります。

  6. サブネットごとに、セキュリティ グループを適用して、関連する EFS マウント ターゲットを作成します。

    aws efs create-mount-target \
        --file-system-id EFS_ID \
        --subnet-id SUBNET_ID \
        --security-groups SECURITY_GROUP_ID
    

    次のように置き換えます。

    • EFS_ID: EFS リソースの ID。
    • SUBNET_ID: ノードプールのサブネットの ID。
    • SECURITY_GROUP_ID
  7. EFS セキュリティ グループをすべてのクラスタ ノードプールに追加します。

    すべてのノードプールのリストを取得します。

    gcloud container aws node-pools list \
      --cluster=CLUSTER_NAME \
      --location=LOCATION
    

    次のように置き換えます。

    • CLUSTER_NAME
    • LOCATION

    出力には、クラスタのノードプールの名前が含まれます。この値を保存してください。後で必要になります。

  8. 各ノードプールを更新して、新しい EFS セキュリティ グループを含めます。

    gcloud container aws node-pools update NODE_POOL_NAME \
      --cluster=CLUSTER_NAME \
      --location=LOCATION  \
      --security-group-ids=SECURITY_GROUP_IDS
    

    次のように置き換えます。

    • NODE_POOL_NAME: ノードプールの名前。
    • CLUSTER_NAME: クラスタの名前。
    • LOCATION
    • SECURITY_GROUP_IDS は、ワーカーノードのセキュリティ グループ ID のリストです。

PersistentVolume(静的)または StorageClass(動的)を作成する

静的プロビジョニングの場合は、次に PersistentVolume を作成します。動的プロビジョニングの場合は EFS ドライバによって自動的に作成されるので、その代わりに PersistentVolumeClaim で指定するワークロードの StorageClass を定義します。選択したプロビジョニング方法と一致するタブを選択します。

静的プロビジョニング

静的プロビジョニングの場合は、次に、EFS 共有をマウントする PersistentVolume を作成します。

  1. EFS 共有に直接接続するのか、アクセス ポイントを介して接続するのか応じて、適切なタブを選択してください。

    直接接続

    次の YAML マニフェストを efs-volume.yaml という名前のファイルにコピーします。このマニフェストは、先ほど作成した EFS ストレージ クラスを参照します。

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: VOLUME_NAME
    spec:
      capacity:
        # Note: storage capacity is not used by the EFS CSI driver.
        # It is required by the PersistentVolume spec.
        storage: 5Gi
      volumeMode: Filesystem
      accessModes:
        - ReadWriteMany
      persistentVolumeReclaimPolicy: Retain
      storageClassName: "" # storageClassName is not required, see note in the following section.
      claimRef:
        name: CLAIM_NAME
        namespace: default
      csi:
        driver: efs.csi.aws.com
        volumeHandle: EFS_ID
    

    次のように置き換えます。

    • VOLUME_NAME は、永続ボリュームの名前に置き換えます。
    • CLAIM_NAME は、PersistentVolumeClaim に使用する名前に置き換えます。
    • EFS_ID は、EFS リソース ID に置き換えます。例: fs-12345678a

    アクセス ポイント

    アクセス ポイント ベースのボリュームを作成する場合は、手動でプロビジョニングする必要があります。詳細については、EFS アクセス ポイントの操作をご覧ください。

    次の YAML マニフェストを efs-volume.yaml という名前のファイルにコピーします。このマニフェストは、先ほど作成した EFS ストレージ クラスを参照します。

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: VOLUME_NAME
    spec:
      capacity:
        # Note: storage capacity is not used by the EFS CSI driver.
        # It is required by the PersistentVolume spec.
        storage: 5Gi
      volumeMode: Filesystem
      accessModes:
        - ReadWriteMany
      persistentVolumeReclaimPolicy: Retain
      # Set storageClassName to empty string for static provisioning. See [Use an EFS resource](/kubernetes-engine/multi-cloud/docs/aws/how-to/use-efs)
      storageClassName: ""
      claimRef:
        name: CLAIM_NAME
        namespace: default
      csi:
        driver: efs.csi.aws.com
        volumeHandle: EFS_ID::ACCESS_POINT_ID
    

    次のように置き換えます。

    • VOLUME_NAME は、永続ボリュームの名前に置き換えます。
    • CLAIM_NAME は、PersistentVolumeClaim に使用する名前に置き換えます。
    • EFS_ID は、EFS リソース ID に置き換えます。例: fs-12345678a
    • ACCESS_POINT_ID は、アクセス ポイントの ID に置き換えます。例: fsap-1234567890abcde
  2. YAML をクラスタに適用します。

    kubectl apply -f efs-volume.yaml
    

    出力で、PersistentVolume の作成を確認します。

    persistentvolume/VOLUME_NAME created
    
    

動的プロビジョニング

このセクションでは、以前に作成した EFS リソースを参照する StorageClass を作成する方法について説明します。これを行うと、デベロッパーは、EFS リソースを使用するの手順に沿って EFS リソースにアクセスできます。

  1. EFS リソース ID を参照する StorageClass を作成します。

    次の yaml フラグメントを efs-storage-class.yaml という名前の新しいファイルにコピーします。このファイルに記述されている StorageClass の特性を調整する方法については、EFS StorageClass パラメータのドキュメントをご覧ください。

    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      name: EFS_STORAGE_CLASS_NAME
    provisioner: efs.csi.aws.com
    mountOptions:
      - tls
    parameters:
      provisioningMode: efs-ap
      fileSystemId: EFS_ID
      directoryPerms: "700"
    
    

    次のように置き換えます。

    • EFS_STORAGE_CLASS_NAME は、StorageClass に選択した名前に置き換えます。
    • EFS_ID は、EFS リソース ID に置き換えます(例: fs-12345678a)。
  2. YAML をクラスタに適用します。

    kubectl apply -f efs-storage-class.yaml
    

    成功した場合は、このコマンドの出力に次のような行が含まれます。

    storageclass/EFS_STORAGE_CLASS_NAME created

クリーンアップ

前のセクションで作成したリソースを削除するには、次のコマンドを実行します。

  1. kubectl を使用して、クラスタから EFS クレーム リソースを削除します。

    kubectl delete -f efs-claim.yaml
    
  2. 静的プロビジョニングを使用している場合は、kubectl を使用して、関連するリソースをクラスタから削除します。

    kubectl delete -f efs-volume.yaml
    
  3. 動的プロビジョニングを使用している場合は、kubectl を使用して、関連するリソースをクラスタから削除します。

    kubectl delete -f efs-storage-class.yaml
    
  4. マウント ターゲットの ID を確認します。

    aws efs describe-mount-targets \
    --file-system-id EFS_ID \
    --profile adminuser \
    --region AWS_REGION
    

    次のように置き換えます。

    • EFS_ID: EFS リソースの ID
    • AWS_REGION: クラスタが稼働している AWS リージョン

    出力には、マウント ターゲット ID が含まれます。この値を保存してください。後で必要になります。

  5. EFS マウント ターゲットを削除します。

    aws efs delete-mount-target \
    --mount-target-id MOUNT_TARGET_ID \
    --profile adminuser \
    --region AWS_REGION
    

    次のように置き換えます。

    • MOUNT_TARGET_ID: EFS マウント ターゲットの ID
    • AWS_REGION: マウント ターゲットの AWS リージョン
  6. 作成したセキュリティ グループをすべて削除します。

  7. delete-file-system CLI コマンドを使用して、ファイル システムを削除します。describe-file-systems CLI コマンドを使用すると、ファイル システムのリストを取得できます。レスポンスにファイル システム ID が含まれます。

    aws efs delete-file-system \
      --file-system-id EFS_ID \
      --profile adminuser \
      --region AWS_REGION
    

    次のように置き換えます。

    • EFS_ID
    • AWS_REGION

次のステップ