3주차 eks 스터디는 스토리지 및 노드 관리이다.

 

 

3주차 실습 환경 구성은 앞선 2주차와 마찬가지로 클라우드 포메이션을 통해 배포를 진행한다.

2주차

https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/eks-oneclick.yaml

3주차

https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/eks-oneclick2.yaml

 

2주차 3주차 각각 다운받아서 diff로 비교해보면 efs 쪽 설정이 추가된것을 확인할수있다.

  • Amazon EKS 윈클릭 배포 (EFS 생성 추가) & 기본 설정
    • 기본 설정 및 EFS 확인
    # default 네임스페이스 적용
    **kubectl ns default**
    
    # (옵션) context 이름 변경
    NICK=<각자 자신의 닉네임>
    **NICK=gasida**
    kubectl ctx
    kubectl config rename-context admin@myeks.ap-northeast-2.eksctl.io **$NICK@myeks**
    
    # EFS 확인 : AWS 관리콘솔 EFS 확인해보자
    mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport ***<자신의 EFS FS ID>***.efs.ap-northeast-2.amazonaws.com:/ **/mnt/myefs**
    **df -hT --type nfs4**
    mount | grep nfs4
    **echo "efs file test" > /mnt/myefs/memo.txt**
    cat /mnt/myefs/memo.txt
    **rm -f /mnt/myefs/memo.txt**
    
    # 스토리지클래스 및 CSI 노드 확인
    kubectl get sc
    kubectl get sc gp2 -o yaml | yh
    kubectl get csinodes
    
    # 노드 정보 확인
    kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone
    ****eksctl get iamidentitymapping --cluster myeks
    ****
    # 노드 IP 확인 및 PrivateIP 변수 지정
    N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})
    N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2b -o jsonpath={.items[0].status.addresses[0].address})
    N3=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})
    echo "export N1=$N1" >> /etc/profile
    echo "export N2=$N2" >> /etc/profile
    echo "export N3=$N3" >> /etc/profile
    echo $N1, $N2, $N3
    
    # 노드 보안그룹 ID 확인
    NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=*ng1* --query "SecurityGroups[*].[GroupId]" --output text)
    aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr 192.168.1.100/32
    
    # 워커 노드 SSH 접속
    ssh ec2-user@$N1 hostname
    ssh ec2-user@$N2 hostname
    ssh ec2-user@$N3 hostname
    
    # 노드에 툴 설치
    ssh ec2-user@$N1 sudo yum install links tree jq tcpdump sysstat -y
    ssh ec2-user@$N2 sudo yum install links tree jq tcpdump sysstat -y
    ssh ec2-user@$N3 sudo yum install links tree jq tcpdump sysstat -y
    
    • AWS LB/ExternalDNS, kube-ops-view 설치
    # AWS LB Controller
    helm repo add eks <https://aws.github.io/eks-charts>
    helm repo update
    helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME \\
      --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller
    
    # ExternalDNS
    MyDomain=<자신의 도메인>
    **MyDomain=gasida.link**
    MyDnzHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text)
    echo $MyDomain, $MyDnzHostedZoneId
    curl -s -O <https://raw.githubusercontent.com/gasida/PKOS/main/aews/externaldns.yaml>
    MyDomain=$MyDomain MyDnzHostedZoneId=$MyDnzHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -
    
    # kube-ops-view
    helm repo add geek-cookbook <https://geek-cookbook.github.io/charts/>
    helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system
    kubectl patch svc -n kube-system kube-ops-view -p '{"spec":{"type":"LoadBalancer"}}'
    kubectl **annotate** service kube-ops-view -n kube-system "external-dns.alpha.kubernetes.io/hostname=**kubeopsview**.$MyDomain"
    echo -e "Kube Ops View URL = http://**kubeopsview**.$MyDomain:8080/#scale=1.5"
    
    • 설치 정보 확인
    # 이미지 정보 확인
    **kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" | tr -s '[[:space:]]' '\\n' | sort | uniq -c**
    
    # eksctl 설치/업데이트 addon 확인
    **eksctl get addon --cluster $CLUSTER_NAME**
    
    # IRSA 확인
    **eksctl get iamserviceaccount --cluster $CLUSTER_NAME**
    

 

 

