Infra & DevOps/k8s(EKS)

[EKS] Storage

용감한 개복치 2024. 3. 22. 16:40

Amazon EKS Workshop Study 2기

 

3주차

EKS Storage & node group :

쿠버네티스의 저장소에 대해서

 

실습환경 사전 설치

 - cloudformation 사용

 - yaml 파일 사용

aws cloudformation deploy --template-file eks-oneclick2.yaml --stack-name myeks --parameter-overrides KeyName=<pem키 이름> SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 MyIamUserAccessKeyID=<Accesskey id> MyIamUserSecretAccessKey=<Accesskey secret> ClusterBaseName=<cluster name> --region ap-northeast-2

 

bastion ec2 ip 확인

aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text

 

ssh 접속~

 

기본 설정 및 efs 확인

# default 네임스페이스 적용
kubectl ns default

# EFS 확인
echo $EfsFsId
mount -t efs -o tls $EfsFsId:/ /mnt/myefs
df -hT --type nfs4

echo "efs file test" > /mnt/myefs/memo.txt
cat /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 확인 및 Private IP 변수할당

 

워커노드 접속

 

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 연결 & kube-ops-view 확인

MyDomain=peachengineer
MyDomain=peachengineer.click
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
sed -i "s/0.13.4/0.14.0/g" externaldns.yaml
MyDomain=$MyDomain MyDnzHostedZoneId=$MyDnzHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -

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"

+) 왜인지 dns 주소로는 안돼고 로드밸런서 dns로만 접근이 된다..

 

storage

pod

파드는 공유 네임스페이스와 공유 파일시스템 볼륨이 있는 컨테이너들의 집합과 비슷하다.
출처 : https://kubernetes.io/ko/docs/concepts/workloads/pods/

 

- 하나 이상의 컨테이너 그룹, 배포 최소단위

- 파드는 노드 IP와 별개로 고유 IP를 할당 받으며, 파드 안의 컨테이너(컨테이너 런타)들은 그 IP를 공유

- 파드는 stateless 어플리케이션

- 파드 내의 데이터는 휘발성 -> 파드 사라지면 다 사라짐

- 파드 내에 여러 컨테이너 동작 가능

- 각 컨테이너는 고유한 파일 시스템 가짐(컨테이너 이미지에서 파일 시스템 제공)

==> 컨테이너가 공유할 별도의 저장소(storage) 필요, k8s 에서는 이 저장소를 volume.

출처 : https://aws.amazon.com/ko/blogs/tech/persistent-storage-for-kubernetes/

 

 

volume

개념

- 파드는 여러 볼륨 유형을 동시에 사용할 수 있음

- 기본적으로 볼륨이란 디렉토리

- 임시 볼륨 유형은 파드의 수명을 갖지만, 퍼시스턴트 볼륨(PV)은 파드의 수명을 넘어 존재

- 파드가 삭제 될 시 임시(ephemeral) 볼륨은 삭제됨

- 퍼시스턴트(persistent) 볼륨은 유지

- 볼륨의 종류와 상관없이, 파드 내의 컨테이너가 재시작되어도 데이터는 보존된다.

- 내부는 local, 외부는 network

출처 : https://kimjingo.tistory.com/153

종류

 

local

emptyDir

- 임시유형

- 파드 삭제 시 데이터도 삭제됨

- 동일 파드 안에서 여러 컨테이너가 공유

- 워커 노드의 디스크에 생성

 

사용 예제( volume mount 하는 방법)

출처 :&nbsp;https://blog.eunsukim.me/posts/kubernetes-volume-overview

 

임시 파일시스템 사용 실습

# 파드 배포
# date 명령어로 현재 시간을 10초 간격으로 /home/pod-out.txt 파일에 저장
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/3/date-busybox-pod.yaml
cat date-busybox-pod.yaml | yh
kubectl apply -f date-busybox-pod.yaml

# 파일 확인
kubectl get pod
kubectl exec busybox -- tail -f /home/pod-out.txt

