EKS S3 CSI Driver
이번 블로그에서는 Amazon EKS 환경에서 S3 CSI Driver를 사용하여 Amazon S3를 Kubernetes Pod에서 스토리지처럼 활용하는 방법을 실습해보는 글을 작성해보겠습니다.
구축방안
먼저 아래의 명령어로 실습에 필요한 환경변수를 지정해 줘야 합니다.
export EKS_CLUSTER_NAME="<EKS_CLUSTER_NAME>"
export EKS_NODE_GROUP_NAME=<EKS_NODE_GROUP_NAME>
export AWS_REGION=ap-northeast-2
export CLUSTER_OIDC=$(aws eks describe-cluster --name $EKS_CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | cut -c 9-100)
export ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
다음으로 아래의 명령어를 이용하여 실습에 사용할 S3 Bucket을 생성해주겠습니다.
aws s3 mb s3://<BUCKET_NAME>
다음으로 EKS가 S3에 접근하기 위한 IAM 정책을 아래의 명령어를 이용해 생성해 줘야 합니다.
cat << EOF > s3-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "MountpointFullBucketAccess",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::<BUCKET_NAME>"
]
},
{
"Sid": "MountpointFullObjectAccess",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:AbortMultipartUpload",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::<BUCKET_NAME>/*"
]
}
]
}
EOF
아래의 명렁어를 이용하여 IAM 정책을 생성해주겠습니다.
aws iam create-policy --policy-name AmazonS3CSIDriverPolicy --policy-document file://s3-policy.json
다음으로 아래의 명령어를 이용해 생성한 IAM 정책을 EKS NodeGroup Role에 부여해 줘야 합니다.
현재는 NodeGroup Role의 권한을 부여하여 진행하지만 운영 환경에서는 권장되지 않습니다. 운영환경이라면 노드에 올라가는 모든 Pod가 해당 IAM Role의 권한을 얻을 가능성이 있기 때문에 최소 권한 원칙(Principle of Least Privilege)에 맞지 않아 IRSA 방식이나 Pod Identity 방식을 이용하여 구성하시는 것을 추천 드립니다.
NODE_GROUP_ROLE_NAME=$(aws eks describe-nodegroup \
--cluster-name $EKS_CLUSTER_NAME \
--nodegroup-name $EKS_NODE_GROUP_NAME \
--query 'nodegroup.nodeRole' \
--output text | awk -F/ '{print $NF}')
aws iam attach-role-policy \
--role-name $NODE_GROUP_ROLE_NAME \
--policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AmazonS3CSIDriverPolicy
다음으로 아래의 명령어를 이용하여 S3 CSI Driver Addons를 생성해줍니다.
eksctl create addon --name aws-mountpoint-s3-csi-driver --cluster $EKS_CLUSTER_NAME
다음으로 아래의 YAML파일을 이용하여 PV & PVC & Pod를 생성해주면 됩니다.
apiVersion: v1
kind: PersistentVolume
metadata:
name: s3-pv
spec:
capacity:
storage: 1200Gi # Ignored, required
accessModes:
- ReadWriteMany # Supported options: ReadWriteMany / ReadOnlyMany
storageClassName: "" # Required for static provisioning
claimRef: # To ensure no other PVCs can claim this PV
namespace: default # Namespace is required even though it's in "default" namespace.
name: s3-pvc # Name of your PVC
mountOptions:
- allow-delete
- region ap-northeast-2
- prefix skills/ # Change Here
csi:
driver: s3.csi.aws.com # Required
volumeHandle: s3-csi-driver-volume
volumeAttributes:
bucketName: <BUCKET_NAME> # Bucket Name
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: s3-pvc
spec:
accessModes:
- ReadWriteMany # Supported options: ReadWriteMany / ReadOnlyMany
storageClassName: "" # Required for static provisioning
resources:
requests:
storage: 1200Gi # Ignored, required
volumeName: s3-pv # Name of your PV
---
apiVersion: v1
kind: Pod
metadata:
name: s3-app
spec:
containers:
- name: app
image: alpine:latest
command: ["/bin/sh"]
args:
[
"-c",
"echo 'Hello from the container!' >> /data/$(date -u).txt; tail -f /dev/null",
]
volumeMounts:
- name: persistent-storage
mountPath: /data
volumes:
- name: persistent-storage
persistentVolumeClaim:
claimName: s3-pvc
kubectl apply -f static_provisioning.yaml
Result
아래의 명령어로 Pod가 잘 생성된지 확인을 한 후 S3 Bucket에 가보면 txt 파일이 생성되어 있는 것을 볼 수 있습니다.
kubectl get pod s3-app
아래의 CLI 명령어로도 확인이 가능합니다.
aws s3 ls <BUCKET_NAME>
이것으로 EKS S3 CSI Driver 구성 글을 마치겠습니다. 감사합니다!