Kubernetes/EKS Study

[3주차] EKS Storage

백곰곰 2023. 5. 9. 23:49
728x90
반응형

이번 주는 EKS에서 Storage 관련 내용과 노드 그룹을 추가하는 방법을 알아봤습니다.

EKS Storage

EKS에서는 Amazon CSI driver를 통해 스토리지 볼륨을 생성하고 관리합니다. 먼저 CSI에 대해 알아보겠습니다.

CSI(Container Storage Interface)

CSI는 storage 벤더가 여러 컨테이너 오케스트레이션 시스템에서 동작하는 플러그인을 개발하기 위한 표준(인터페이스)을 정의합니다.

다음과 같은 API를 정의합니다. (참고)

  • 볼륨의 동적 프로비저닝 및 해제
  • 노드에 볼륨 부착 및 해제 / mount 및 umount
  • 볼륨 스냅샷 생성 및 삭제
  • 스냅샷으로부터 신규 볼륨 생성 등

CSI driver

CSI 표준을 따라 구현하여 실제 스토리지 시스템과 kubernetes이 함께 작동하도록 설정합니다.

Amazon CSI driver

AWS의 스토리지 종류(EBS, EFS, FSX 등)에 따라 CSI driver를 각각 제공합니다. 

CSI driver의 구성 요소는 아래와 같습니다.

csi-controller는 api server에 볼륨 관련 요청이 있는지 확인하고 AWS API를 호출하는 역할을 합니다.

csi-node는 각 노드에서 실행되며, 실제 볼륨을 Pod에 마운트 하는 역할을 합니다.

 

이제 AWS에서 주로 사용하는 CSI driver에 대해 알아보겠습니다.

Amazon EBS CSI driver

EBS를 pv의 볼륨으로 사용하기 위해 설치하는 driver입니다.

EBS를 사용하기 때문에 동시에 하나의 노드에만 마운트가 가능하고, AZ도 고려를 해야 합니다.

EKS add-on을 통해 설치가 가능하며, driver에서 사용하는 service account에 AmazonEBSCSIDriverPolicy 정책이 필요합니다.

해당 정책은 AWS managed 정책이며 볼륨 생성/삭제, snapshot 생성/삭제, 볼륨 attach/detach 등의 권한이 포함되어 있습니다.

 

Amazon EFS CSI driver

EFS를 pv의 볼륨으로 사용하기 위해 설치하는 driver입니다.

여러 pod에서 하나의 볼륨 공유가 필요할 때 사용할 수 있습니다. 하지만 테스트를 통해 성능 확인 후 사용이 필요합니다.

helm이나 별도의 manifest를 사용해서 설치할 수 있습니다.

별도의  IAM 정책을 만들고 driver에서 사용하는 service account에  연결을 해야 합니다.

해당 정책은 주로 AmazonEKS_EFS_CSI_Driver_Policy 라는 이름으로 생성하지만 사용자 관리 정책이기 때문에 이름 변경이 가능합니다. 또한, access point 생성/삭제 등의 권한을 갖습니다.

권한을 통해 유추할 수 있지만, EFS CSI driver는 access point는 생성할 수 있지만 EFS 생성에 대한 권한은 갖고 있지 않습니다. 따라서 EFS를 미리 생성할 필요가 있습니다.

 

EKS의 Storage Class

Storage Class는 클러스터 내에서 동적으로 볼륨을 생성할 때 사용합니다.

이는 pvc 생성 시 pv를 자동으로 생성할 때 사용하는 개념입니다.

storage class에는 이름과 provisioner 정보가 포함됩니다.

EKS에는 기본적으로 gp2 storage class가 생성됩니다. 추가로 필요한 storege class(gp3 등)는 직접 생성이 필요합니다.

 

기타

주로 사용하는 pv, pvc 같은 스토리지 오브젝트 외에 볼륨의 snapshot을 만들 때 사용하는 오브젝트도 있습니다.