# 파드 삭제 후 다시 생성 후 파일 정보 확인 > 이전 기록이 보존되어 있는지?
kubectl delete pod busybox
kubectl apply -f date-busybox-pod.yaml
kubectl exec busybox -- tail -f /home/pod-out.txt

 

파드 배포 후 파일 쓴 것 확인

 

파드 삭제 후 다시 생성하고 이전 기록 확인 > 없음

 

hostPath

- 기존에 존재하는 파드 외부의 워커노드의 특정 디렉터리를 파드의 컨테이너 파일 시스템에 마운트

- 동일 노드 안에서 여러 파드가 공유

- 같은 노드에 파드가 재시작 하는 조건으로 이전 파드의 히스토리를 볼 수 있음

- 즉, 다른 노드로 스케줄링되면 볼 수 x

==> db의 데이터 디렉토리 혹은 여러 노드에 걸쳐 유지되어야하는 용으로는 부적절

- 다음은 공식문서에서 제공하는 hostpath 의 용도

- 도커 내부에 접근할 필요가 있는 실행중인 컨테이너. /var/lib/docker 를 hostPath 로 이용함
- 컨테이너에서 cAdvisor의 실행. /sys 를 hostPath 로 이용함
- 파드는 주어진 hostPath 를 파드가 실행되기 이전에 있어야 하거나, 생성해야 하는지 그리고 존재해야 하는 대상을 지정할 수 있도록 허용함

 

PV

퍼시스턴트볼륨 서브시스템은 사용자 및 관리자에게 스토리지 사용 방법에서부터 스토리지가 제공되는 방법에 대한 세부 사항을 추상화하는 API를 제공한다. 이를 위해 PV 및 PVC라는 두 가지 새로운 API 리소스를 소개
출처 : https://kubernetes.io/ko/docs/concepts/storage/persistent-volumes/

 

- persistance volume

- 관리자가 프로비저닝 하거나, 스토리지 클래스를 사용하여 동적으로 프로비저닝한 클러스터의 스토리지

- 클러스터의 리소스

- 이걸 사용하는 파드와는 별개의 라이프사이클

- 종류

  • hostPath
  • nfs
  • CSI
  • EBS( 사용 중단 )

스토리지 클래스

- 개념과 설정하는 방식은 아래 글 참조

https://velog.io/@_zero_/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-StorageClass-%EA%B0%9C%EB%85%90-%EB%B0%8F-%EC%84%A4%EC%A0%95

 

쿠버네티스 StorageClass 개념 및 설정

쿠버네티스 StorageClass 개념 및 설정

velog.io

 

 

PVC

- 사용자의 스토리지에 대한 요청

- PV 리소스 사용

- 라이프 사이클

  • 프로비저닝 : 스토리지와 관련하여 필요한 자원을 할당하고 구성하는 과정
  • 정적 프로비저닝 : 관리자가 수동으로 PV 생성, 용량, 액세스모드, 유형 등 세부 정보를 직접 지정. 사용자가 생성하는 PVC 에서 요청되며, 쿠버네티스는 해당 PVC 요구 사항과 일치하는 사용가능한 PV 에 바인딩
  • 동적 프로비저닝 : PV를 직접 만드는 대신 스토리지 클래스 리소스만 정의해 두고, PVC를 요청하면 사용자가 원하는 PV 유형이 프로비저닝되도록 하는 기능

 

실습

hostPath를 사용하는 PV/PVC

배포

curl -s -O https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
kubectl apply -f local-path-storage.yaml

 

확인

kubectl get-all -n local-path-storage
kubectl get pod -n local-path-storage -owide
kubectl describe cm -n local-path-storage local-path-config
kubectl get sc
kubectl get sc local-path

 

pvc/pv 생성 및 확인

# PVC 생성
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/3/localpath1.yaml
cat localpath1.yaml | yh
kubectl apply -f localpath1.yaml

# PVC 확인
kubectl get pvc
kubectl describe pvc

# 파드 생성
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/3/localpath2.yaml
cat localpath2.yaml | yh
kubectl apply -f localpath2.yaml