2주차와 마찬가지(efs 및 2주차에서 실습 진행했떤 ALB등은 추가돼있음)로 위와같이 진행하면 3주차 실습 준비 완료

 

 

첫번째 사진처럼 파드안의 컨테이너 내 tmpFS가 있는경우 컨테이너가 종료되면 tmpFS내 데이터도 삭제된다.

마찬가지로 두번째 사진처럼 파드내에 볼륨이 있고 두개의 컨테이너가 해당 볼륨을 공유해서 사용하여도 파드가 종료되면 볼륨내 데이터도 삭제가 된다.

따라서 컨테이너, 파드의 종료여부와 상관없이 데이터를 보존하기 위해 PV/PVC가 필요하다.

앞서 PV/PVC를 이용하지 않는다면(즉 컨테이너 내에 임시의 파일시스템을 이용한다면)데이터가 보존되지 않는다고했는데 이를 실제로 확인해보면 아래와 같다.

10초간격으로 date를 찍는 busybox를 deployment로 배포하고 pod-out.txt 확인하면 10초에 한번씩 찍힌것을 볼수있다.

이후 busybox 파드를 종료후 다시 확인해보면 이전에 찍혔던 date(즉 기존 데이터)는 보존되지 않은것을 확인할수있다.

 

이번에는 local-path-provisioner 스트리지 클래스를 사용하여 데이터 보존성을 확인해보자.

위와같이 local-path-provisioner 사용하기 위해 localpth claim 을 생성해주고

위와같이 앞서 생성한 PVC를 마운트하여 파드를 실행하고 아까와같이 파드를 재시작하여 데이터 보존유무를 확인해보자.

위와같이 파드를 종료하여도 데이터가 없어지지않고 기존 데이터가 보존되는것을 확인할수있다.

실제 데이터는 node1에 저장돼있는것을 확인할수있다.

 

여기까지 eks 클러스터내의 파드를 이용한 볼륨 마운트를 알아보았는데 지금부터는 AWS EBS 마운트를 알아보도록 하자.

 

```bash
# 아래는 **aws-ebs-csi-driver** 전체 버전 정보와 기본 설치 버전(True) 정보 확인
**aws eks describe-addon-versions \\
    --addon-name aws-ebs-csi-driver \\
    --kubernetes-version 1.24 \\
    --query "addons[].addonVersions[].[addonVersion, compatibilities[].defaultVersion]" \\
    --output text**
v1.18.0-eksbuild.1
Tru
v1.17.0-eksbuild.1
False
...

# ISRA 설정 : AWS관리형 정책 AmazonEBSCSIDriverPolicy 사용
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**

# ISRA 확인
kubectl get sa -n kube-system ebs-csi-controller-sa -o yaml | head -5
**eksctl get iamserviceaccount --cluster myeks**
NAMESPACE	    NAME				            ROLE ARN
kube-system 	ebs-csi-controller-sa		**arn:aws:iam::911283464785:role/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

# 확인
**eksctl get addon --cluster ${CLUSTER_NAME}**
kubectl get deploy,ds -l=app.kubernetes.io/name=aws-ebs-csi-driver -n kube-system
kubectl get pod -n kube-system -l 'app in (ebs-csi-controller,ebs-csi-node)'
kubectl get pod -n kube-system -l app.kubernetes.io/component=csi-driver

# ebs-csi-controller 파드에 6개 컨테이너 확인
**kubectl get pod -n kube-system -l app=ebs-csi-controller -o jsonpath='{.items[0].spec.containers[*].name}' ; echo**
ebs-plugin csi-provisioner csi-attacher csi-snapshotter csi-resizer liveness-probe

# csinodes 확인
kubectl get csinodes

# gp3 스토리지 클래스 생성
kubectl get sc
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
**kubectl apply -f gp3-sc.yaml**
kubectl get sc
kubectl describe sc gp3 | grep Parameters
```

