EKS 8탄 - 3주차
본 내용은 CloudNet 주말 스터디 내용을 참고로 작성되었습니다.
https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863
계속 테스트하며 내용과 설명이 업데이트 됩니다.
Pod에서 EFS 사용하기
1
참고 자료
https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/efs-csi.html
https://github.com/kubernetes-sigs/aws-efs-csi-driver
https://artifacthub.io/packages/helm/aws-efs-csi-driver/aws-efs-csi-driver
2
앞에서 Cloudformation으로 efs 파일 시스템은 만들었다. eks-oneclick2.yaml file
3
내용 ?
보안 그룹 하나 추가함.
EFS
EFSSG:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref EksVPC
GroupDescription: EFS Security Group
Tags:
- Key : Name
Value : !Sub ${ClusterBaseName}-EFS
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '2049'
ToPort: '2049'
CidrIp: !Ref VpcBlock
ElasticFileSystem:
Type: AWS::EFS::FileSystem
Properties:
FileSystemTags:
- Key: Name
Value: !Sub ${ClusterBaseName}-EFS
ElasticFileSystemMountTarget0:
Type: AWS::EFS::MountTarget
Properties:
FileSystemId: !Ref ElasticFileSystem
SecurityGroups:
- !Ref EFSSG
SubnetId: !Ref PublicSubnet1
ElasticFileSystemMountTarget1:
Type: AWS::EFS::MountTarget
Properties:
FileSystemId: !Ref ElasticFileSystem
SecurityGroups:
- !Ref EFSSG
SubnetId: !Ref PublicSubnet2
ElasticFileSystemMountTarget2:
Type: AWS::EFS::MountTarget
Properties:
FileSystemId: !Ref ElasticFileSystem
SecurityGroups:
- !Ref EFSSG
SubnetId: !Ref PublicSubnet3
https://dev.to/awscommunity-asean/aws-eks-with-efs-csi-driver-and-irsa-using-cdk-dgc
# EFS 정보 확인
aws efs describe-file-systems --query "FileSystems[*].FileSystemId" --output text
------
fs-00fc18f0ad801703e
4
정책을 만들어야 한다. 고객 관리형 정책을 별도로 만들어야 한다. (고객이 직접 만든 정책이다.)
IRSA 설정을 해야 한다.
5
# IAM 정책 생성
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
6
# IRSA 설정
: 고객관리형 정책 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
(2분 소요)
7
# IRSA 확인
kubectl get sa -n kube-system efs-csi-controller-sa -o yaml | head -5
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::476286675138:role/eksctl-myeks-addon-iamserviceaccount-kube-sy-Role1-Q5FRU0E419V2
eksctl get iamserviceaccount --cluster myeks
---------
NAMESPACE NAME ROLE ARN
kube-system aws-load-balancer-controller arn:aws:iam::476286675138:role/eksctl-myeks-addon-iamserviceaccount-kube-sy-Role1-ILKQZ0MFQ6E5
kube-system ebs-csi-controller-sa arn:aws:iam::4738:role/AmazonEKS_EBS_CSI_DriverRole
kube-system efs-csi-controller-sa arn:aws:iam::47138:role/eksctl-myeks-addon-iamserviceaccount-kube-sy-Role1-Q5FRU0E419V2
// 로드 밸드밸런서 컨트롤러, EBS 컨트롤러, EFS컨트롤러 role을 가지고 있다.
8
# 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
9
# 확인
helm list -n kube-system
(masterseo@myeks:default) [root@myeks-bastion-EC2 ~]# helm list -n kube-system
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
aws-efs-csi-driver kube-system 1 2023-05-11 00:08:53.043865633 +0900 KST deployed aws-efs-csi-driver-2.4.3 1.5.5
aws-load-balancer-controller kube-system 1 2023-05-10 18:54:06.089972566 +0900 KST deployed aws-load-balancer-controller-1.5.2 v2.5.1
kube-ops-view kube-system 1 2023-05-10 18:55:59.745086296 +0900 KST deployed kube-ops-view-1.2.2 20.4.0
10
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-6f64dcc5dc-86nr5 3/3 Running 0 59s
efs-csi-controller-6f64dcc5dc-wjlc6 3/3 Running 0 59s
efs-csi-node-nf2c2 3/3 Running 0 59s
efs-csi-node-ngrf5 3/3 Running 0 59s
efs-csi-node-zdscq 3/3 Running 0 59s
1
워크셥
https://www.eksworkshop.com/docs/fundamentals/storage/efs/efs-csi-driver/
2
# 모니터링
watch 'kubectl get sc efs-sc; echo; kubectl get pv,pvc,pod'
3
# 실습 코드 clone
git clone https://github.com/kubernetes-sigs/aws-efs-csi-driver.git /root/efs-csi
cd /root/efs-csi/examples/kubernetes/multiple_pods/specs && tree
├── claim.yaml
├── pod1.yaml
├── pod2.yaml
├── pv.yaml
└── storageclass.yaml
4
# EFS 스토리지클래스 생성 및 확인
cat storageclass.yaml | yh
kubectl apply -f storageclass.yaml
kubectl get sc efs-sc
kubectl get sc
(masterseo@myeks:default) [root@myeks-bastion-EC2 specs]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
efs-sc efs.csi.aws.com Delete Immediate false 88s
gp2 (default) kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 6h42m
gp3 ebs.csi.aws.com Delete WaitForFirstConsumer true 94m
local-path rancher.io/local-path Delete WaitForFirstConsumer false 4h28m
5
# PV 생성 및 확인
: volumeHandle을 자신의 EFS 파일시스템ID로 변경
EfsFsId=$(aws efs describe-file-systems --query "FileSystems[*].FileSystemId" --output text)
sed -i "s/fs-00fc18f0ad801703e/$EfsFsId/g" pv.yaml
// 본인 EFS의 fs id 확인
sed -i "s/fs-00fc18f0ad801703e/$EfsFsId/g" pv.yaml
cat pv.yaml | yh
kubectl apply -f pv.yaml
kubectl get pv; kubectl describe pv
6
# PVC 생성 및 확인
cat claim.yaml | yh
kubectl apply -f claim.yaml
kubectl get pvc
--------------------
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ebs-snapshot-restored-claim Bound pvc-61d66ff6-be81-4899-8d84-7e6a55fd7b35 4Gi RWO gp3 36m
efs-claim Bound efs-pv 5Gi RWX efs-sc 2s
localpath-claim Bound pvc-c37e1be5-de1a-4e4b-a7df-4984a60f6ee3 1Gi RWO local-path 4h32m
7
# 파드 생성 및 연동 ?
파드 내에 /data 데이터는 EFS를 사용
# 파드 2개 생성 됨
cat pod1.yaml pod2.yaml | yh
kubectl apply -f pod1.yaml,pod2.yaml
kubectl df-pv
PV NAME PVC NAME NAMESPACE NODE NAME POD NAME VOLUME MOUNT NAME SIZE USED AVAILABLE %USED IUSED IFREE %IUSED
pvc-61d66ff6-be81-4899-8d84-7e6a55fd7b35 ebs-snapshot-restored-claim default ip-192-168-2-38.ap-northeast-2.compute.internal app persistent-storage 3Gi 44Ki 3Gi 0.00 12 262132 0.00
8
# 파드 정보 확인 ?
kubectl get pods
kubectl exec -ti app1 -- sh -c "df -hT -t nfs4"
kubectl exec -ti app2 -- sh -c "df -hT -t nfs4"
Filesystem Type Size Used Available Use% Mounted on
127.0.0.1:/ nfs4 8.0E 0 8.0E 0% /data
# 공유 저장소 저장 동작 확인
tree /mnt/myefs
9
# 작업용EC2에서도 마운트 되어 있다. 확인
tail -f /mnt/myefs/out1.txt
# 작업용EC2에서도 확인
kubectl exec -ti app1 -- tail -f /data/out1.txt
kubectl exec -ti app2 -- tail -f /data/out2.txt
// 모두 EFS에 저장 된다.
10
스테틱 방식으로 실습 한것이다.
11
# 쿠버네티스 리소스 삭제
kubectl delete pod app1 app2
kubectl delete pvc efs-claim && kubectl delete pv efs-pv && kubectl delete sc efs-sc
1
# 모니터링
watch 'kubectl get sc efs-sc; echo; kubectl get pv,pvc,pod'
2
다이나믹은 파게이트는 지원 안함.
3
# EFS 스토리지클래스 생성 및 확인
curl -s -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/storageclass.yaml
cat storageclass.yaml | yh
sed -i "s/fs-00fc18f0ad801703e/$EfsFsId/g" storageclass.yaml
kubectl apply -f storageclass.yaml
kubectl get sc efs-sc
4
# PVC/파드 생성 및 확인
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
kubectl apply -f pod.yaml
kubectl get pvc,pv,pod
# PVC/PV 생성 로그 확인
kubectl logs -n kube-system -l app=efs-csi-controller -c csi-provisioner -f
5
# 파드 정보 확인
kubectl exec -it efs-app -- sh -c "df -hT -t nfs4"
Filesystem Type Size Used Available Use% Mounted on
127.0.0.1:/ nfs4 8.0E 0 8.0E 0% /data
6
# 공유 저장소 저장 동작 확인
tree /mnt/myefs # 작업용EC2에서 확인
kubectl exec efs-app -- bash -c "cat data/out"
7
콘솔에서 확인하자
EFS -> 엑세스 포인트에 정보가 나온다.
https://kschoi728.tistory.com/86
1
프라이빗 서브넷에서 NATGW 생성
Pod가 프라이빗 서브넷에서 사용하는 경우 NAT를 생성해야 한다.
CF로 NATGW 만들어지고, 라우팅 정보가 추가 된다.
2
# 변수 지정
PrivateSubnetRouteTable=$(aws ec2 describe-route-tables --filters Name=tag:Name,Values=$CLUSTER_NAME-PrivateSubnetRouteTable --query 'RouteTables[0].RouteTableId' --output text)
# NATGW 생성, Private 라우팅 정보 추가
curl -s -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/natgw.yaml
sed -i "s/<PublicSubnet1>/$PrivateSubnet1/g" natgw.yaml
sed -i "s/<PrivateSubnetRouteTable>/$PrivateSubnetRouteTable/g" natgw.yaml
cat natgw.yaml
3
aws cloudformation deploy --template-file natgw.yaml --stack-name $CLUSTER_NAME-natgw
1
클러스터는 기존 것을 유지한다.
신규 노드 그룹 ng2 생성한다 - Blog :
서버는 1대로 생성한다.
c5d.large 의 EC2 인스턴스 스토어(임시 블록 스토리지) 설정 작업
https://aws.amazon.com/ko/blogs/containers/eks-persistent-volumes-for-instance-store/
https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/InstanceStorage.html
2
인스턴스 스토어는 EC2 스토리지(EBS) 정보에 출력되지는 않는다
3
# 인스턴스 스토어 볼륨이 있는 c5 모든 타입의 스토리지 크기
aws ec2 describe-instance-types --filters "Name=instance-type,Values=c5*" "Name=instance-storage-supported,Values=true" --query "InstanceTypes[].[InstanceType, InstanceStorageInfo.TotalSizeInGB]" --output table
--------------------------
| DescribeInstanceTypes |
+---------------+--------+
| c5d.large | 50 |
| c5d.12xlarge | 1800 |
...
# 신규 노드 그룹 생성
eksctl create nodegroup --help
eksctl create nodegroup -c $CLUSTER_NAME -r $AWS_DEFAULT_REGION --subnet-ids "$PubSubnet1","$PubSubnet2","$PubSubnet3" --ssh-access \
-n ng2 -t c5d.large -N 1 -m 1 -M 1 --node-volume-size=30 --node-labels disk=nvme --max-pods-per-node 100 --dry-run > myng2.yaml
(20분 걸림)
4
cat <<EOT > nvme.yaml
preBootstrapCommands:
- |
# Install Tools
yum install nvme-cli links tree jq tcpdump sysstat -y
# Filesystem & Mount
mkfs -t xfs /dev/nvme1n1
mkdir /data
mount /dev/nvme1n1 /data
# Get disk UUID
uuid=\$(blkid -o value -s UUID mount /dev/nvme1n1 /data)
# Mount the disk during a reboot
echo /dev/nvme1n1 /data xfs defaults,noatime 0 2 >> /etc/fstab
EOT
sed -i -n -e '/volumeType/r nvme.yaml' -e '1,$p' myng2.yaml
eksctl create nodegroup -f myng2.yaml
인스턴스 스토어 볼륨을 가지고 있다.
임시 스토리지 - 속도가 빠르다.
5
# 노드 보안그룹 ID 확인
NG2SGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=*ng2* --query "SecurityGroups[*].[GroupId]" --output text)
aws ec2 authorize-security-group-ingress --group-id $NG2SGID --protocol '-1' --cidr 192.168.1.100/32
6
# 워커 노드 SSH 접속
N4=192.168.3.160
ssh ec2-user@$N4 hostname
# 확인
ssh ec2-user@$N4 sudo nvme list
// 인스턴스 스토어 확인 = 휘발성이다.
ssh ec2-user@$N4 sudo lsblk -e 7 -d
// 용량 확인
ssh ec2-user@$N4 sudo df -hT -t xfs
// 파일 시스템 확인
ssh ec2-user@$N4 sudo tree /data
ssh ec2-user@$N4 sudo cat /etc/fstab
7
# (옵션) max-pod 확인
kubectl describe node -l disk=nvme | grep Allocatable: -A7
Allocatable:
attachable-volumes-aws-ebs: 25
cpu: 1930m
ephemeral-storage: 27905944324
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 3097552Ki
pods: 100
8
# (옵션) kubelet 데몬 파라미터 확인 ?
버그 ?
--max-pods=29 --max-pods=100
ssh ec2-user@$N4 sudo ps -ef | grep kubelet
root 2972 1 0 16:03 ? 00:00:09 /usr/bin/kubelet --config /etc/kubernetes/kubelet/kubelet-config.json --kubeconfig /var/lib/kubelet/kubeconfig --
9
스토리지 클래스 재생성
# 기존 삭제
#curl -s -O https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
kubectl delete -f local-path-storage.yaml
#
sed -i 's/opt/data/g' local-path-storage.yaml
kubectl apply -f local-path-storage.yaml
# 모니터링
watch 'kubectl get pod -owide;echo;kubectl get pv,pvc'
ssh ec2-user@$N4 iostat -xmdz 1 -p nvme1n1
# 측정 : Read
#curl -s -O https://raw.githubusercontent.com/wikibook/kubepractice/main/ch10/fio-read.fio
kubestr fio -f fio-read.fio -s local-path --size 10G --nodeselector disk=nvme
// nodeselector 사용.
# 삭제
(20분 걸림)
helm uninstall -n kube-system kube-ops-view
aws cloudformation delete-stack --stack-name eksctl-$CLUSTER_NAME-addon-iamserviceaccount-kube-system-efs-csi-controller-sa
aws cloudformation delete-stack --stack-name eksctl-$CLUSTER_NAME-addon-iamserviceaccount-kube-system-ebs-csi-controller-sa
aws cloudformation delete-stack --stack-name eksctl-$CLUSTER_NAME-addon-iamserviceaccount-kube-system-aws-load-balancer-controller
eksctl delete cluster --name $CLUSTER_NAME && aws cloudformation delete-stack --stack-name $CLUSTER_NAME
화면을 닫으면 리소스가 삭제되지 않습니다.
https://brunch.co.kr/@topasvga/3239
https://brunch.co.kr/@topasvga/3217
감사합니다.