Home 4. kubernetes pv and pvc
Post
Cancel

4. kubernetes pv and pvc

kubernetes pv and pvc

데이터 보존

docker 에서도 컨테이너의 데이터를 영속적으로 저장하기 위해서는 호스트의 영역을 공유하는 방식을 이용했다. kubernetes 에서도 호스트에 위치한 디렉터리를 각 포드와 공유함으로써 데이터를 보존하는 것이 가능하다. 하지만 쿠버네티스는 클러스터 환경이기 때문에, 운영상의 이유(장애 등)로 워커 노드 중 다른 노드로 포드가 배정 되었을 경우에는 호스트의 저장공간을 접근할 수 없게 된다. 따라서 어느 노드에서도 접근해 사용할 수 있는 Persistent Volume 을 사용한다.

Type 1. Local Volume (hostPath, emptyDir)

hostPath

hostPath 는 워커노드의 호스트와 볼륨을 공유하기 위해 사용한다. CAdvisor와 같은 모니터링 툴을 사용하는 경우가 아니라면 권장되는

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Pod
metadata:
  name: hostpath-pod
spec:
  containers:
    - name: my-container
      image: busybox
      args: [ "tail", "-f", "/dev/null" ]
      volumeMounts:
        - name: my-hostpath-volume
          mountPath: /etc/data # 포드의 /etc/data를 호스트의 /tmp에 연결
  volumes:
    - name: my-hostpath-volume
      hostPath:
        path: /tmp 
1
2
3
kubectl apply -f ./docs/Kubernetes/Kubernetes_yarm_files/4_pv_pvc/hostpath-pod.yaml 

kubectl exec -it hostpath-pod -- touch /etc/data/mydata

emptyDir

emptyDir 는 포드가 실행되는 도중에만 필요한 휘발성 데이터를 각 컨테이너가 함께 사용할 수 있도록 볼륨을 공유하기 위해 사용한다. 포드가 삭제되면 emptyDir 에 저장되어 있던 데이터도 함께 삭제된다.

  • 한 컨테이너가 파일을 관리하고, 한 컨테이너가 그 파일을 사용하는 경우에 유용하게 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: v1
kind: Pod
metadata: 
  name: emptydir-pod
spec:
  containers:
    - name: content-creator
      image: alicek106/alpine-wget:latest
      args: ["tail", "-f", "/dev/null"]
      volumeMounts:
      - name: my-emptydir-volume
        mountPath: /data # 1. 컨테이너가 파일을 생성하는 영역
  
    - name: apache-webserver
      image: httpd:2
      volumeMounts:
      - name: my-emptydir-volume
        mountPath: /usr/local/apache2/htdocs/ # 2. 아파치 웹서버에서 접근

  volumes:
    - name: my-emptydir-volume
      emptyDir: {}
1
2
3
4
5
6
7
8
9
10
11
kubectl apply -f emptydir-pod.yaml

kubectl exec -it emptydir-pod -c content-creator sh 
/ # echo Hello, Kubernetes! >> /data/test.html
/ # exit

kubectl describe pod emptydir-pod | grep IP

kubectl run -i tty --rm debug \
  --image=alicek106/ubuntu:curl --restart=Never -- curl 172.17.0.8/test.html
  Hello, Kubernetes!

Type 2. 네트워크 볼륨

쿠버네티스는 네트워크 볼륨의 위치에 상관없이, 네트워크로 접근만 가능하다면 어느곳에서든지 포드에 마운트 시킬 수 있다. 네트워크 볼륨을 선택하는 기준은 1) 데이터 읽고 쓰는 속도, 2) 마운트 방식(1:1, 1:n), 3) 구축비용 등이 있다.

NFS

NFS(Network File System) 는 하나의 서버만으로 간편하게 사용할 수 있으며, NFS를 마치 로컬 스토리지 처럼 사용할 수 있다는 장점이 있다.

  • NFS 서버 : 영속적인 데이터가 실제로 저장되는 네트워크 스토리지 서버
  • NFS 클라이언트 : NFS 서버에 마운트해 스토리지에 파일을 읽고 쓰는 역할을 한다.

