Amazon EFS CSI ドライバー - Amazon EKS

Amazon EFS CSI ドライバー

Amazon EFS Container Storage Interface (CSI) ドライバーは、AWS で動作する Kubernetes クラスターが Amazon EFS ファイルシステムのライフサイクルを管理できるようにする CSI インターフェイスを提供します。

このトピックでは、Amazon EFS CSI ドライバーを Amazon EKS クラスターにデプロイし、動作確認する方法を示します。

注記

Amazon EFS CSI ドライバーのアルファ機能は、Amazon EKS クラスターではサポートされていません。

使用可能なパラメータの詳細と、ドライバーの機能を示す完全な例については、GitHub の「Amazon EFS Container Storage Interface (CSI) ドライバー」プロジェクトを参照してください。

Considerations

  • Fargate ノードでは動的永続ボリュームプロビジョニングを使用できませんが、静的プロビジョニングを使用することはできます。

  • 動的プロビジョニングには、1.2 以降のドライバーが必要です。これには 1.17 以降のクラスターが必要です。サポートされている Amazon EKS クラスターバージョンでドライバーの 1.1 を使用して、永続ボリュームを静的にプロビジョニングできます。

Prerequisites

  • OIDC プロバイダーを使用した既存クラスター — クラスターがない場合は、Amazon EKS の使用開始 ガイドの 1 つを使用してクラスターを作成できます。既存クラスターの OIDC プロバイダーの有無を判断する、または作成するには、「クラスターの IAM OIDC プロバイダーを作成するには」を参照してください。。

  • AWS CLI – Amazon EKS など AWS のサービスを操作するためのコマンドラインツールです。このガイドでは、バージョン 2.1.26 以降または 1.19.7 以降のツールを使用する必要があります。詳細については、AWS Command Line Interface ユーザーガイドの「AWS CLI のインストール、更新、アンインストール」を参照してください。AWS CLI のインストール後は、設定も行っておくことをお勧めします。詳細については、AWS Command Line Interface ユーザーガイドの「AWS の設定を使用したクイック設定」を参照してください。

  • kubectl — Kubernetes クラスターを操作するためのコマンドラインツール。このガイドでは、バージョン 1.19 以降のツールを使用する必要があります。詳細については、「kubectl のインストール」を参照してください。

IAM ポリシーとロールを作成するには

IAM ポリシーを作成して、それを IAM ロールにアサインします。このポリシーは、Amazon EFS ドライバーがファイルシステムと対話できるようにします。

