Search

쿠버네티스 스토리지

Date
2023/03/18
Catagory
Kubernetes
Service
Kubenetes
Keyword
week2

쿠버네티스 스토리지

기본 개념

일반적으로 파드가 중지되거나 삭제되면 파드 내부의 데이터는 모두 삭제됩니다. 즉, 파드는 Stateless한 특징을 가지고 있습니다.
하지만 파드를 DB용도로 사용하거나 데이터 보존이 필요한 경우 아래와 같은 별도의 볼륨을 사용해야 합니다.
emptyDir : 파드에서 일반적으로 사용하는 볼륨. 파드가 삭제되면 같이 삭제됩니다.
hostPath : 특정 노드에서만 사용가능한 영구 볼륨
Persistent Volume; PV : 모든 노드에서 사용가능한 영구 볼륨
PV는 파드가 생성될 때 위와 같은 볼륨을 자동으로 마운트하는 기능인 동적 프로비저닝(Dynamic Provisioning) 기능을 제공합니다.
또한, PV는 파드의 삭제로 사용이 끝났을 때 어떻게 초기화할 것인지 별도로 설정할 수 있습니다. 이를 Reclaim Policy라고 하는데, 이 정책에는 Retain(보존), Delete(삭제), Recycle 방식이 있습니다.
쿠버네티스에서 동적 프로비저닝은 스토리지 클래스 정의를 통해 제공되며, 스토리지 클래스에 명시되어 있는 프로비저너가 PV를 생성하고 PVC 상태를 체크합니다. 이와 같은 프로비저너가 제공하는 기능을 별도의 Controller Pod를 통해 사용할 수 있도록 만든 것이 CSI(Container Storage Interface) 드라이버 입니다.
kOps에서는 AWS에서 제공하는 AWS EBS CSI driver를 사용합니다.

실습 - hostPath를 사용하는 PV/PVC인 local-path-provisioner 스토리지 클래스 배포

# 마스터노드의 이름 확인해두기 kubectl get node | grep control-plane | awk '{print $1}' i-01565b9b70da400be # yaml 다운로드 curl -s -O https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.23/deploy/local-path-storage.yaml # local-path-storage.yaml에 추가 ... spec: replicas: 1 selector: matchLabels: app: local-path-provisioner template: metadata: labels: app: local-path-provisioner spec: nodeSelector: kubernetes.io/hostname: i-01565b9b70da400be # 마스터 노드 이름 tolerations: - effect: NoSchedule key: node-role.kubernetes.io/control-plane operator: Exists ... # local-path-storage.yaml에 변경 kind: ConfigMap apiVersion: v1 metadata: name: local-path-config namespace: local-path-storage data: config.json: |- { "nodePathMap":[ { "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES", "paths":["/data/local-path"] } ] } ...
Bash
/data/local-path 경로는 인스턴스 스토어 볼륨 경로
(jjikin:default) [root@kops-ec2 ~]# df -hT --type xfs Filesystem Type Size Used Avail Use% Mounted on /dev/nvme0n1p1 xfs 8.0G 2.7G 5.4G 34% /
Bash
생성 후 확인
kubectl apply -f local-path-storage.yaml
Bash
hostPath와 NodeSelector를 사용해서 특정 노드(마스터 노드)에 배포할 수 있었습니다.
이후 PV, PVC를 사용하는 파드를 생성합니다.
# PVC 생성 cat ~/pkos/3/localpath1.yaml | yh kubectl apply -f ~/pkos/3/localpath1.yaml # PVC 확인 kubectl get pvc kubectl describe pvc # 파드 생성 cat ~/pkos/3/localpath2.yaml | yh kubectl apply -f ~/pkos/3/localpath2.yaml # 파드 확인 kubectl get pod,pv,pvc kubectl krew install df-pv && kubectl df-pv kubectl exec -it app -- tail -f /data/out.txt Sat Mar 18 15:30:27 UTC 2023 Sat Mar 18 15:30:32 UTC 2023 Sat Mar 18 15:30:37 UTC 2023
Bash
파드가 출력하는 날짜가 저장되는 경로(/data/out.txt)를 찾아보면 1번 워커 노드에 생성되었음을 확인했습니다.
또한 실행 중인 파드를 삭제할 경우에도 PV, PVC는 유지되며 PV 내 데이터는 유지됨을 확인했습니다.
다시 파드를 생성하면, 이어서 이후 날짜가 저장됩니다.

실습 - AWS EBS Controller

추후 정리 예정

AWS EBS Controller를 사용한 PV, PVC 생성