두 오브젝트 모두 api 그룹(snapshot.storage.k8s.io/v1)을 통해 제공됩니다. 참고로 pv, pvc는 core api 그룹에 포함되어 있습니다.

 

  • VolumeSnapshot
    • 사용 중인 pvc의 볼륨에 대해서 snapshot을 생성 요청
    • VolumeSnapshot 생성 시 실제 snapshot인 VolumeSnapshotContent가 생성되고 두 오브젝트는 pvc와 pv의 관계와 유사함
    • VolumeSnapshot은 이미 만들어진 VolumeSnapshotContent를 사용할 수도 있고 동적으로 생성 후에 사용할 수도 있음
    • VolumeSnapshot 삭제 시 VolumeSnapshotContent 삭제 여부도 정책에 설정할 수 있음
  • VolumeSnapshotClass
    • Storage Class와 유사하게 snapshot을 생성할 때 속성을 지정하는 역할

실습

이번 주부터는 AWS loadbalancer controller가 포함된 yaml 파일을 활용하여 클러스터를 생성합니다.

노드에서 사용할 수 있는 볼륨 수 확인

노드의 describe 결과에서 Allocatable 아래 설정된 값을 보면 해당 노드에 생성할 수 있는 pod, 부착할 수 있는 볼륨의 수 등을 확인할 수 있습니다.

$ k describe no | grep Allocatable -A7
Allocatable:
  attachable-volumes-aws-ebs:  25
  cpu:                         1930m
  ephemeral-storage:           27905944324
  hugepages-1Gi:               0
  hugepages-2Mi:               0
  memory:                      3388364Ki
  pods:                        17
  ...

EBS CSI driver 설치 및 예제

EBS CSI driver를 설치해보겠습니다.

# IRSA 설정
eksctl create iamserviceaccount \
  --name ebs-csi-controller-sa \
  --namespace kube-system \
  --cluster ${CLUSTER_NAME} \
  --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
  --approve \
  --role-only \
  --role-name AmazonEKS_EBS_CSI_DriverRole
# Amazon EBS CSI driver addon 추가
eksctl create addon --name aws-ebs-csi-driver --cluster ${CLUSTER_NAME} --service-account-role-arn arn:aws:iam::${ACCOUNT_ID}:role/AmazonEKS_EBS_CSI_DriverRole --force

# IRSA 확인
k get sa -n kube-system ebs-csi-controller-sa -o yaml | head -5
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::xxxxxxxxxxxx:role/AmazonEKS_EBS_CSI_DriverRole

# EBS CSI pod 확인
 k get po -n kube-system | grep -i csi
ebs-csi-controller-67658f895c-8bpkf   6/6     Running   0          3m31s
ebs-csi-controller-67658f895c-jlnjn   6/6     Running   0          3m31s
ebs-csi-node-b7bvd                    3/3     Running   0          3m31s
ebs-csi-node-fkqgc                    3/3     Running   0          3m31s
ebs-csi-node-tqft2                    3/3     Running   0          3m31s
# EKS Addon 현황 확인
$ eksctl get addon --cluster ${CLUSTER_NAME}
2023-05-08 20:27:14 [ℹ]  Kubernetes version "1.24" in use by cluster "myeks"
2023-05-08 20:27:14 [ℹ]  getting all addons
2023-05-08 20:27:16 [ℹ]  to see issues for an addon run `eksctl get addon --name <addon-name> --cluster <cluster-name>`
NAME			VERSION			STATUS	ISSUES	IAMROLE										UPDATE AVAILABLE	CONFIGURATION VALUES
aws-ebs-csi-driver	v1.18.0-eksbuild.1	ACTIVE	0	arn:aws:iam::xxxxxxxxxxxx:role/AmazonEKS_EBS_CSI_DriverRole
coredns			v1.9.3-eksbuild.3	ACTIVE	0
kube-proxy		v1.24.10-eksbuild.2	ACTIVE	0
vpc-cni			v1.12.6-eksbuild.1	ACTIVE	0	arn:aws:iam::xxxxxxxxxxxx:role/eksctl-myeks-addon-vpc-cni-Role1-1H4JLKF6W7LU1

클러스터 내 Storage Class를 확인하면 gp2를 볼 수 있습니다.