# 파드 확인
kubectl get pod,pv,pvc
kubectl describe pv    # Node Affinity 확인
kubectl exec -it app -- tail -f /data/out.txt

 

파드에서 out.txt 파일 존재 확인

for node in $N1 $N2 $N3; do ssh ec2-user@$node tree /opt/local-path-provisioner; done

 

파드를 삭제 > 재생성 하고 데이터 유지되는지 확인

kubectl delete pod app
kubectl get pod,pv,pvc
for node in $N1 $N2 $N3; do ssh ec2-user@$node tree /opt/local-path-provisioner; done

kubectl apply -f localpath2.yaml
 
kubectl exec -it app -- head /data/out.txt
kubectl exec -it app -- tail -f /data/out.txt

 

결과

데이터가 다


+) 바인딩? 마운트?

일반적인 경우

  1. 바인딩(bind):
    • 바인딩은 기존의 파일 시스템 경로를 다른 경로에 "바인드"하는 것을 의미합니다.
    • 이것은 일반적으로 파일 시스템 내에서의 경로를 가상화된 컨테이너 내부의 경로와 매핑할 때 사용됩니다.
    • 컨테이너 내부에서의 변경 사항이 호스트의 파일 시스템에 반영됩니다.
    • 주로 Docker 및 다른 컨테이너 기반 시스템에서 사용됩니다.
  2. 마운트(mount):
    • 마운트는 파일 시스템을 특정 디렉터리에 연결하는 프로세스를 말합니다.
    • 주로 네트워크 드라이브, USB 드라이브, CD-ROM과 같은 외부 장치를 시스템에 연결할 때 사용됩니다.
    • 마운트된 파일 시스템은 해당 디렉터리에 있는 것처럼 시스템에서 접근할 수 있습니다.
    • 마운트는 주로 운영 체제 수준에서 처리됩니다.

요약하자면, 바인딩은 컨테이너 내부 경로를 호스트 파일 시스템 경로에 매핑하는 데 사용되며, 변경 사항이 양쪽에 모두 반영됩니다. 반면에 마운트는 주로 외부 장치나 네트워크 드라이브를 시스템에 연결하여 해당 디렉터리에 접근할 수 있게 합니다.

 

쿠버네티스에서의 경우

  1. 바인딩 (Binding):
    • 쿠버네티스에서 바인딩은 특정한 리소스를 다른 리소스에 "바인드"하는 과정을 의미합니다.
    • 주로 스토리지 볼륨과 파드 간의 관계를 설정할 때 사용됩니다.
    • PersistentVolumeClaim (PVC)는 스토리지를 요청하는데 사용되며, 이 PVC는 PersistentVolume (PV)와 바인딩됩니다. 이는 클러스터 내의 스토리지 볼륨과 PVC 간의 물리적인 연결을 설정하는 것입니다.
    • 바인딩은 PV의 유형, 용량 및 액세스 모드 등을 고려하여 적절한 PVC에 할당됩니다.
  2. 마운트 (Mount):
    • 쿠버네티스에서 마운트는 컨테이너 내부에서 외부 스토리지를 사용할 수 있도록 하는 과정을 의미합니다.
    • 파드가 실행될 때, 해당 파드가 요청한 스토리지가 해당 컨테이너 내에 마운트됩니다.
    • 파드 스펙의 volumes 섹션에서 정의된 볼륨이 컨테이너 내의 특정 경로에 마운트됩니다.
    • 컨테이너 내의 파일 시스템은 이 마운트된 볼륨을 통해 외부 스토리지에 액세스할 수 있습니다.

요약하면, 쿠버네티스에서 바인딩은 스토리지 요청과 실제 스토리지 간의 매핑을 설정하는 과정이며, 마운트는 컨테이너 내에서 해당 스토리지를 실제로 사용할 수 있게 하는 과정입니다. 함께 사용되어 파드가 필요로 하는 스토리지를 동적으로 할당하고 사용할 수 있도록 합니다.


 

CSI

개념

- container storage interace