# aws ebs csi driver는 kOps 설치 시 기본 설치 kubectl get pod -n kube-system -l app.kubernetes.io/instance=aws-ebs-csi-driver # 스토리지 클래스 확인 kubectl get sc kops-csi-1-21 kops-ssd-1-17 kubectl describe sc kops-csi-1-21 | grep Parameters Parameters: encrypted=true,type=gp3 kubectl describe sc kops-ssd-1-17 | grep Parameters Parameters: encrypted=true,type=gp2 # 워커노드의 EBS 볼륨 확인 aws ec2 describe-volumes --filters Name=tag:k8s.io/role/node,Values=1 --query "Volumes[].{VolumeId: VolumeId, VolumeType: VolumeType, InstanceId: Attachments[0].InstanceId, State: Attachments[0].State}" | jq # 워커노드에서 파드에 추가한 EBS 볼륨 확인 aws ec2 describe-volumes --filters Name=tag:ebs.csi.aws.com/cluster,Values=true --query "Volumes[].{VolumeId: VolumeId, VolumeType: VolumeType, InstanceId: Attachments[0].InstanceId, State: Attachments[0].State}" | jq # 워커노드에서 파드에 추가한 EBS 볼륨 모니터링 while true; do aws ec2 describe-volumes --filters Name=tag:ebs.csi.aws.com/cluster,Values=true --query "Volumes[].{VolumeId: VolumeId, VolumeType: VolumeType, InstanceId: Attachments[0].InstanceId, State: Attachments[0].State}" --output text; date; sleep 1; done # PVC 생성 cat ~/pkos/3/awsebs-pvc.yaml | yh kubectl apply -f ~/pkos/3/awsebs-pvc.yaml # 파드 생성 cat ~/pkos/3/awsebs-pod.yaml | yh kubectl apply -f ~/pkos/3/awsebs-pod.yaml # PVC, 파드 확인 kubectl get pvc,pv,pod kubectl df-pv # 추가된 EBS 볼륨 상세 정보 확인 aws ec2 describe-volumes --volume-ids $(kubectl get pv -o jsonpath="{.items[0].spec.csi.volumeHandle}") | jq # 파일 내용 추가 저장 확인 kubectl exec app -- tail -f /data/out.txt # 파드 내에서 볼륨 정보 확인 kubectl exec -it app -- sh -c 'df -hT --type=ext4'
Bash

볼륨 증설

# 현재 pv 명 기준 4G > 10G 로 증가 : .spec.resources.requests.storage의 4Gi 를 10Gi로 변경 kubectl edit pvc ebs-claim kubectl patch pvc ebs-claim -p '{"spec":{"resources":{"requests":{"storage":"10Gi"}}}}' kubectl patch pvc ebs-claim -p '{"status":{"capacity":{"storage":"10Gi"}}}' kubectl get pvc ebs-claim -o jsonpath={.spec.resources.requests.storage} ; echo kubectl get pvc ebs-claim -o jsonpath={.status.capacity.storage} ; echo # 확인 : 볼륨 용량 수정 반영이 되어야 되니, 수치 반영이 조금 느릴수 있다 kubectl exec -it app -- sh -c 'df -hT --type=ext4' kubectl df-pv aws ec2 describe-volumes --volume-ids $(kubectl get pv -o jsonpath="{.items[0].spec.csi.volumeHandle}") | jq
Bash
# 리소스 삭제 kubectl delete pod app & kubectl delete pvc ebs-claim
Bash

실습 - AWS Volume SnapShots Controller

vs controller 설치

# kOps 클러스터 편집 및 적용 kops edit cluster ----- spec: snapshotController: enabled: true certManager: # 이미 설치됨 enabled: true # 이미 설치됨 ----- kops update cluster --yes && sleep 3 && kops rolling-update cluster # 생성 확인 kubectl get pod -n kube-system | grep snapshot kubectl get crd | grep volumesnapshot # vsclass 생성 kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/master/examples/kubernetes/snapshot/manifests/classes/snapshotclass.yaml kubectl get volumesnapshotclass NAME DRIVER DELETIONPOLICY AGE csi-aws-vsc ebs.csi.aws.com Delete 17s
Bash

테스트를 위한 PVC, 파드 생성

# PVC 생성 kubectl apply -f ~/pkos/3/awsebs-pvc.yaml # 파드 생성 kubectl apply -f ~/pkos/3/awsebs-pod.yaml # VolumeSnapshot 생성 : Create a VolumeSnapshot referencing the PersistentVolumeClaim name cat ~/pkos/3/ebs-volume-snapshot.yaml | yh kubectl apply -f ~/pkos/3/ebs-volume-snapshot.yaml # 파일 내용 추가 저장 확인 kubectl exec app -- tail -f /data/out.txt # VolumeSnapshot 확인 kubectl get volumesnapshot kubectl get volumesnapshot ebs-volume-snapshot -o jsonpath={.status.boundVolumeSnapshotContentName} kubectl describe volumesnapshot.snapshot.storage.k8s.io ebs-volume-snapshot # AWS EBS 스냅샷 확인 aws ec2 describe-snapshots --owner-ids self | jq aws ec2 describe-snapshots --owner-ids self --query 'Snapshots[]' --output table (jjikin:default) [root@kops-ec2 ~]#ubectl get volumesnapshot NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE ebs-volume-snapshot true ebs-claim csi-aws-vsc snapcontent-b90f7ebc-d59b-4607-ac5f-f47bd65f6556 6m47s (jjikin:default) [root@kops-ec2 ~]# kubectl get volumesnapshot ebs-volume-snapshot -o jsonpath={.status.boundVolumeSnapshotContentName} snapcontent-b90f7ebc-d59b-4607-ac5f-f47bd65f6556
Bash

파드 및 pvc를 강제 삭제하고 스냅샷으로 복원 진행

kubectl delete pod app && kubectl delete pvc ebs-claim # 스냅샷에서 PVC 로 복원 cat ~/pkos/3/ebs-snapshot-restored-claim.yaml | yh kubectl apply -f ~/pkos/3/ebs-snapshot-restored-claim.yaml # 파드 생성 cat ~/pkos/3/ebs-snapshot-restored-pod.yaml | yh kubectl apply -f ~/pkos/3/ebs-snapshot-restored-pod.yaml # 파일 내용 저장 확인 kubectl exec app -- cat /data/out.txt ... Sat Mar 18 16:38:06 UTC 2023 Sat Mar 18 16:38:11 UTC 2023 Sat Mar 18 16:43:03 UTC 2023 Sat Mar 18 16:43:08 UTC 2023 ... # 리소스 삭제 kubectl delete pod app && kubectl delete pvc ebs-snapshot-restored-claim && kubectl delete volumesnapshots ebs-volume-snapshot
Bash
참고
가시다님 PKOS2 스터디 자료