k get sc
NAME            PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
gp2 (default)   kubernetes.io/aws-ebs   Delete          WaitForFirstConsumer   false                  36m

최신 볼륨 타입을 사용하기 위해 gp3 Storage Class를 추가하겠습니다.

$ cat <<EOT > gp3-sc.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: gp3
allowVolumeExpansion: true
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
  type: gp3
  allowAutoIOPSPerGBIncrease: 'true'
  encrypted: 'true'
  #fsType: ext4 # 기본값이 ext4 이며 xfs 등 변경 가능 >> 단 스냅샷 경우 ext4를 기본으로하여 동작하여 xfs 사용 시 문제가 될 수 있음 - 테스트해보자
EOT

allowVolumeExpansion 옵션을 true로 설정했기 때문에 자동으로 볼륨 증설이 가능합니다.

$ kubectl apply -f gp3-sc.yaml
$ k get sc
NAME            PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
gp2 (default)   kubernetes.io/aws-ebs   Delete          WaitForFirstConsumer   false                  39m
gp3             ebs.csi.aws.com         Delete          WaitForFirstConsumer   true                   18s

이제 pvc를 생성해서 pod에 연결해보겠습니다.

먼저 pvc를 생성합니다.

$ cat <<EOT > awsebs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi
  storageClassName: gp3
EOT
$ kubectl apply -f awsebs-pvc.yaml
$ k get pvc,pv
NAME                              STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/ebs-claim   Pending                                      gp3            32s

pvc를 생성한 후에 pvc, pv를 조회하면 pv는 아직 생성되지 않은 것을 볼 수 있습니다.

이제 pod에 pvc를 연결해보겠습니다.

$ cat <<EOT > awsebs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  terminationGracePeriodSeconds: 3
  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: ebs-claim
EOT
$ kubectl apply -f awsebs-pod.yaml

다시 객체들을 조회 해보겠습니다.

pv가 동적으로 생성된 것을 확인할 수 있습니다.

$ kubectl get pvc,pv,pod
NAME                              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/ebs-claim   Bound    pvc-2cc56fdc-83b7-48cb-8020-90cce998f4af   4Gi        RWO            gp3            3m4s

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE
persistentvolume/pvc-2cc56fdc-83b7-48cb-8020-90cce998f4af   4Gi        RWO            Delete           Bound    default/ebs-claim   gp3                     46s

NAME      READY   STATUS    RESTARTS   AGE
pod/app   1/1     Running   0          50s
$ kubectl get VolumeAttachment
NAME                                                                   ATTACHER          PV                                         NODE                                              ATTACHED   AGE
csi-f7c3e8530a92fd0c9ddcce17d7eca88254e983a3f1924bf93e2c7561555df271   ebs.csi.aws.com   pvc-2cc56fdc-83b7-48cb-8020-90cce998f4af   ip-192-168-3-73.ap-northeast-2.compute.internal   true       62s

pv가 동적으로 생성된 것을 확인할 수 있습니다. 생성된 pv를 자세히 보면 Node Affinity가 자동으로 설정된 것을 볼 수 있습니다.

EBS는 같은 AZ에 실행 중인 EC2와 연결할 수 있기 때문에 해당 설정이 필요합니다.

$ kubectl get pv -o yaml
...
    nodeAffinity:
      required:
        nodeSelectorTerms:
        - matchExpressions:
          - key: topology.ebs.csi.aws.com/zone
            operator: In
            values:
            - ap-northeast-2c
    persistentVolumeReclaimPolicy: Delete
    storageClassName: gp3
    volumeMode: Filesystem
  status:
    phase: Bound
...

실제 pod는 ap-northeast-2c AZ에 있는 노드에서 실행중인 것을 알 수 있습니다.

