CSI Driver for Amazon EFS が EKS アドオンとして利用可能になったので試してみた
2023/08 に CSI Driver for Amazon EFS を EKS アドオンとして利用可能になりました。
これまでは kubernetes-sigs/aws-efs-csi-driver 記載の手順に従って manifest ファイル等を用意して手動インストールする必要がありましたが、今後はアドオンを活用してより簡単にインストールやアップデート可能になります。
セットアップしてみた
今回は eksctl を使って試してみました。
eksctl version 0.158.0
まず、EKS クラスターを作成します。
eksctl create cluster \ --name test-cluster \ --version 1.24 \ --vpc-cidr 10.0.0.0/16 \ --with-oidc \ --node-type t3.medium \ --nodes 2 \ --nodes-min 1 \ --nodes-max 2
AmazonEFSCSIDriverPolicy
という AWS 管理の IAM ポリシーがあるので、こちらの権限を付与しつつ Service Account に紐づけた IAM ロールを作成します。
eksctl create iamserviceaccount \ --name efs-csi-controller-sa \ --namespace kube-system \ --cluster test-cluster \ --role-name AmazonEKS_EFS_CSI_DriverRole \ --role-only \ --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEFSCSIDriverPolicy \ --approve
今回は EKS 1.24 を利用しているので、対応しているアドオンのバージョンを調べてみました。
eksctl utils describe-addon-versions --kubernetes-version 1.24 --name aws-efs-csi-driver | grep AddonVersion "AddonVersions": [ "AddonVersion": "v1.6.0-eksbuild.1", "AddonVersion": "v1.5.9-eksbuild.1", "AddonVersion": "v1.5.8-eksbuild.1",
aws-efs-csi-driver をアドオンとして追加します。バージョンは一番新しい v1.6.0-eksbuild.1
とします。
eksctl create addon \ --cluster test-cluster \ --name aws-efs-csi-driver \ --version v1.6.0-eksbuild.1 \ --service-account-role-arn arn:aws:iam::12345678912:role/AmazonEKS_EFS_CSI_DriverRole \ --force
deployment(efs-csi-controller) と daemonset(efs-csi-node) がそれぞれ作成されます。
kubectl get deployment -n kube-system NAME READY UP-TO-DATE AVAILABLE AGE coredns 2/2 2 2 4h19m efs-csi-controller 2/2 2 2 2m16s
kubectl get daemonset -n kube-system NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE aws-node 2 2 2 2 2 <none> 4h19m efs-csi-node 2 2 2 2 2 kubernetes.io/os=linux 2m27s kube-proxy 2 2 2 2 2 <none> 4h19m
EFS は CloudFormation でさくっと作りました。
AWSTemplateFormatVersion: "2010-09-09" Description: This template creates an Amazon EFS file system Parameters: VolumeName: Description: The name to be used for the EFS volume Type: String MinLength: "1" Default: myEFSvolume VPC: Description: VPC Id to create EFS volume Type: String Subnet1a: Description: Subnet Id in ap-northeast-1a Type: String Subnet1c: Description: Subnet Id in ap-northeast-1c Type: String Subnet1d: Description: Subnet Id in ap-northeast-1d Type: String VPCCIDR: Description: CIDR of VPC Type: String Default: 10.0.0.0/16 Resources: MountTargetSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: Ref: VPC GroupDescription: Security group for mount target SecurityGroupIngress: - IpProtocol: tcp FromPort: 2049 ToPort: 2049 CidrIp: !Ref VPCCIDR FileSystem: Type: AWS::EFS::FileSystem Properties: PerformanceMode: generalPurpose FileSystemTags: - Key: Name Value: Ref: VolumeName MountTarget1a: Type: AWS::EFS::MountTarget Properties: FileSystemId: Ref: FileSystem SubnetId: !Ref Subnet1a SecurityGroups: - Ref: MountTargetSecurityGroup MountTarget1c: Type: AWS::EFS::MountTarget Properties: FileSystemId: Ref: FileSystem SubnetId: !Ref Subnet1c SecurityGroups: - Ref: MountTargetSecurityGroup MountTarget1d: Type: AWS::EFS::MountTarget Properties: FileSystemId: Ref: FileSystem SubnetId: !Ref Subnet1d SecurityGroups: - Ref: MountTargetSecurityGroup Outputs: FileSystemID: Description: File system ID Value: Ref: FileSystem
EFS を CLI で作成する場合は、こちらを参考にすると良いと思います。
動作確認
kubernetes-sigs/aws-efs-csi-driver でサンプルとして紹介されている manifest ファイルを利用して動作確認してみます。
クラスターを作成した状態では EBS を使うための StorageClass のみ存在します。
kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE gp2 (default) kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 4h29m
ここで下記マニフェストファイルを適用して、 StorageClass を追加します。
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: efs-sc provisioner: efs.csi.aws.com
examples/kubernetes/static_provisioning/specs/storageclass.yaml に紹介されている manifest ファイルだと、apiVersion: v1
と記載されています。
しかし、 Kubernetes 1.22 でこの API は廃止されているので、apiVersion: storage.k8s.io/v1
に修正して適用します。
kubectl apply -f storageclass.yaml storageclass.storage.k8s.io/efs-sc created
無事ストレージクラスが追加されました。
kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE efs-sc efs.csi.aws.com Delete Immediate false 3s gp2 (default) kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 4h30m
PersistentVolume (PV) を作成します。
apiVersion: v1 kind: PersistentVolume metadata: name: efs-pv spec: capacity: storage: 5Gi volumeMode: Filesystem accessModes: - ReadWriteOnce storageClassName: efs-sc persistentVolumeReclaimPolicy: Retain csi: driver: efs.csi.aws.com volumeHandle: [FileSystemId]
この際、spec.csi.volumeHandle
を EFS の ID に書き換えます。
kubectl apply -f pv.yaml persistentvolume/efs-pv created
Available 状態で PV が作成されます。
kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE efs-pv 5Gi RWO Retain Available efs-sc 24s
次に PersistentVolumeClaims(PVC) を作成します。
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: efs-claim spec: accessModes: - ReadWriteOnce storageClassName: efs-sc resources: requests: storage: 5Gi
kubectl apply -f claim.yaml persistentvolumeclaim/efs-claim created
PV の STATUS が Bound に変わります。
kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE efs-pv 5Gi RWO Retain Bound default/efs-claim efs-sc 2m22s
PVC の STATUS も同様です。
kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE efs-claim Bound efs-pv 5Gi RWO efs-sc 4s
最後に pod を作成します。
この Pod では 5 秒ごとに /data/out.txt
に data -u
の出力を書き込むコンテナが定義されています。
pod を作成する際に、作成済みの PVC を指定することで EFS に書き込めるようになります。
apiVersion: v1 kind: Pod metadata: name: efs-app spec: containers: - name: app image: centos command: ["/bin/sh"] args: ["-c", "while true; do echo $(date -u) >> /data/out.txt; sleep 5; done"] volumeMounts: - name: persistent-storage mountPath: /data volumes: - name: persistent-storage persistentVolumeClaim: claimName: efs-claim
kubectl apply -f pod.yaml
無事作成され、Volumes.persistent-storage
を確認すると、先程作成した PVC を利用できています。
kubectl describe pod efs-app Name: efs-app Namespace: default Priority: 0 Node: ip-10-0-91-134.ap-northeast-1.compute.internal/10.0.91.134 Start Time: Sun, 24 Sep 2023 20:48:51 +0900 Labels: <none> Annotations: kubernetes.io/psp: eks.privileged Status: Running IP: 10.0.93.179 IPs: IP: 10.0.93.179 Containers: app: Container ID: containerd://d4ff8ed835bf69946092d7b4a58ba48c8a523b137113f7399ff659f8167d1e60 Image: centos Image ID: docker.io/library/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177 Port: <none> Host Port: <none> Command: /bin/sh Args: -c while true; do echo $(date -u) >> /data/out.txt; sleep 5; done State: Running Started: Sun, 24 Sep 2023 20:49:12 +0900 Ready: True Restart Count: 0 Environment: <none> Mounts: /data from persistent-storage (rw) /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-gvpwk (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: persistent-storage: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: efs-claim ReadOnly: false kube-api-access-gvpwk: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 8m14s default-scheduler Successfully assigned default/efs-app to ip-10-0-91-134.ap-northeast-1.compute.internal Normal Pulling 8m3s kubelet Pulling image "centos" Normal Pulled 7m53s kubelet Successfully pulled image "centos" in 9.436549639s Normal Created 7m53s kubelet Created container app Normal Started 7m53s kubelet Started container app
下記コマンドを実行すると、/data/out.txt
に書きこめていることが確認できました。
kubectl exec -ti efs-app -- tail -f /data/out.txt Sun Sep 24 11:58:29 UTC 2023 Sun Sep 24 11:58:34 UTC 2023 Sun Sep 24 11:58:39 UTC 2023 Sun Sep 24 11:58:44 UTC 2023
まとめ
手動でドライバーの管理をするのは面倒なので、アドオンがあるなら積極的に使っていきたいです。
今は手動管理をしている場合もこれからクラスターを作る場合も、是非アドオンの利用を検討してみて下さい。