Amazon EFS CSI ドライバーを Amazon EKS クラスターにデプロイするには

  1. CSI ドライバーのサービスアカウントがユーザーに代わって AWS API を呼び出すことを許可する IAM ポリシーを作成します。

    1. GitHub から IAM ポリシードキュメントをダウンロードします。ポリシードキュメントを表示することもできます。

      curl -o iam-policy-example.json https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/v1.2.0/docs/iam-policy-example.json
    2. ポリシーを作成します。AmazonEKS_EFS_CSI_Driver_Policy を別の名前に変更できますが、変更する場合は、後の手順でも変更してください。

      aws iam create-policy \ --policy-name AmazonEKS_EFS_CSI_Driver_Policy \ --policy-document file://iam-policy-example.json
  2. IAM ロールを作成して、それに IAM ポリシーをアタッチします。IAM ロール ARN で Kubernetes サービスアカウントに、Kubernetes サービスアカウント名で IAM ロールに、注釈を付けます。eksctl または AWS CLI を使用して、ロールを作成できます。

    eksctl

    以下のコマンドは、IAM ロールと Kubernetes サービスアカウントを作成します。また、ポリシーをロールにアタッチし、IAM ロール ARN で Kubernetes サービスアカウントに 注釈を付け、Kubernetes サービスアカウント名を IAM ロールの信頼ポリシーに追加します。クラスターの IAM OIDC プロバイダーがない場合は、コマンドは IAM OIDC プロバイダーも作成できます。

    eksctl create iamserviceaccount \ --name efs-csi-controller-sa \ --namespace kube-system \ --cluster <cluster-name> \ --attach-policy-arn arn:aws:iam::<AWS account ID>:policy/AmazonEKS_EFS_CSI_Driver_Policy \ --approve \ --override-existing-serviceaccounts \ --region us-west-2
    AWS CLI
    1. クラスターの OIDC プロバイダー URL を決定します。<cluster_name> (<> を含む) をクラスター名に置き換えます。コマンドの出力が None の場合は、「前提条件」を確認してください。

      aws eks describe-cluster --name <cluster-name> --query "cluster.identity.oidc.issuer" --output text

      出力

      https://oidc.eks.us-west-2.amazonaws.com/id/EXAMPLEXXX45D83924220DC4815XXXXX
    2. IAM ロールを作成し、Kubernetes サービスアカウントに AssumeRoleWithWebIdentity アクション。

      1. 以下の内容を trust-policy.json というファイルにコピーします。<AWS_ACCOUNT_ID> (<> を含む) をアカウント ID に、<EXAMPLEXXX45D83924220DC4815XXXXX> およびus-west-2 を前のステップで返された値に置き換えます。

        { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/<EXAMPLEXXX45D83924220DC4815XXXXX>" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.us-west-2.amazonaws.com/id/<EXAMPLEXXX45D83924220DC4815XXXXX>:sub": "system:serviceaccount:kube-system:efs-csi-controller-sa" } } } ] }
      2. ロールを作成します。AmazonEKS_EFS_CSI_DriverRole を別の名前に変更できますが、変更する場合は、後の手順でも変更してください。

        aws iam create-role \ --role-name AmazonEKS_EFS_CSI_DriverRole \ --assume-role-policy-document file://"trust-policy.json"
    3. IAM ポリシーをロールにアタッチします。<AWS_ACCOUNT_ID> (<> を含む) をアカウント ID に置き換えます。

      aws iam attach-role-policy \ --policy-arn arn:aws:iam::<AWS_ACCOUNT_ID>:policy/AmazonEKS_EFS_CSI_Driver_Policy \ --role-name AmazonEKS_EFS_CSI_DriverRole
    4. 作成した IAM ロールの ARN で注釈を付けた Kubernetes サービスアカウントを作成します。

      1. 次の内容を efs-service-account.yaml という名前のファイルに保存します。

        --- apiVersion: v1 kind: ServiceAccount metadata: name: efs-csi-controller-sa namespace: kube-system labels: app.kubernetes.io/name: aws-efs-csi-driver annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/AmazonEKS_EFS_CSI_DriverRole
      2. マニフェストを適用します。

        kubectl apply -f efs-service-account.yaml

Amazon EFS ドライバーをインストールします。

Helm またはマニフェストを使用して、Amazon EFS CSI ドライバーをインストールします。

重要
  • 次の手順では、ドライバーの 1.2.0 バージョンをインストールします。これには 1.17 以降のクラスターが必要です。バージョン 1.17 より前のクラスターにドライバーをインストールする場合は、ドライバーのバージョン 1.1 をインストールする必要があります。詳細については、GitHub で「Amazon EFS CSI ドライバー」を参照してください。

  • TLS を使用した 転送時のデータの暗号化は、デフォルトで有効になっています。転送時の暗号化を使用すると、データはネットワーク経由で Amazon EFS サービスに移行する時に暗号化されます。NFSv4 を使用して、ボリュームを無効にしてマウントするには、永続ボリュームマニフェストで volumeAttributes フィールド encryptInTransit"false" に設定します。マニフェストの例については、GitHub で「転送時の暗号化例」を参照してください。

Helm