$ k get po -o wide
NAME   READY   STATUS    RESTARTS   AGE     IP              NODE                                              NOMINATED NODE   READINESS GATES
app    1/1     Running   0          6m44s   192.168.3.214   ip-192-168-3-73.ap-northeast-2.compute.internal   <none>           <none>
$ kubectl get node --label-columns=topology.ebs.csi.aws.com/zone,topology.kubernetes.io/zone
NAME                                               STATUS   ROLES    AGE   VERSION                ZONE              ZONE
ip-192-168-1-148.ap-northeast-2.compute.internal   Ready    <none>   42m   v1.24.11-eks-a59e1f0   ap-northeast-2a   ap-northeast-2a
ip-192-168-2-67.ap-northeast-2.compute.internal    Ready    <none>   42m   v1.24.11-eks-a59e1f0   ap-northeast-2b   ap-northeast-2b
ip-192-168-3-73.ap-northeast-2.compute.internal    Ready    <none>   42m   v1.24.11-eks-a59e1f0   ap-northeast-2c   ap-northeast-2c

 

볼륨 snapshot 생성 및 복구

이번에는 pv로 사용 중인 EBS 볼륨의 snapshot을 생성하기 위해 관련 구성 요소를 설치해보겠습니다.

# Install Snapshot CRDs
$ curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
$ curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
$ curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
$ kubectl apply -f snapshot.storage.k8s.io_volumesnapshots.yaml,snapshot.storage.k8s.io_volumesnapshotclasses.yaml,snapshot.storage.k8s.io_volumesnapshotcontents.yaml
$ kubectl get crd | grep snapshot
volumesnapshotclasses.snapshot.storage.k8s.io    2023-05-08T11:48:24Z
volumesnapshotcontents.snapshot.storage.k8s.io   2023-05-08T11:48:24Z
volumesnapshots.snapshot.storage.k8s.io          2023-05-08T11:48:23Zkubectl api-resources  | grep snapshot
$ kubectl api-resources  | grep snapshot

volumesnapshotclasses             vsclass,vsclasses   snapshot.storage.k8s.io/v1             false        VolumeSnapshotClass
volumesnapshotcontents            vsc,vscs            snapshot.storage.k8s.io/v1             false        VolumeSnapshotContent
volumesnapshots                   vs                  snapshot.storage.k8s.io/v1             true         VolumeSnapshot

# Install Common Snapshot Controller
$ curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml
$ curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml
$ kubectl apply -f rbac-snapshot-controller.yaml,setup-snapshot-controller.yaml
$ kubectl get deploy -n kube-system snapshot-controller
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
snapshot-controller   2/2     2            2           82s
$ kubectl get pod -n kube-system -l app=snapshot-controller
NAME                                   READY   STATUS    RESTARTS   AGE
snapshot-controller-76494bf6c9-4bkwj   1/1     Running   0          98s
snapshot-controller-76494bf6c9-lth8k   1/1     Running   0          98s

# Install Snapshotclass
$ curl -s -O https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/master/examples/kubernetes/snapshot/manifests/classes/snapshotclass.yaml
$ kubectl apply -f snapshotclass.yaml
$ kubectl get vsclass
NAME          DRIVER            DELETIONPOLICY   AGE
csi-aws-vsc   ebs.csi.aws.com   Delete           30s

설치 과정을 보면 앞서 살펴본 VolumeSnapshot, VolumeSnapshotClass 등을 생성하는 것을 알 수 있습니다.

이제 snapshot을 생성하고 테스트 해보겠습니다.

앞서 만들어둔 pod에서 /data/out.txt 파일에 시간을 기록하고 있습니다.  해당 볼륨을 snapshot으로 복구했을 때 동일한 데이터가 있는지 확인해보겠습니다.

kubectl exec app -- tail -f /data/out.txt
Mon May 8 11:52:04 UTC 2023
Mon May 8 11:52:09 UTC 2023
Mon May 8 11:52:14 UTC 2023
Mon May 8 11:52:19 UTC 2023
Mon May 8 11:52:24 UTC 2023
Mon May 8 11:52:29 UTC 2023
Mon May 8 11:52:34 UTC 2023
Mon May 8 11:52:39 UTC 2023
Mon May 8 11:52:44 UTC 2023
Mon May 8 11:52:49 UTC 2023
Mon May 8 11:52:54 UTC 2023

먼저 ebs-volume-snapshot.yaml 라는 파일을 작성합니다.

