Kubernetes

Kubernetes 에서 CSI Driver 를 활용한 ebs storage 사용하기

seungkyua@gmail.com 2023. 1. 31. 19:45
반응형

이전에는 aws 에 Kubernetes Cluster 를 설치한 후 Load Balancer 를 연결한는 방법을 설명하였다. Kubernetes Cluster 를 사용하려면 Load Balancer 외에도 필요한 기능이 있는데 그것이 바로 Storage 이다.

Pod 에서 영구적으로 데이터를 저장하기 위해서는 ebs 와 같은 Block Storage 를 생성해서 연결해야 하는데 Kubernetes 에서는 CSI 로 이를 지원하고 있다.

aws 에서 ebs 를 사용하려면 아래의 순서대로 적용한다.

  1. IAM Policy 생성
  2. CSI Driver (Provisioner) 설치
  3. Storage Class 생성
  4. PVC, POD 로 테스트

1. IAM Policy 생성

CSI 를 위한 IAM Policy 는 생성하기 전에 이미 만들어서 제공되고 있는 Managed Policy 를 사용해도 된다. arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy

하지만 새로 만든다고 하면 아래와 같이 만들수 있다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CreateSnapshot",
        "ec2:AttachVolume",
        "ec2:DetachVolume",
        "ec2:ModifyVolume",
        "ec2:DescribeAvailabilityZones",
        "ec2:DescribeInstances",
        "ec2:DescribeSnapshots",
        "ec2:DescribeTags",
        "ec2:DescribeVolumes",
        "ec2:DescribeVolumesModifications"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CreateTags"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:volume/*",
        "arn:aws:ec2:*:*:snapshot/*"
      ],
      "Condition": {
        "StringEquals": {
          "ec2:CreateAction": [
            "CreateVolume",
            "CreateSnapshot"
          ]
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DeleteTags"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:volume/*",
        "arn:aws:ec2:*:*:snapshot/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CreateVolume"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "aws:RequestTag/ebs.csi.aws.com/cluster": "true"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CreateVolume"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "aws:RequestTag/CSIVolumeName": "*"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DeleteVolume"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "ec2:ResourceTag/ebs.csi.aws.com/cluster": "true"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DeleteVolume"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "ec2:ResourceTag/CSIVolumeName": "*"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DeleteVolume"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "ec2:ResourceTag/kubernetes.io/created-for/pvc/name": "*"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DeleteSnapshot"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "ec2:ResourceTag/CSIVolumeSnapshotName": "*"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DeleteSnapshot"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "ec2:ResourceTag/ebs.csi.aws.com/cluster": "true"
        }
      }
    }
  ]
}

Role 에 Policy 연결

이전 글에서 설명한 control-plane.cluster-api-provider-aws.sigs.k8s.ionodes.cluster-api-provider-aws.sigs.k8s.io role 에 위의 Policy 를 연결한다.

Role : control-plane.cluster-api-provider-aws.sigs.k8s.io

Role : nodes.cluster-api-provider-aws.sigs.k8s.io

2. CSI Driver (Provisioner) 설치

EBS 용 CSI Driver 를 helm chart repo 를 등록한다.

$ helm repo add aws-ebs-csi-driver https://kubernetes-sigs.github.io/aws-ebs-csi-driver
$ helm repo update

$ helm search repo aws-ebs-csi-driver -l
NAME                                    CHART VERSION   APP VERSION     DESCRIPTION
aws-ebs-csi-driver/aws-ebs-csi-driver   2.16.0          1.15.0          A Helm chart for AWS EBS CSI Driver
aws-ebs-csi-driver/aws-ebs-csi-driver   2.15.1          1.14.1          A Helm chart for AWS EBS CSI Driver
...

지금 최신 버전 차트는 2.16.0 이다. 해당 차트는 Kubernetes 1.17+ 이상만 호환되는데 현재의 웬만한 Kubernetes 버전은 지원된다고 보면 된다.

Helm chart 로 설치한다.

$ helm upgrade -i aws-ebs-csi-driver -n kube-system aws-ebs-csi-driver/aws-ebs-csi-driver --version 2.16.0

설치가 제대로 되었는지는 아래의 명령어로 확인할 수 있다.

3. Storage Class 설치

ebs volume 이 생성될 때 CSI Driver 에게 필요한 설정 값을 전달해야 하는데 이것이 바로 Storage Class 라고 보면 된다.

아래와 같이 생성한다.

$ vi standard-ebs-sc.yaml
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  annotations: 
    storageclass.kubernetes.io/is-default-class: "true"
  name: standard
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete

$ kubectl apply -f standard-ebs-sc.yaml

storage class 에 storage type (gp2, gp3, io1 등), iops, 데이터 암호화 여부, 토폴로지 등을 넣을 수 있는데 이를 적용하면 현재 csi driver 에서 에러가 나므로 추가 확인이 필요하다. (볼륨 생성이 안된다던지, 볼륨 attach 가 안된다든지 하는 문제가 발생했는데 자세히 소스까지 찾아보지는 않았음 ㅠㅠ)

storage class 가 잘 생성되었는지 확인한다.

$ kubectl get sc
NAME                 PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
local-path           rancher.io/local-path   Delete          WaitForFirstConsumer   false                  12d
standard (default)   ebs.csi.aws.com         Delete          WaitForFirstConsumer   false                  138m

4. PVC, POD 로 테스트

pvc 를 생성하고 pod 에서 이를 mount 하여 활용해본다.

pvc 생성

$ vi pvc-example.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-claim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 4Gi

$ kubectl apply -f pvc-example.yaml

sc 설정에서 volumeBindingMode: WaitForFirstConsumer 이기 때문에 pod 가 생성되기 전까지는 pv 는 만들어지지 않는다.

POD 생성

$ vi pod-example.yaml
---
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-claim

$ kubectl apply -f pod-example.yaml

out.txt 에 date 값이 설정된 것을 확인할 수 있다.

$ kubectl exec -it app -- cat /data/out.txt
반응형