この手順には、Helm V3 以降が必要です。Helm をインストールまたは更新する方法については、「Amazon EKS での Helm の使用」を参照してください。

  1. Helm リポジトリを追加します。

    helm repo add aws-efs-csi-driver https://kubernetes-sigs.github.io/aws-efs-csi-driver/
  2. リポジトリを更新します。

    helm repo update
  3. グラフをインストールします。クラスターがus-west-2 リージョンにない場合、602401143452.dkr.ecr.us-west-2.amazonaws.com をリージョンのアドレスに変更します。

    helm upgrade -i aws-efs-csi-driver aws-efs-csi-driver/aws-efs-csi-driver \ --namespace kube-system \ --set image.repository=602401143452.dkr.ecr.us-west-2.amazonaws.com/eks/aws-efs-csi-driver \ --set serviceAccount.controller.create=false \ --set serviceAccount.controller.name=efs-csi-controller-sa
Manifest
  1. マニフェストをダウンロードします。

    kubectl kustomize \ "github.com/kubernetes-sigs/aws-efs-csi-driver/deploy/kubernetes/overlays/stable/ecr?ref=release-1.2" > driver.yaml
  2. ファイルを編集し、Kubernetes サービスアカウントを作成する以下の行を削除します。これは、前の手順で作成されたサービスアカウントのため、必要ありません。

    apiVersion: v1 kind: ServiceAccount metadata: labels: app.kubernetes.io/name: aws-efs-csi-driver name: efs-csi-controller-sa namespace: kube-system ---
  3. 以下の行を追加します。クラスターが us-west-2 リージョンにない場合、以下のアドレスをリージョンのアドレスに置き換えます。変更が完了したら、変更したマニフェストを保存します。

    image: 602401143452.dkr.ecr.us-west-2.amazonaws.com/eks/aws-efs-csi-driver:v1.2.0
  4. マニフェストを適用します。

    kubectl apply -f driver.yaml

Amazon EFS ファイルシステムを作成します。

Amazon EFS CSI ドライバーは、Amazon EFS アクセスポイントをサポートします。これは、Amazon EFS ファイルシステムへのアプリケーション固有のエントリポイントで、複数のポッド間でのファイルシステムの共有を容易にします。アクセスポイントは、アクセスポイントを介したすべてのファイルシステムリクエストにユーザー ID を適用でき、各ポッドにルートディレクトリを適用できます。詳細については、GitHub で「Amazon EFS アクセスポイント」を参照してください。

重要

変数は手順間で設定および使用されるため、同じ端末で以下の手順を完了する必要があります。