앞에서 생성한 pvc(ebs-claim)와 volumeSnapshotClass(csi-aws-vsc)를 입력하고 VolumeSnapshot을 생성합니다.

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: ebs-volume-snapshot
spec:
  volumeSnapshotClassName: csi-aws-vsc
  source:
    persistentVolumeClaimName: ebs-claim

volumesnapshot과 volumesnapshotcontents가 생성된 것을 볼 수 있습니다.

$ kubectl get volumesnapshot
NAME                  READYTOUSE   SOURCEPVC   SOURCESNAPSHOTCONTENT   RESTORESIZE   SNAPSHOTCLASS   SNAPSHOTCONTENT                                    CREATIONTIME   AGE
ebs-volume-snapshot   true         ebs-claim                           4Gi           csi-aws-vsc     snapcontent-2eaab85c-ce5f-4270-b32b-23a7ce61eae7   2m44s          2m44s
$ kubectl get volumesnapshotcontents
NAME                                               READYTOUSE   RESTORESIZE   DELETIONPOLICY   DRIVER            VOLUMESNAPSHOTCLASS   VOLUMESNAPSHOT        VOLUMESNAPSHOTNAMESPACE   AGE
snapcontent-2eaab85c-ce5f-4270-b32b-23a7ce61eae7   true         4294967296    Delete           ebs.csi.aws.com   csi-aws-vsc           ebs-volume-snapshot   default                   2m48s

실제 AWS 볼륨 snapshot이 생성됐는지 확인해보겠습니다.

aws ec2 describe-snapshots --owner-ids self --query 'Snapshots[]' --output table

-----------------------------------------------------------------------------------------------------
|                                         DescribeSnapshots                                         |
+-------------+-------------------------------------------------------------------------------------+
|  Description|  Created by AWS EBS CSI driver for volume vol-0545776c5686066d6                     |
|  Encrypted  |  True                                                                               |
|  KmsKeyId   |  arn:aws:kms:ap-northeast-2:xxxxxxxxxxx:key/b270e6dd-9226-46ac-8e69-68729a56795a   |
|  OwnerId    |  738740507565                                                                       |
|  Progress   |  100%                                                                               |
|  SnapshotId |  snap-03b511aeff38a0e57                                                             |
|  StartTime  |  2023-05-08T11:55:58.794000+00:00                                                   |
|  State      |  completed                                                                          |
|  StorageTier|  standard                                                                           |
|  VolumeId   |  vol-0545776c5686066d6                                                              |
|  VolumeSize |  4                                                                                  |
+-------------+-------------------------------------------------------------------------------------+
||                                              Tags                                               ||
|+-------------------------------+-----------------------------------------------------------------+|
||              Key              |                              Value                              ||
|+-------------------------------+-----------------------------------------------------------------+|
||  ebs.csi.aws.com/cluster      |  true                                                           ||
||  CSIVolumeSnapshotName        |  snapshot-2eaab85c-ce5f-4270-b32b-23a7ce61eae7                  ||
||  kubernetes.io/cluster/myeks  |  owned                                                          ||
||  Name                         |  myeks-dynamic-snapshot-2eaab85c-ce5f-4270-b32b-23a7ce61eae7    ||
|+-------------------------------+-----------------------------------------------------------------+|

이제 pod와 pvc를 삭제해보겠습니다.

$ kubectl delete pod app && kubectl delete pvc ebs-claim
$ kubectl get pvc,pv
No resources found

그 다음에 snapshot을 통해서 pvc를 복구해보겠습니다.

dataSource에 전에 생성한 snapshot 이름을 입력합니다.

$ cat <<EOT > ebs-snapshot-restored-claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-snapshot-restored-claim
spec:
  storageClassName: gp3
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi
  dataSource:
    name: ebs-volume-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
EOT
$ kubectl apply -f ebs-snapshot-restored-claim.yaml
$ kubectl get pvc,pv
NAME                                                STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/ebs-snapshot-restored-claim   Pending                                      gp3            2m3s

아직 pv는 생성되지 않았고, 이제 복구된 pvc가 연결된 pod를 만들어 보겠습니다.