- 컨테이너 오케스트레이션 시스템(쿠버네티스)과 스토리지를 제어하는 플러그인(뒤에 실습할 여러가지 storage controller) 사이의 인터페이스

- 스토리지 제어 플러그인 / volume의 라이프사이클 / 컨테이너 오케스트레이션 시스템과 플러그인 사이의 인터페이스 세 가지를 정의

- 클러스터에 별도 설치 필

 

k8s csi 플러그인

- 프로비저너(Provisioner), 어태쳐(Attacher), 컨트롤러(Controller), 노드서버(NodeServer)로 구성

출처 : https://tech.gluesys.com/blog/2022/06/21/CSI.html

  • 프로비저너(Provisioner) : 클러스터에 PVC가 생성되는 걸 모니터링하고 있다가 PVC가 생성되면 PV를 생성
  • 어태쳐(Attacher) : 파드가 PVC를 사용하려할 때 해당 컨테이너에서 PV를 마운트
  • 컨트롤러(Controller) : 컨테이너에서 사용할 볼륨을 스토리지 서버에서 생성 및 삭제
  • 노드서버(NodeServer) : 파드가 배포될 노드에서 스토리지 볼륨에 마운트할 수 있게 환경을 만듦

 

AWS EBS Controller

EBS

- EC2 인스턴스에 연결하여 데이터를 영구적으로 저장하고 부팅 볼륨으로 사용할 수 있는 블록 스토리지

- k8s 에서는 EBS 볼륨을 활용하기 위해 ebs-csi-driver 필요

- 하나의 인스턴스에만 마운트 가능

==> 여러개 쓰고 싶으면 EFS

==> accessModes 를 한 번만 사용한다는 의미로 ReadWriteOnce 로 설정

출처 :&nbsp;https://malwareanalysis.tistory.com/598

 

EBS Controller

- 쿠버네티스 클러스터 내에서 ebs 볼륨을 관리하는데 사용되는 컨트롤러

- ebs-csi-driver 와 함께 ebs 볼륨을 동적으로 생성,삭제,파드에 마운트 하는 설정에 관여

 

실습

ISRA 설정

# 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 확인
eksctl get iamserviceaccount --cluster myeks

 

EBS CSI driver 설치 (EKS add-on)

# 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
kubectl get sa -n kube-system ebs-csi-controller-sa -o yaml | head -5

# 확인
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

# csinodes 확인
kubectl get csinodes

 

gp3 스토리지 클래스 생성

# gp3 스토리지 클래스 생성 - Link
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
  #iops: "5000"
  #throughput: "250"
  allowAutoIOPSPerGBIncrease: 'true'
  encrypted: 'true'
  fsType: xfs # 기본값이 ext4
EOT
kubectl apply -f gp3-sc.yaml
kubectl get sc
kubectl describe sc gp3 | grep Parameters

 

PVC 생성

EBS 가 볼륨이니까 볼륨에 연결하고 싶다는 주문서인 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
kubectl get pvc,pv

 

파드 생성

pvc -> pv 요청

ebs가 마운트 됨

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

 

확인

kubectl get pvc,pv,pod
kubectl get VolumeAttachment

 

PV 상세 정보를 확인해 보면

kubectl get pv -o yaml | yh

 

아래와 같은 결과를 볼 수 있는데, nodeAffinity 는 파드 스케줄링에 관한 내용 -> 어떤 노드에 파드를 스케줄링할까

아래에는 required 만 있는데, preferred 도 있음

꼭 필요한 조건과 만족하면 좋은 조건

 

얘를 왜 보냐면, EBS 는 기본적으로 동일 가용영역의 인스턴스에만 붙음

==> PV 와 파드가 동일 AZ 에 위치하도록 스케쥴링 하고싶어서

==> 쉽게 말하면 파드가 뜨는 AZ(ap-northeast-2b) 조정하려고

 

 

out.txt 파일에 내용 추가 저장 확인

kubectl exec app -- tail -f /data/out.txt
kubectl df-pv

 

AWS Volume SnapShots Controller

개념

- EBS 는 스냅샷 기능 제공