Amazon EKS クラスターの Amazon EFS ファイルシステムを作成するには

  1. クラスターがある VPC ID を取得し、後のステップで使用するため変数に格納します。<cluster-name> (<> を含む) をクラスター名に置き換えます。

    vpc_id=$(aws eks describe-cluster \ --name <cluster-name> \ --query "cluster.resourcesVpcConfig.vpcId" \ --output text)
  2. クラスターの VPC の CIDR 範囲を取得し、後のステップで使用するため変数に格納します。

    cidr_range=$(aws ec2 describe-vpcs \ --vpc-ids $vpc_id \ --query "Vpcs[].CidrBlock" \ --output text)
  3. Amazon EFS マウントポイントのインバウンド NFS トラフィックを許可するインバウンドルールを使用して、セキュリティグループを作成します。

    1. セキュリティグループを作成します。example values を自分の値に置き換えます。

      security_group_id=$(aws ec2 create-security-group \ --group-name MyEfsSecurityGroup \ --description "My EFS security group" \ --vpc-id $vpc_id \ --output text)
    2. クラスターの VPC の CIDR のインバウンド NFS トラフィックを許可するインバウンドルールを作成します。

      aws ec2 authorize-security-group-ingress \ --group-id $security_group_id \ --protocol tcp \ --port 2049 \ --cidr $cidr_range
      重要

      ファイルシステムへのアクセスをさらに制限するには、サブネットに VPC ではなく CIDR を使用できます。

  4. Amazon EKS クラスターの Amazon EFS ファイルシステムを作成します。

    1. ファイルシステムを作成します。

      file_system_id=$(aws efs create-file-system \ --region us-west-2 \ --performance-mode generalPurpose \ --query 'FileSystemId' \ --output text)
    2. マウントターゲットを作成します。

      1. クラスターノードの IP アドレスを確認します。

        kubectl get nodes

        出力

        NAME STATUS ROLES AGE VERSION ip-192-168-56-0.us-west-2.compute.internal Ready <none> 19m v1.19.6-eks-49a6c0
      2. VPC 内のサブネットの ID、およびサブネットが存在するアベイラビリティーゾーンを決定します。

        aws ec2 describe-subnets \ --filters "Name=vpc-id,Values=$vpc_id" \ --query 'Subnets[*].{SubnetId: SubnetId,AvailabilityZone: AvailabilityZone,CidrBlock: CidrBlock}' \ --output table

        出力

        | DescribeSubnets | +------------------+--------------------+----------------------------+ | AvailabilityZone | CidrBlock | SubnetId | +------------------+--------------------+----------------------------+ | us-west-2c | 192.168.128.0/19 | subnet-EXAMPLE6e421a0e97 | | us-west-2b | 192.168.96.0/19 | subnet-EXAMPLEd0503db0ec | | us-west-2c | 192.168.32.0/19 | subnet-EXAMPLEe2ba886490 | | us-west-2b | 192.168.0.0/19 | subnet-EXAMPLE123c7c5182 | | us-west-2a | 192.168.160.0/19 | subnet-EXAMPLE0416ce588p | | us-west-2a | 192.168.64.0/19 | subnet-EXAMPLE12c68ea7fb | +------------------+--------------------+----------------------------+
      3. ノードがあるサブネットのマウントターゲットを追加します。前の 2 つの手順の出力から、クラスターには IP アドレスが 192.168.56.0 のノードが 1 つあります。その IP アドレスは ID subnet-EXAMPLEe2ba886490 を持つサブネットの CidrBlock の範囲内にあります。その結果、以下のコマンドでノードが存在するサブネットのマウントターゲットを作成します。クラスターにノードがある場合は、ノードがある各 AZ のサブネットに対してコマンドを 1 回実行し、subnet-EXAMPLEe2ba886490 を適切なサブネット ID に置き換えます。

        aws efs create-mount-target \ --file-system-id $file_system_id \ --subnet-id subnet-EXAMPLEe2ba886490 \ --security-groups $security_group_id

(オプション) サンプルアプリケーションをデプロイする

永続ボリュームを動的に作成するサンプルアプリケーションをデプロイすることも、永続ボリュームを手動で作成することもできます。

Dynamic
重要

Fargate ノードでは動的プロビジョニングを使用できません。

Prerequisite

1.17 以降のクラスターを必要とする Amazon EFS CSI ドライバーのバージョン 1.2x 以降を使用する必要があります。クラスターを更新するには、「クラスターの更新」を参照してください。。

コントローラーが作成する永続ボリュームを使用するサンプルアプリケーションをデプロイするには

この手順では、Amazon EFS Container Storage Interface (CSI) ドライバー GitHub リポジトリの動的プロビジョニングの例を使用します。これは、EFS アクセスポイントとポッドが消費する永続ボリューム要求 (PVC) の両方を介して、永続ボリュームを動的に作成します。

