새소식

AWS/EKS

[PKOS Study 2주차] Kubernetes Storage ( emptyDir, hostPath, PV/PVC )

  • -

CloudNet@ 팀의 가시다님께서 Leading 하시는 PKOS 2기 Study 내용 요약

해당 Kubernetes Study 는 '24단계 실습으로 정복하는 쿠버네티스' 책을 기반으로 진행 중입니다.

 

 

이번 포스팅에서는 쿠버네티스의 Storage 중 PVPVC 에 관해 알아보겠습니다.



1. Kubernetes Storage 개요

쿠버네티스의 스토리지로는 emptyDir , hostPath , PV/PVC 가 존재합니다.

각각의 타입을 알아보겠습니다.

 

1.1. emptyDir

Pod 내부에 존재하며 동일한 Pod의 컨테이너 간 공유될 수 있는 스토리지, Pod 삭제 시 함께 삭제

Pod 내부에 데이터를 저장하는 스토리지 유형


emptyDir은 휘발성 데이터 저장소로써 만약 Pod 어플리케이션에서 보관되어야 할 데이터가 있다면 emptyDir 유형은 적합하지 않습니다.

 

다음과 같이 nginx 와 nginx 로그를 출력해주는 busybox 컨테이너가 포함된 Pod 를 배포해봅니다.
cat << EOF > web-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: weblog
spec:
  volumes:
  - name : empty-dir
    emptyDir: {}
  containers:
  - image: nginx:1.17
    name: weblog
    volumeMounts:
    - name: empty-dir
      mountPath: /var/log/nginx
  - image: busybox
    name: log-container
    volumeMounts:
    - name: empty-dir
      mountPath: /data
      readOnly: true
    args: [/bin/sh, -c, "tail -n+1 -f /data/access.log"]
EOF

kubectl apply -f web-emptydir.yaml

 

nginx 컨테이너에 접속하여 로그를 남깁니다.

ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME curl 172.30.94.33

 

 

busybox 컨테이너의 로그를 확인해봅니다.

ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME kubectl logs weblog -c log-container

 

 

emptyDir 은 Pod 내부에서는 Mount 를 통해 컨테이너 간 데이터 공유가 가능하나 Pod 를 삭제하는 순간 emptyDir은 삭제됩니다.



1.2. hostPath

hostPath 는 말 그대로 Pod 가 배포된 Worker Node (host) 의 Directory Path 를 Pod 에 마운트 시켜 사용하는 방법을 말합니다.

emptyDir 과는 다르게 Worker Node Path 에 데이터를 저장하기 때문에, Pod 가 삭제되어도 데이터는 존재합니다.

 

하지만, 해당 Pod 가 존재하는 Node 에만 데이터를 저장하기 때문에 여러 Pod 를 운영할 시 ,

Node 및 Pod 간 데이터 동기화가 복잡해진다는 단점이 존재합니다.

 

Worker Node 에 Mount 할 디렉토리를 생성합니다.

# Worker Node IP 확인
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value}" --filters Name=instance-state-name,Values=running --output table

--------------------------------------------------------------------------
|                            DescribeInstances                           |
+-----------------------------------------------------+------------------+
|                    InstanceName                     |   PublicIPAdd    |
+-----------------------------------------------------+------------------+
|  nodes-ap-northeast-2c.kimalarm.net                 |  43.200.3.61     |
|  kops-ec2                                           |  13.125.197.254  |
|  control-plane-ap-northeast-2a.masters.kimalarm.net |  43.201.58.22    |
|  nodes-ap-northeast-2a.kimalarm.net                 |  3.39.235.233    |
+-----------------------------------------------------+------------------+

# 변수 설정
W1PIP=3.39.235.233
W2PIP=43.200.3.61
ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP sudo mkdir /data
ssh -i ~/.ssh/id_rsa ubuntu@$W2PIP sudo mkdir /data

 

hostPath 를 사용하는 Pod 를 배포합니다.
cat << EOF > web-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: weblog
spec:
  volumes:
  - name : host-path
    hostPath:
      path: /data
      type: Directory
  containers:
  - image: nginx:1.17
    name: weblog
    volumeMounts:
    - name: host-path
      mountPath: /var/log/nginx
