3주차 - EKS Storage & Managed Node Groups(1)(스토리지)

728x90

CSI

  • Container Srotage Interface
  • 쿠버네티스에서는 다양한 스토리지 연계를 위해 CSI 인터페이스를 제공
    • CSI 인터페이스 덕분에 쿠버네티스에서 쉽게 스토리지(EBS, EFS 등)를 사용할 수 있음
  • 쿠버네티스 CSI 인터페이스에 맞춰 개발된 AWS CSI
    • EKS에서 EBS, EFS 등 AWS 스토리지를 다루려면 스토리지 별로 AWS CSI 드라이버를 설치해야 사용 가능

참고: https://malwareanalysis.tistory.com/598 (악분님 블로그)

https://malwareanalysis.tistory.com/598

 

K8S Storage

1. 파드 내부의 데이터는 파드가 정지되면 모두 삭제됨(휘발성) → 즉, 파드가 모두 상태가 없는(Stateless) 애플리케이션이였음! : Temporary filesystem, Volume

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

 

 

  • 파드 기본 및 empty 저장소 동작 확인 
# 모니터링
kubectl get pod -w

# redis 파드 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - name: redis
    image: redis
EOF

# redis 파드 내에 파일 작성
kubectl exec -it redis -- pwd
kubectl exec -it redis -- sh -c "echo hello > /data/hello.txt"
kubectl exec -it redis -- cat /data/hello.txt

# ps 설치
kubectl exec -it redis -- sh -c "apt update && apt install procps -y"
kubectl exec -it redis -- ps aux

# redis 프로세스 강제 종료 : 파드가 어떻게 되나요? hint) restartPolicy
kubectl exec -it redis -- kill 1
kubectl get pod

# redis 파드 내에 파일 확인
kubectl exec -it redis -- cat /data/hello.txt
kubectl exec -it redis -- ls -l /data

# 파드 삭제
kubectl delete pod redis

 

  • 프로세스 강제 종료 시, Pod가 재시작 되는것을 확인

  • Pod 재시작 후, 이전에 생성한 hello.txt파일이 사라진 것을 확인

 

※ 별도 볼륨 설정을 하지 않은 경우, 컨테이너의 저장된 데이터는 Pod 삭제 및 재기동 시 사라지는 휘발성 Data

 

  • emptyDir 동작 확인
# 모니터링
kubectl get pod -w

# redis 파드 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - name: redis
    image: redis
    volumeMounts:
    - name: redis-storage
      mountPath: /data/redis
  volumes:
  - name: redis-storage
    emptyDir: {}
EOF

# redis 파드 내에 파일 작성
kubectl exec -it redis -- pwd
kubectl exec -it redis -- sh -c "echo hello > /data/redis/hello.txt"
kubectl exec -it redis -- cat /data/redis/hello.txt

# ps 설치
kubectl exec -it redis -- sh -c "apt update && apt install procps -y"
kubectl exec -it redis -- ps aux

# redis 프로세스 강제 종료 : 파드가 어떻게 되나요? hint) restartPolicy
kubectl exec -it redis -- kill 1
kubectl get pod

# redis 파드 내에 파일 확인
kubectl exec -it redis -- cat /data/redis/hello.txt
kubectl exec -it redis -- ls -l /data/redis

# 파드 삭제 후 파일 확인
kubectl delete pod redis
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - name: redis
    image: redis
    volumeMounts:
    - name: redis-storage
      mountPath: /data/redis
  volumes:
  - name: redis-storage
    emptyDir: {}
EOF

# redis 파드 내에 파일 확인
kubectl exec -it redis -- cat /data/redis/hello.txt
kubectl exec -it redis -- ls -l /data/redis

# 파드 삭제
kubectl delete pod redis
  • 프로세스 강제 종료 시, Pod가 재시작 되는것을 확인

  • Pod 재시작 후, 이전에 생성한 hello.txt파일이 사라진 것을 확인

 

※ emptydir 경우, 컨테이너의 저장된 데이터는 Pod 재기동 시 저장된 Data는 보존 → 하지만, Pod가 삭제된다면 저장된 Data는 모두 소멸

 

2. 데이터베이스(파드)처럼 데이터 보존이 필요 == 상태가 있는(Stateful) 애플리케이션 : PV & PVC
→ 로컬 볼륨(hostPath) ⇒ 퍼시스턴트 볼륨(Persistent Volume, PV) - 어느 노드에서도 연결하여 사용 가능, 예시) NFS, AWS EBS, Ceph 등

 

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

 

 

# hostPath vs Local Path Provisioner(StorageClass 제공) 의 차이점과 장단점은?

→ Local Path Provisioner를 사용하면 디렉토리명을 다이나믹하게 지정 할 수 있음(ex: pvc-f0b9e730-a590-4505-9f90-f92cb356db2a_default_localpath-claim)

→ StorageClass를 사용하여 동적으로 PV를 사용 할 수 있음.

 

  • hostpath 동장확인(local-path-provisioner 스트리지 클래스)
# 배포
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.31/deploy/local-path-storage.yaml
...
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-path
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: local-path-config
  namespace: local-path-storage
data:
  config.json: |-
    {
            "nodePathMap":[
            {
                    "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES",
                    "paths":["/opt/local-path-provisioner"]
            }
            ]
    }
  setup: |-
    #!/bin/sh
    set -eu
    mkdir -m 0777 -p "$VOL_DIR"
  teardown: |-
    #!/bin/sh
    set -eu
    rm -rf "$VOL_DIR"
...

# 확인
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 생성
    • 최초 생성 시, pending상태 확인

  • pv 생성 후, pvc 바인딩 확인

  • Pod가 배포된 Node1에서 localpath 경로 확인
    • 경로: /opt/local-path-provisioner

  • Pod에 저장된 Data 확인

  • 파드 삭제 후 파드 재생성해서 데이터 유지 되는지 확인
# 파드 삭제 후 PV/PVC 확인
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

# 파드 다시 실행
cat <<EOF | kubectl apply -f -
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: localpath-claim
EOF
 
# 확인
kubectl exec -it app -- head /data/out.txt
kubectl exec -it app -- tail -f /data/out.txt

 

  • Pod 삭제 시, Node1에 데이터가 남아있는 것을 확인

 

  • Pod 재실행 시 저장되는 데이터 확인
    • Pod가 삭제된 시점의 Data는 존재하지 않고, Pod 재실행 시 Data가 다시 기록되는 것을 확인

728x90