.

  1. EFS のストレージクラスを作成します。すべてのパラメーターと設定オプションについては、GitHub で「Amazon EFS CSI ドライバー」を参照してください。。

    1. Amazon EFS の StorageClass マニフェストをダウンロードします。

      curl -o storageclass.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/storageclass.yaml
    2. ファイルを編集し、fileSystemId の値を ファイルシステム ID に置き換えます。

    3. ストレージクラスをデプロイします。

      kubectl apply -f storageclass.yaml
  2. PersistentVolumeClaim を使用するポッドをデプロイして、自動プロビジョニングをテストします。

    1. ポッドと PersistentVolumeClaim をデプロイするマニフェストをダウンロードします。

      curl -o pod.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/pod.yaml
    2. サンプルアプリケーションとポッドで使用される PersistentVolumeClaim を使用して、ポッドをデプロイします。

      kubectl apply -f pod.yaml
  3. コントローラーを実行しているポッド名を決定します。

    kubectl get pods -n kube-system | grep efs-csi-controller

    出力

    efs-csi-controller-74ccf9f566-q5989 3/3 Running 0 40m efs-csi-controller-74ccf9f566-wswg9 3/3 Running 0 40m
  4. 数秒後、コントローラーが (可読性のために編集された) 変更を収集するのを監視できます。74ccf9f566-q5989を、前のコマンドの出力のポッドの 1 つの値に置き換えます。

    kubectl logs efs-csi-controller-74ccf9f566-q5989 \ -n kube-system \ -c csi-provisioner \ --tail 10

    出力

    ... 1 controller.go:737] successfully created PV pvc-5983ffec-96cf-40c1-9cd6-e5686ca84eca for PVC efs-claim and csi volume name fs-95bcec92::fsap-02a88145b865d3a87

    前の出力が表示されない場合は、他のコントローラーポッドのいずれかを使用して、前のコマンドを実行します。

  5. 永続ボリュームが Bound から PersistentVolumeClaim のステータスで作成されたことを確認します。

    kubectl get pv

    出力

    NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-5983ffec-96cf-40c1-9cd6-e5686ca84eca 20Gi RWX Delete Bound default/efs-claim efs-sc 7m57s
  6. 作成された PersistentVolumeClaim の詳細を表示します。

    kubectl get pvc

    出力

    NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE efs-claim Bound pvc-5983ffec-96cf-40c1-9cd6-e5686ca84eca 20Gi RWX efs-sc 9m7s
  7. サンプルアプリアプリケーションポッドのステータスを表示します。

    kubectl get pods -o wide

    出力

    NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES efs-example 1/1 Running 0 10m 192.168.78.156 ip-192-168-73-191.us-west-2.compute.internal <none> <none>

    データがボリュームに書き込まれていることを確認します。

    kubectl exec efs-app -- bash -c "cat data/out"

    出力

    ... Tue Mar 23 14:29:16 UTC 2021 Tue Mar 23 14:29:21 UTC 2021 Tue Mar 23 14:29:26 UTC 2021 Tue Mar 23 14:29:31 UTC 2021 ...
  8. (オプション) ポッドが実行されている Amazon EKS ノードを終了し、ポッドが再スケジュールされるのを待ちます。または、ポッドを削除し、再デプロイすることもできます。ステップ 7 をもう一度完了し、出力が前の出力を含むことを確認します。

Static

作成した永続ボリュームを使用するサンプルアプリケーションをデプロイするには