apiVersion: v1
kind: Pod
metadata:
  name: 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: ebs-snapshot-restored-claim

pod 생성 후에 pv가 생성된 것을 볼 수 있습니다.

$ kubectl get pvc,pv,pod
NAME                                                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/ebs-snapshot-restored-claim   Bound    pvc-ce3c5e51-0267-4ef6-8cdb-62e229ac95d6   4Gi        RWO            gp3            3m56s

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                 STORAGECLASS   REASON   AGE
persistentvolume/pvc-ce3c5e51-0267-4ef6-8cdb-62e229ac95d6   4Gi        RWO            Delete           Bound    default/ebs-snapshot-restored-claim   gp3                     17s

NAME      READY   STATUS    RESTARTS   AGE
pod/app   1/1     Running   0          21s

이제 pod의 /data/out.txt 파일에 이전 데이터가 남아있는지 확인해보겠습니다.

$ kubectl exec app -- cat /data/out.txt
Mon May 8 11:51:49 UTC 2023
Mon May 8 11:51:54 UTC 2023
Mon May 8 11:51:59 UTC 2023
Mon May 8 11:52:04 UTC 2023
Mon May 8 11:52:09 UTC 2023
Mon May 8 11:52:14 UTC 2023
Mon May 8 11:52:19 UTC 2023
Mon May 8 11:52:24 UTC 2023
Mon May 8 11:52:29 UTC 2023
Mon May 8 11:52:34 UTC 2023
Mon May 8 11:52:39 UTC 2023
Mon May 8 11:52:44 UTC 2023
Mon May 8 11:52:49 UTC 2023
Mon May 8 11:52:54 UTC 2023
Mon May 8 11:52:59 UTC 2023
...

pod 삭제 이전 시간의 데이터가 남아있는 것을 확인할 수 있습니다.

EFS CSI driver 설치 및 예제

이번에는 EFS CSI driver를 설치해보겠습니다.

먼저 IAM Policy를 생성합니다.

$ curl -s -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/docs/iam-policy-example.json
$ aws iam create-policy --policy-name AmazonEKS_EFS_CSI_Driver_Policy --policy-document file://iam-policy-example.json

그 다음 IRSA를 설정하고 EFS CSI driver를 설치합니다.

# ISRA 설정 : 고객관리형 정책 AmazonEKS_EFS_CSI_Driver_Policy 사용
$ eksctl create iamserviceaccount \
  --name efs-csi-controller-sa \
  --namespace kube-system \
  --cluster ${CLUSTER_NAME} \
  --attach-policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/AmazonEKS_EFS_CSI_Driver_Policy \
  --approve
  
# EFS Controller 설치
$ helm repo add aws-efs-csi-driver https://kubernetes-sigs.github.io/aws-efs-csi-driver/
$ helm repo update
$ helm upgrade -i aws-efs-csi-driver aws-efs-csi-driver/aws-efs-csi-driver \
    --namespace kube-system \
    --set image.repository=602401143452.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/eks/aws-efs-csi-driver \
    --set controller.serviceAccount.create=false \
    --set controller.serviceAccount.name=efs-csi-controller-sa
    
# 확인
$ kubectl get sa -n kube-system efs-csi-controller-sa -o yaml | head -5
$ eksctl get iamserviceaccount --cluster myeks
$ helm list -n kube-system
NAME              	NAMESPACE  	REVISION	UPDATED                                	STATUS  	CHART                   	APP VERSION
aws-efs-csi-driver	kube-system	1       	2023-05-08 21:27:12.256768144 +0900 KST	deployed	aws-efs-csi-driver-2.4.1	1.5.4
$ kubectl get pod -n kube-system -l "app.kubernetes.io/name=aws-efs-csi-driver,app.kubernetes.io/instance=aws-efs-csi-driver"
NAME                                  READY   STATUS    RESTARTS   AGE
efs-csi-controller-64d67ffcdd-2xx2x   3/3     Running   0          24m
efs-csi-controller-64d67ffcdd-h8czl   3/3     Running   0          24m
efs-csi-node-4pr42                    3/3     Running   0          24m
efs-csi-node-7x8dt                    3/3     Running   0          24m
efs-csi-node-gj626                    3/3     Running   0          24m