- 쿠버네티스 클러스터에서 EBS 스냅샷을 관리하기 위한 컨트롤러

- 쿠버네티스 클러스터 내에서 동적으로 동작

- 정의된 일정에 따라 자동으로 스냅샷 생성 가능

- Custom Resource Definitions(CRDs)를 사용하여 스냅샷 관련 쿠버네티스 리소스 관리

 

실습

volumesnapshot controller 설치

# (참고) 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

 

설치 결과 확인

 

파드 생성 후 스냅샷 찍히는지 확인

pvc 생성 > 파드 생성 > 파일 내용 추가 저장확인 > 볼륨 스냅샷 생성

kubectl apply -f awsebs-pvc.yaml

kubectl apply -f awsebs-pod.yaml

kubectl exec app -- tail -f /data/out.txt

curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/3/ebs-volume-snapshot.yaml
cat ebs-volume-snapshot.yaml | yh
kubectl apply -f ebs-volume-snapshot.yaml

 

볼륨 스냅샷 확인

# VolumeSnapshot 확인
kubectl get volumesnapshot
kubectl get volumesnapshot ebs-volume-snapshot -o jsonpath={.status.boundVolumeSnapshotContentName} ; echo
kubectl describe volumesnapshot.snapshot.storage.k8s.io ebs-volume-snapshot
kubectl get volumesnapshotcontents

# VolumeSnapshot ID 확인 
kubectl get volumesnapshotcontents -o jsonpath='{.items[*].status.snapshotHandle}' ; echo

 

ebs 스냅샷 확인

ec2>ebs>snapshots

 

복원해보기 위해 강제 장애 재현

kubectl delete pod app && kubectl delete pvc ebs-claim

 

스냅샷 복원

kubectl get pvc,pv
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
cat ebs-snapshot-restored-claim.yaml | yh
kubectl apply -f ebs-snapshot-restored-claim.yaml

 

파드 재생성

curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/3/ebs-snapshot-restored-pod.yaml
cat ebs-snapshot-restored-pod.yaml | yh
kubectl apply -f ebs-snapshot-restored-pod.yaml

 

이전 기록 남아있나 확인 > 시간 다른 것 남아있는 거 확인 가능~

kubectl exec app -- cat /data/out.txt

 

AWS EFS Controller

EBS  여러개 쓰고싶다 > EFS

EFS 사용한 EKS 아키텍처

아키텍처에서 알 수 있듯이 EBS, EFS 는 EKS 관리 밖에 있음 -> 네트워크로 통함

 

NFS

- NetworkFileSystem

- 클라이언트 컴퓨터에서 원격 서버의 파일 시스템에 마운트하여 파일을 읽고 쓴다는 개념

출처 :&nbsp;https://dev.to/awscommunity-asean/aws-eks-with-efs-csi-driver-and-irsa-using-cdk-dgc

 

실습

Add on 혹은 helm 설치 중에 add on으로 EFS Controller 설치

핸즈온은 공식문서 -> https://docs.aws.amazon.com/eks/latest/userguide/efs-csi.html

 

Amazon EFS CSI driver - Amazon EKS