Type 3. PV, PVC를 이용한 볼륨관리

PV, PVC는 왜 사용하나?

위의 NFS 같이 쿠버네티스에서 지원하는 대부분의 볼륨타입은 포드나 디플로이먼트 YAML 파일에서 직접 정의해서 사용할 수 있다. 하지만 이런 방식을 사용하면 네트워크 볼륨으로서 NFS를 명시했으므로 다른 볼륨을 사용할 수 없게된다. 흔히 말하는 결합도가 높아지는 상황인 것이다. 이를 해결하기 위해 PV와 PVC를 사용한다.

PV(Persistent Volume)PVC(Persistent Volume Claim) 은 포드(yaml)가 세부적인 사항을 몰라도 볼륨을 사용할 수 있도록 추상화해주는 역할을 담당한다.

Pod <-> PVC(개발자) <-> PV(인프라관리자) <-> 네트워크 볼륨 의 모양이라고 생각하면 쉽다.

1
2
3
1) 인프라 관리자는 네트워크 볼륨의 정보를 이용해 PV 리소스를 미리 생성해 둔다.
2) 사용자는 포드 yaml에는 외부볼륨이 필요하다는 PV claim을 명시하고, 생성한다.
3) 쿠버네티스는 미리 만들어둔 PV 리소스와 PVC가 요구한 사항이 일치하면 매칭(bind) 시켜준다. 

PV, PVC 사용하기 (AWS EBS활용)

핵심은 외부 네트워크 볼륨을 쿠버네티스에 등록하고, 어플리케이션을 배포하려는 사용자(개발자) 입장에서 PVC를 사용해보는 것이다.

1) AWS에서 EBS(Elastic Block Stroe) 생성
이때 주의할 점은 EBS의 가용영역과 리전은 쿠버네티스 워커노드와 동일한 곳에 있어야 한다는 것이다!

1
2
3
4
5
6
7
8
9
10
export VOLUME_ID=$(aws ec2 create-volume --size 5 \
--region ap-northeast-2 \
--availability-zone ap-northeast-2a \ 
--volume-type gp2 \
--tag-specifications \
'ResourceType=volume,Tags=[{Key=KubernetesCluster,Value=mycluster.k8s.local}]' \
| jq '.VolumeId' -r)

echo VOLUME_ID

2) EBS 볼륨으로 쿠버네티스 PV(Persistent Volume) 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: PersistentVolume
metadate:
  name: ebs-pv
spec:
  capacity:
    storage: 5Gi # 볼륨의 크기는 5G
  accessModels:
    - ReadWriteOnce # 하나의 포드(인스턴스)에 의해서만 마운트 가능
  awsElasticBlockStore: # EBS 마운트를 위한 항목정의
    fsType: ext4
    volumeID: <VOLUME_ID>

1
2
3
cat ebs-pv.yaml | sed "s/<VOLUME_ID>/$VOLUME_ID/g" | kubectl apply -f -

kubectl get pv # 생성된 pv 확인

3) 개발자 입장(사용자)에서 PVC(Persistent Volume Claim)생성 후 포드에 사용명시 여기서 PVC의 accessMode와 resources는 볼륨의 요구사항으로 해당조건을 만족하는 PV와 연결되어야 한다는 것을 의미한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-ebs-pvc # 1. pvc 생성
spec:
  storageClassName: " "
  accessModes:
    - ReadWriteOnce # 2-1. RWO인 PV와 연결
  resources:
    requests:
      storage: 5Gi # 2-2. 볼륨 크기가 최소 5G인 PV와 연결
---
apiVersion: v1
kind: Pod
metadata:
  - name: ebs-mount-container
spec:
  containers:
    - name: ebs-mount-container
      image: busybox
      args: ["tail", "-f", "/dev/null"]
      volumeMounts:
      - name: ebs-volume
        mountPath: /mnt
  volumes:
  - name: ebs-volume
    persistentVolumeClaim:
      claimName: my-ebs-pvc # 3. my-ebs-pvc라는 이름의 pvc를 사용
This post is licensed under CC BY 4.0 by the author.