현재 상태에서는 EFS 자체 id를 사용하거나 access point를 생성한 뒤 해당 id를 통해서 pv를 먼저 만들어주어야 pvc가 정상적으로 볼륨과 binding될 수 있습니다.

동적으로 EFS pv를 만들기 위해서는 Storage Class를 추가로 생성해야합니다.

$ curl -s -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/storageclass.yaml
$ cat storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: efs-sc
provisioner: efs.csi.aws.com
parameters:
  provisioningMode: efs-ap
  fileSystemId: fs-92107410
  directoryPerms: "700"
  gidRangeStart: "1000" # optional
  gidRangeEnd: "2000" # optional
  basePath: "/dynamic_provisioning" # optional
$ sed -i "s/fs-92107410/$EfsFsId/g" storageclass.yaml
$ kubectl apply -f storageclass.yaml
$ kubectl get sc efs-sc
NAME     PROVISIONER       RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
efs-sc   efs.csi.aws.com   Delete          Immediate           false                  3s

이 때 먼저 생성해 둔 EFS id를 입력해야 합니다.

이제 EFS를 사용하는 pod를 만들어 보겠습니다.

$ curl -s -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/pod.yaml
$ cat pod.yaml | yh
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: efs-claim
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: efs-sc
  resources:
    requests:
      storage: 5Gi
---
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; sleep 5; done"]
      volumeMounts:
        - name: persistent-storage
          mountPath: /data
  volumes:
    - name: persistent-storage
      persistentVolumeClaim:
        claimName: efs-claim
$ kubectl apply -f pod.yaml
$ kubectl get pvc,pv,pod
NAME                                                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/efs-claim                     Bound    pvc-0ee5efeb-75c9-475c-9d0e-09e3fb32b364   5Gi        RWX            efs-sc         19s

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                 STORAGECLASS   REASON   AGE
persistentvolume/pvc-0ee5efeb-75c9-475c-9d0e-09e3fb32b364   5Gi        RWX            Delete           Bound    default/efs-claim                     efs-sc                  19s

NAME                              READY   STATUS             RESTARTS      AGE
pod/app                           1/1     Running            0             59m
pod/efs-app                       1/1     Running            0             45s

이후 EFS의 access point를 확인하면 pvc이름 기반의 path로 새로운 access point가 생성된 것을 확인할 수 있습니다.

또한, 자동으로 생성된 pv를 확인하면 EBS를 사용하는 pv와 다르게 nodeAffinity 설정이 없는 것을 확인할 수 있습니다.

이상으로 3주차 내용을 마무리하겠습니다.


추가로 생각해 볼 만한 것

주기적으로 snapshot을 생성하는 방법

  1) AWS Backup 이용하여 ebs 볼륨 백업
    - 백업 스케쥴링 및 백업본 관리가 쉬움
    - tag 기반 백업을 위해서 pv에 custom tag 추가 필요 (pv에 tag 추가하기)

    - 클러스터 객체인 VolumeSnapshot은 사용하지 못하고, 백업된 EBS로 PV를 만든 후에 PVC와 연결이 필요함

 
  2) snapshot scheduler 설치 후 사용

     - snapshot은 kubectl 명령어로 생성이 불가하고 yaml 파일을 생성한 뒤 apply를 해야 하는데, 백업본 보관일 지정이나 백업을 하기 위한 pod 세팅이 번거로워 보였음

     - snapshot scheduler라는 비슷한 이름으로 다양한 프로젝트가 있는 것으로 보임 (실습


참고 문서

728x90

'Kubernetes > EKS Study' 카테고리의 다른 글

[5주차] EKS Autoscaling  (0) 2023.05.24
[4주차] EKS Observability  (0) 2023.05.21
EKS에서 볼륨 snapscheduler 설치하기  (0) 2023.05.09
EKS에서 pvc로 생성한 ebs에 태그 추가하기  (0) 2023.05.09
[2주차] EKS Networking  (0) 2023.05.01