Amazon EFS CSI driver Amazon Elastic File System (Amazon EFS) provides serverless, fully elastic file storage so that you can share file data without provisioning or managing storage capacity and performance. The Amazon EFS Container Storage Interface (CSI

docs.aws.amazon.com

export cluster_name=myeks
export role_name=AmazonEKS_EFS_CSI_DriverRole
eksctl create iamserviceaccount \
    --name efs-csi-controller-sa \
    --namespace kube-system \
    --cluster $cluster_name \
    --role-name $role_name \
    --role-only \
    --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEFSCSIDriverPolicy \
    --approve
TRUST_POLICY=$(aws iam get-role --role-name $role_name --query 'Role.AssumeRolePolicyDocument' | \
    sed -e 's/efs-csi-controller-sa/efs-csi-*/' -e 's/StringEquals/StringLike/')
aws iam update-assume-role-policy --role-name $role_name --policy-document "$TRUST_POLICY"

 

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 확인

kubectl get sa -n kube-system efs-csi-controller-sa -o yaml | head -5
eksctl get iamserviceaccount --cluster myeks

엇 찾을 수 없다고 한다

 

삽질...후...워크샵...

https://www.eksworkshop.com/docs/fundamentals/storage/efs/efs-csi-driver/

 

EFS CSI Driver | EKS Workshop

Before we dive into this section, make sure to familiarized yourself with the Kubernetes storage objects (volumes, persistent volumes (PV), persistent volume claim (PVC), dynamic provisioning and ephemeral storage) that were introduced on the Storage main

www.eksworkshop.com

 

EFS CSI Driver addon 추가

아래 명령어를 추가 해준다

eksctl create addon \
  --name aws-efs-csi-driver \
  --cluster ${CLUSTER_NAME} \
  --service-account-role-arn arn:aws:iam::${ACCOUNT_ID}:role/AmazonEKS_EFS_CSI_DriverRole \
  --force

ㅉ..짜란...

 

결과 확인

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"

 

탑재 대상 ID 확인

 

EFS  파일 시스템을 다수의 파드가 사용하도록 설정

실습 코드는 git clone

 

EFS  스토리지 클래스 생성 및 확인

cat storageclass.yaml | yh
kubectl apply -f storageclass.yaml
kubectl get sc efs-sc

 

pv 생성 > volumeHandle을 위에서 확인한 efs 파일 시스템 id 로 변경

EfsFsId=$(aws efs describe-file-systems --query "FileSystems[*].FileSystemId" --output text)
sed -i "s/fs-4af69aab/$EfsFsId/g" pv.yaml
cat pv.yaml | yh

 

PVC 생성 및 확인

cat claim.yaml | yh
kubectl apply -f claim.yaml
kubectl get pvc

 

파드 생성 & 연동 > 파드 내 /data 에 저장되는 것들이 EFS를 사용한다는 뜻

cat pod1.yaml pod2.yaml | yh
kubectl apply -f pod1.yaml,pod2.yaml
kubectl df-pv

 

파드 정보 확인

Kubernetes 클러스터 내에서 app1, app2 라는 이름의 파드에 접속하여 셸을 실행한 후, 해당 파드 내에서 df 명령을 실행하여 NFSv4(Network File System version 4) 타입의 파일 시스템을 조회

kubectl get pods
kubectl exec -ti app1 -- sh -c "df -hT -t nfs4"
kubectl exec -ti app2 -- sh -c "df -hT -t nfs4"

 

현재 접속한 배스천 호스트에서 efs 파일 시스템 디렉토리를 확인한 것

pod1 pod2에서 각각 만든 out1.txt out2.txt가 여기서도 보임~

 

AWS EKS Node Group

이론

- 개념 자체는 유사 ec2 오토스케일링 그룹

- 부하가 높아지면 노드를 자동으로 증가시킴

- 인스턴스에 오토 스케일링 거는 것 처럼 desired / max / min 개수 설정 및 어떤 타입으로 만들지 미리 지정 가능

 

인스턴스 스토어 vs EBS

- 인스턴스 스토어

  • EC2 인스턴스 로컬에 연결되는 임시 스토리지. 인스턴스 종료하면 데이터도 삭제
  • 용량과 성능이 인스턴스 유형에 의해 정해짐
  • 인스턴스 비용에 포함
  • EBS에 비해 IOPS 빠름

- EBS

  • 영구적. 인스턴스 라이프사이클과 별개로 유지
  • 용량 및 성능 선택 옵션 폭이 넓음
  • 사용량 대로 추가비용 발생
  • 스냅샷과 백업 지원

 

실습

노드 그룹 생성 w. 그래비톤

생성 된 것 확인

eksctl create nodegroup --help
eksctl create nodegroup -c $CLUSTER_NAME -r $AWS_DEFAULT_REGION --subnet-ids "$PubSubnet1","$PubSubnet2","$PubSubnet3" --ssh-access \
  -n ng3 -t t4g.medium -N 1 -m 1 -M 1 --node-volume-size=30 --node-labels family=graviton --dry-run > myng3.yaml
eksctl create nodegroup -f myng3.yaml

kubectl get nodes --label-columns eks.amazonaws.com/nodegroup,kubernetes.io/arch
kubectl describe nodes --selector family=graviton
aws eks describe-nodegroup --cluster-name $CLUSTER_NAME --nodegroup-name ng3 | jq .nodegroup.taints

 

이렇게 그래비톤 적용된 노드가 결과값으로 보임

 

taints 셋팅

- nodeaffinity 랑 대조되는 개념

- node affinity 가 파드가 특정 노드를 선택하도록 하는 파드의 속성

- taints 는 노드가 파드 셋을 제외하도록 노드에 설정하는 것

- key / value / effect 로 구성

- effect 필드 값은 NoSchedule / PreferNoSchedule / NoExecute

출처 :&nbsp;https://kimjingo.tistory.com/146

aws eks update-nodegroup-config --cluster-name $CLUSTER_NAME --nodegroup-name ng3 --taints "addOrUpdateTaints=[{key=frontend, value=true, effect=NO_EXECUTE}]"

 

결과

kubectl describe nodes --selector family=graviton | grep Taints
aws eks describe-nodegroup --cluster-name $CLUSTER_NAME --nodegroup-name ng3 | jq .nodegroup.taints

 

파드 그래비톤에서 돌리기

cat << EOT > busybox.yaml
apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  terminationGracePeriodSeconds: 3
  containers:
  - name: busybox
    image: busybox
    command:
    - "/bin/sh"
    - "-c"
    - "while true; do date >> /home/pod-out.txt; cd /home; sync; sync; sleep 10; done"
  tolerations:
    - effect: NoExecute
      key: frontend
      operator: Exists
EOT
kubectl apply -f busybox.yaml

kubectl get pod -owide

 

 

 

 


참고자료

https://kubernetes.io/ko/docs/concepts/workloads/pods/

https://kubernetes.io/ko/docs/concepts/storage/storage-classes/

 

스토리지 클래스

이 문서는 쿠버네티스의 스토리지클래스의 개념을 설명한다. 볼륨과 퍼시스턴트 볼륨에 익숙해지는 것을 권장한다. 소개 스토리지클래스는 관리자가 제공하는 스토리지의 "classes"를 설명할 수

kubernetes.io

 

파드

운영 수준의 컨테이너 오케스트레이션

kubernetes.io

https://anggeum.tistory.com/entry/Kubernetes-Volume-Deep-Dive

https://kimjingo.tistory.com/146

 

[k8s] 노드 스케쥴링 - Taints와 Toleratioin(테인트와 톨러레이션)

테인트(Taints)와 톨러레이션(Toleration) 쿠버네티스 클러스터의 특정 노드에 테인트(Taint)를 설정할 수 있습니다. Node Affinity는 Pod가 특정 노드를 선택하게 하는 Pod의 속성이었다면 테인트(Taint)는 반

kimjingo.tistory.com

https://sh-t.tistory.com/38

 

[이론] AWS Container Platform (ECS, EKS) 기본 개념

안녕하세요 서후아빠입니다. ^_^ 이번 세션은 AWS Container Platform에 대해서 업무적으로 필요한 최소한의 개념에 대해서 간단히 정리해 보았습니다. VM (Virtual Machine) vs Container 구조 Container : VM처럼 Gu

sh-t.tistory.com

https://blog.eunsukim.me/posts/kubernetes-volume-overview

 

쿠버네티스 볼륨(Volume) 개념 정리

쿠버네티스에서 컨테이너에 디스크 스토리지를 연결하는 볼륨에 대해 알아봅시다

blog.eunsukim.me

 

'Infra & DevOps > k8s(EKS)' 카테고리의 다른 글

[EKS] Autoscaling  (0) 2024.04.06
[EKS] Observability  (0) 2024.03.31
[EKS] network  (0) 2024.03.17
[EKS] VPC CNI  (1) 2024.03.16
[EKS] 설치 및 기본 사용  (0) 2024.03.10