스토리지 이해
배경
- 파드가 정지되면 파드 내부의 데이터는 모두 삭제됩니다. → 파드는 Stateless 애플리케이션
- 컨테이너는 temporary filesystem(tmpfs)를 사용하여 파일을 읽고 쓸 수 있습니다.
- 컨테이너가 삭제되면 temporary filesystem의 데이터는 삭제고, 컨테이너는 깨끗한 상태로 다시 시작됩니다. 또한 여러 컨테이너가 temporary filesystem을 공유할 수 없습니다.
- Ephemeral volumes을 사용하면 Pod내의 컨테이너간 데이터를 공유할 수 있습니다. 그러나 Pod가 삭제되는 즉시 Ephemeral volumes도 삭제가 됩니다.
- 데이터베이스처럼 데이터 보존이 필요합니다. → Persistent Volumes
- Persistent Volume(PV) 객체는 애플리케이션 데이터를 유지하는 데 사용되는 스토리지 볼륨입니다.
- Pods의 수명 주기와 별개로 자체의 수명 주기를 가집니다.
- Persistent Volume(PV)은 실제 스토리지 볼륨을 나타냅니다. Kubernetes는 PV를 포드에 연결하는데 필요한 추가 추상화 계층인 PersistentVolumeClaim(PVC)을 가지고 있습니다.
- 기본적으로 PV 객체를 직접 Pod에 마운트할 수 없습니다. PVC객체를 생성하고 Pod에 연결하는 방식입니다.
- 파드가 생성될 때 자동으로 볼륨을 마운트하여 파드에 연결하는 기능을 동적 프로비저닝(Dynamic Provisioning)이라고 합니다.
- 동적 프로비저닝을 사용하면 PV객체를 생성할 필요가 없습니다. 대신에, PVC를 생성할 때 내부적으로 자동으로 생성됩니다.
- 퍼시스턴트 볼륨의 사용이 끝났을 때 해당 볼륨은 어떻게 초기화할 것인지 별도로 설정할 수 있는데, 쿠버네티스는 이를 Reclaim Policy 라고 부릅니다.
- Reclaim Policy 에는 크게 Retain(보존), Delete(삭제, 즉 EBS 볼륨도 삭제됨), Recycle 방식이 있습니다.
스토리지 소개
emptyDir
- emptyDir 볼륨은 파드가 노드에 할당될 때 처음 생성되며, 해당 노드에서 파드가 실행되는 동안에만 존재합니다.
- 파드 내 모든 컨테이너는 emptyDir 볼륨에서 동일한 파일을 읽고 쓸 수 있지만, 해당 볼륨은 각각의 컨테이너에서 동일하거나 다른 경로에 마운트될 수 있습니다.
- 어떤 이유로든 노드에서 파드가 제거되면 emptyDir 의 데이터가 영구적으로 삭제됩니다.
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
sizeLimit: 500Mi
hostPath
- hostPath 볼륨은 호스트 노드의 파일시스템에 있는 파일이나 디렉터리를 파드에 마운트 합니다.
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# 호스트의 디렉터리 위치
path: /data
# 이 필드는 선택 사항이다
type: Directory
PV/PVC
- 퍼시스턴트볼륨 (PV)은 관리자가 프로비저닝하거나 스토리지 클래스를 사용하여 동적으로 프로비저닝한 클러스터의 스토리지입니다. 노드가 클러스터 리소스인 것처럼 PV는 클러스터 리소스입니다.
- 퍼시스턴트볼륨클레임 (PVC)은 사용자의 스토리지에 대한 요청입니다. 파드는 노드 리소스를 사용하고 PVC는 PV 리소스를 사용합니다. 파드는 특정 수준의 리소스(CPU 및 메모리)를 요청할 수 있습니다. 클레임은 특정 크기 및 접근 모드를 요청할 수 있습니다.
- PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-01
labels:
pv: pv-01
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
- PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-01
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 5Gi
storageClassName: slow
selector:
matchLabels:
pv: pv-01
matchExpressions:
- {key: environment, operator: In, values: [dev]}
라이프사이클
- Provisioning
- 정적 프로비저닝 : 클러스터 관리자는 여러 PV를 만들 수 있습니다. 클러스터 사용자가 사용할 수 있는 실제 스토리지의 세부 사항을 제공합니다. 이 PV들은 쿠버네티스 API에 존재하며 사용할 수 있습니다.
- 동적 프로비저닝 : 클러스터 관리자가 생성한 정적 PV가 사용자의 PVC와 일치하지 않으면 클러스터는 PVC를 위해 특별히 볼륨을 동적으로 프로비저닝할 수 있습니다. 이 프로비저닝은 스토리지클래스를 기반으로 합니다.
- Reclaiming
- Retain : PVC가 삭제되어도 PV는 여전히 존재하며 볼륨은 "Released" 된 상태로 간주됩니다. 그러나 이전 데이터가 여전히 볼륨에 남아 있기 때문에 아직 사용할 수 없는 상태입니다. 관리자는 볼륨을 수동으로 반환할 수 있습니다.
- Delete : PV와 외부 인프라(예: AWS EBS, GCE PD, Azure Disk 또는 Cinder 볼륨)의 관련 스토리지 자산을 모두 삭제합니다. 동적으로 프로비저닝된 볼륨은 스토리지클래스의 ReclaimingPolicy를 상속하며 기본값은 Delete 입니다.
- Recycle : Deprecated
CSI (Contaier Storage Interface) 소개
CSI Driver 배경
- AWS EBS provisioner는 당연히 Kubernetes release lifecycle을 따라서 배포되므로, provisioner 신규 기능을 사용하기 위해서는 Kubernetes version을 업그레이드해야 하는 제약 사항이 있습니다.
- 따라서, Kubernetes 개발자는 Kubernetes 내부에 내장된 provisioner (in-tree)를 모두 삭제하고, 별도의 controller Pod을 통해 동적 provisioning을 사용할 수 있도록 만들었습니다. → CSI (Container Storage Interface) driver
일반적인 CSI driver 구조
- AWS EBS CSI driver도 아래와 같은 구조
- StatefulSet 또는 Deployment로 배포된 controller Pod이 AWS API를 사용하여 실제 EBS volume을 생성하는 역할을 합니다.
- DaemonSet으로 배포된 node Pod은 AWS API를 사용하여 Kubernetes node (EC2 instance)에 EBS volume을 attach 해줍니다.
노드별 볼륨 한도
쿠버네티스 기본 한도
클라우드 서비스 | 노드 당 최대 볼륨 |
Amazon Elastic Block Store (EBS) | 39 |
Google Persistent Disk | 16 |
Microsoft Azure Disk Storage | 16 |
- 할당 가능한 볼륨 개수 확인
# 확인
kubectl describe node | grep Allocatable: -A1
- KUBE_MAX_PD_VOLS 환경 변수의 값을 설정한 후, 스케줄러를 재시작하여 이러한 한도를 변경 가능합니다.
기본 컨테이너 환경의 임시 파일시스템 사용
# 파드 배포
# 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
호스트 Path 를 사용하는 PV/PVC : local-path-provisioner 스트리지 클래스 배포
# 배포
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
- PV/PVC 를 사용하는 파드 생성
# 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 파일 존재 확인
ssh ec2-user@$N2 tree /opt/local-path-provisioner
# 해당 워커노드 자체에서 out.txt 파일 확인 : 아래 굵은 부분은 각자 실습 환경에 따라 다름
ssh ec2-user@$N2 tail -f /opt/local-path-provisioner/pvc-cb13554b-1871-42a2-8c44-590d925f03a9_default_localpath-claim/out.txt
- 파드 삭제 후 파드 재생성해서 데이터 유지 되는지 확인
# 파드 삭제 후 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
# 파드 다시 실행
kubectl apply -f localpath2.yaml
# 확인
kubectl exec -it app -- head /data/out.txt
kubectl exec -it app -- tail -f /data/out.txt
AWS 스토리지 서비스 비교
'Kubernetes > AWS EKS Workshop Study' 카테고리의 다른 글
4주차 1편 EKS Observability - Prometheus (0) | 2024.03.31 |
---|---|
3주차 2편 EKS Fundamentals - CSI, Node Group (0) | 2024.03.24 |
2주차 2편 EKS Networking - AWS LB Ctrl, CoreDNS/ExternalDNS (1) | 2024.03.17 |
2주차 1편 EKS Networking - CNI (2) | 2024.03.17 |