-

2주차때 했던것처럼 IRSA 설정해서 AWS EBS와 EKS 클러스터간에 통신이 가능하도록 해줘야 한다. 

ebs 테스트 준비 완료

 

이제 아까처럼 pv/pvc 로 마운트하여 테스트해보자.

기존

위와같이 pvc 생성하고 해당 pvc를 마운트하는 파드를 새로 생성하면 아래와같이 새로운 볼륨이 생성된것을 확인할수있다.

이와같이 파드에 EBS를 마운트하여 사용할수있다. 또한 기존 aws ebs와 마찬가지로 용량 증설도 가능하다.(반대로 축소는 불가능)

 

이번엔 볼륨 스냅샷에 대해 알아보자. 이또한 EKS의 개념이 아닌 aws내 ebs 의 스냅샷 기능을 이용하는것.

 

```bash
# (참고) EBS CSI Driver에 snapshots 기능 포함 될 것으로 보임
kubectl describe pod -n kube-system -l app=ebs-csi-controller

# 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
kubectl api-resources  | grep snapshot

# 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
kubectl get pod -n kube-system -l app=snapshot-controller

# 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 # 혹은 volumesnapshotclasses
```

 위와같이 준비 진행

 

위와같이 볼륨 스냅샷을 apply하면 아래와같이 스냅샷이 생성된것을 확인할수있다.

 

 

그럼 장애를 재연해서 스냅샷으로 복원해보도록 하자.

위와같이 실수록 삭제한 상황에서

우선 위와같이 datasource를 ebs볼륨 스냅샷을 가지고 pvc를 생성해주고

위와같이 스냅샷을 이용하여 생성한 pvc를 가지고 파드를 생성해주면 

위와같이 기존에 가지고 있떤 스냅샷을 가지고 ebs를 생성된것이 확인된다.

 

이번엔 efs에 대해 진행할것이다.

우선 efs의 구성 및 아키텍쳐는 다음과 같다.

(처음 efs 에 대해 공부할때 AWS에 있는 NFS로 이해했었다.)

 

# EFS 정보 확인 
aws efs describe-file-systems --query "FileSystems[*].FileSystemId" --output text

# 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

# 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

****# ISRA 확인
kubectl get sa -n kube-system efs-csi-controller-sa -o yaml | head -5
****eksctl get iamserviceaccount --cluster myeks

# 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

# 확인
helm list -n kube-system
kubectl get pod -n kube-system -l "app.kubernetes.io/name=aws-efs-csi-driver,app.kubernetes.io/instance=aws-efs-csi-driver"

LB나 EBS와 마찬가지로 IRSA 셋팅해준다.

이제 efs를 마운트한 파드를 배포해보자.

 

위와같이 EFS가 연결돼있는 PV/PVC를 생성해주고

 

위와같이 파드 2개를 생성해준다.

위와같이 2개의 파드와 맨 처음 해당 실습을 진행했을때 배스천호스트에 마운트해놨던 efs까지 확인할수있다.

 

즉 현재 방금 배포한 2개의 파드와 실습용ec2 인스턴스는 한개의 efs 볼륨을 공유해서 사용하고있는상황
(예전 온프레미스 환경에서 NFS는 실시간 동기화필요할때(업로드 디렉토리처럼) 많이 사용했었음)

 

'job > eks' 카테고리의 다른 글

eks 6주차  (0) 2023.05.31
eks 5주차  (0) 2023.05.23
4주차 eks 스터디  (0) 2023.05.16
eks 2주차  (0) 2023.05.02
eks 교육 1  (0) 2023.04.24

+ Recent posts