この手順では、「Amazon EFS Container Storage Interface (CSI) ドライバー」GitHub リポジトリの「Multiple Pods Read Write Many」の例を使用して、静的にプロビジョニングされた Amazon EFS 永続ボリュームを消費し、そこに ReadWriteMany アクセスモードで複数のポッドからアクセスします。

  1. Amazon EFS Container Storage Interface (CSI) ドライバー GitHub リポジトリをローカルシステムにクローンします。

    git clone https://github.com/kubernetes-sigs/aws-efs-csi-driver.git
  2. multiple_pods サンプルディレクトリに移動します。

    cd aws-efs-csi-driver/examples/kubernetes/multiple_pods/
  3. Amazon EFS ファイルシステム ID を取得します。これは Amazon EFS コンソール、または以下の AWS CLI コマンドを使用して確認できます。

    aws efs describe-file-systems --query "FileSystems[*].FileSystemId" --output text

    出力:

    fs-<582a03f3>
  4. specs/pv.yaml ファイルを編集して、volumeHandle の値を Amazon EFS ファイルシステム ID に置き換えます。

    apiVersion: v1 kind: PersistentVolume metadata: name: efs-pv spec: capacity: storage: 5Gi volumeMode: Filesystem accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: efs-sc csi: driver: efs.csi.aws.com volumeHandle: fs-<582a03f3>
    注記

    Amazon EFS は伸縮自在なファイルシステムであるため、ファイルシステムの容量制限は適用されません。永続ボリュームと永続ボリュームクレームの実際のストレージ容量の値は、ファイルシステムを作成するときには使用されません。ただし、ストレージ容量は Kubernetes の必須フィールドであるため、この例では 5Gi などの有効な値を指定する必要があります。この値は、Amazon EFS ファイルシステムのサイズを制限しません。

  5. specs ディレクトリから、efs-sc ストレージクラス、efs-claim 永続ボリュームクレーム、efs-pv 永続ボリュームをデプロイします。

    kubectl apply -f specs/pv.yaml kubectl apply -f specs/claim.yaml kubectl apply -f specs/storageclass.yaml
  6. デフォルトの名前空間の永続的ボリュームを一覧表示します。default/efs-claim クレームがある永続的なボリュームを探します。

    kubectl get pv -w

    出力:

    NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE efs-pv 5Gi RWX Retain Bound default/efs-claim efs-sc 2m50s

    STATUSBound になるまで、次のステップに進まないでください。

  7. app1 および app2 サンプルアプリケーションを specs ディレクトリからデプロイします。

    kubectl apply -f specs/pod1.yaml kubectl apply -f specs/pod2.yaml
  8. デフォルトの名前空間のポッドを監視し、app1 および app2 ポッドの STATUSRunning になるまで待ちます。

    kubectl get pods --watch
    注記

    ポッドが Running ステータスに到達するまで、数秒かかります。

  9. 永続的ボリュームの詳細を表示します。

    kubectl describe pv efs-pv

    出力:

    Name: efs-pv Labels: none Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"PersistentVolume","metadata":{"annotations":{},"name":"efs-pv"},"spec":{"accessModes":["ReadWriteMany"],"capaci... pv.kubernetes.io/bound-by-controller: yes Finalizers: [kubernetes.io/pv-protection] StorageClass: efs-sc Status: Bound Claim: default/efs-claim Reclaim Policy: Retain Access Modes: RWX VolumeMode: Filesystem Capacity: 5Gi Node Affinity: none Message: Source: Type: CSI (a Container Storage Interface (CSI) volume source) Driver: efs.csi.aws.com VolumeHandle: fs-582a03f3 ReadOnly: false VolumeAttributes: none Events: none

    The Amazon EFS ファイルシステム ID は VolumeHandle として一覧表示されます。

  10. app1 ポッドがボリュームにデータを正常に書き込んでいることを確認します。

    kubectl exec -ti app1 -- tail /data/out1.txt

    出力:

    ... Mon Mar 22 18:18:22 UTC 2021 Mon Mar 22 18:18:27 UTC 2021 Mon Mar 22 18:18:32 UTC 2021 Mon Mar 22 18:18:37 UTC 2021 ...
  11. app1 がボリュームに書き込んだのと同じデータを、app2 ポッドがボリューム内に表示していることを確認します。

    kubectl exec -ti app2 -- tail /data/out1.txt

    出力:

    ... Mon Mar 22 18:18:22 UTC 2021 Mon Mar 22 18:18:27 UTC 2021 Mon Mar 22 18:18:32 UTC 2021 Mon Mar 22 18:18:37 UTC 2021 ...
  12. 実験が終了したら、このサンプルアプリケーションのリソースを削除してクリーンアップします。

    kubectl delete -f specs/

    作成したファイルシステムおよびセキュリティグループを手動で削除することもできます。