EOF

kubectl apply -f web-hostpath.yaml

 

nginx 컨테이너에 접속하여 로그를 남깁니다.

ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME curl 172.30.91.226

 

 

Worker Node 에서 로그를 확인합니다.

ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP cat /data/access.log
ssh -i ~/.ssh/id_rsa ubuntu@$W2PIP cat /data/access.log

 

 

Pod 를 삭제하고 다시 로그를 확인합니다.

# Pod 삭제 확인
kubectl get pods -o wide

# Worker Node 의 디렉토리 확인
ssh -i ~/.ssh/id_rsa ubuntu@$W2PIP ls -al /data/

# Worker Node 데이터 확인
ssh -i ~/.ssh/id_rsa ubuntu@$W2PIP cat /data/access.log

 

 

hostPath 는 Pod 가 삭제되어도 Worker Node 에 있는 데이터는 삭제되지 않습니다.



1.3. Persistent Volume (PV)

hostPath 가 Worker Node 의 로컬 볼륨이라면, PV 는 쿠버네티스 전체의 공유 볼륨입니다.

PV 는 클러스터의 어느 노드에서도 연결하여 사용이 가능합니다. ( PV : EFS , AWS EBS 등 )

 

온프레미스 환경이라면 PV 는 스토리지 관리자가 디스크 , 용량 별로 다양하게 PV Pool 을 생성해놓고,
쿠버네티스 사용자가 PVC 를 통해 가장 적합한 스토리지에 연결해서 사용할 것입니다.

 

하지만 클라우드 환경에서는 사용하지 않는 PV 를 만들어 PV Pool 을 준비한다면 필요없는 비용이 발생할 것입니다.
때문에, 클라우드에서는 PV 를 생성하지 않고 PVC 를 통해 스토리지를 요청하게 됩니다.

 

PVC 가 스토리지를 요청할 때에 자동으로 PV 가 생성되는 것Dynamic Provisiong 이라고 지칭하며

이를 위해 Provisioner 가 필요하게 됩니다.

이 Provisioner 의 기능을 가진 것이 EKS , AKS , GKE 입니다.

 

또한, Dynamic Provisioning 기능을 별도의 Controller 로 동작할 수 있게 해놓은 것이

CSI (Container Storage Inteface) Driver 입니다.

 

한편, Dynamic Provisiong 을 통해 자동으로 PV 를 생성할 때 해당 PV 의 스토리지 타입, 종류 등을 지정해야될 필요가 있습니다.

 

이를 위해 사용하는 것이 바로 Storage Class 로,

클라우드에서는 PVC 를 할때 Storage Class 를 필수적으로 지정할 필요가 있습니다.



2. AWS EBS Controller 를 통한 PV 실습

kops 는 기본적으로 AWS EBS Controller 를 배포해줍니다.

kubectl get pod -n kube-system -l app.kubernetes.io/instance=aws-ebs-csi-driver

 

Cluster 에 현재 배포된 Storage Class 를 확인해봅니다.

kubectl get sc

 

 

Storage Class 를 자세히 확인할 수 있습니다.

kubectl describe sc kops-csi-1-21

 

kops 클러스터는 gp3 와 Storage 암호화를 기본으로 사용하고 있는 것을 알 수 있습니다.

 

2.1. PVC 생성

cat << EOF > awsebs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi
EOF

kubectl apply -f awsebs-pvc.yaml

 

 

2.2. PV를 사용하는 Pod 배포

cat << EOF > 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
EOF

kubectl apply -f awsebs-pod.yaml

 

 

Pod 안에서 PV 확인

kubectl exec -it app -- sh -c 'df -hT --type=ext4'

 

 

PV 크기 늘리기

kubectl patch pvc ebs-claim -p '{"spec":{"resources":{"requests":{"storage":"10Gi"}}}}'

 

 

EBS 를 PV 로 사용했기 때문에, 용량을 늘릴 수 있으나 줄일 수는 없다는 것을 주의해야 합니다.

Contents

포스팅 주소를 복사했습니다