본문 바로가기
IT/Kubernetes

[Kubernetes] Storage - PersistentVolume

by 물통꿀꿀이 2019. 4. 21.

이전 포스팅에서는 Volume의 emptyDir과 hostPath에 대해 알아보았다.

(https://timewizhan.tistory.com/entry/Kubernetes-Volume?category=1035066)

그리고 이번 포스팅은 지난 번을 이어서 PersistentVolume에 대해 알아보려고 한다.


PersistentVolume (PV)

PersistentVolume은 기존에 알아보았던 Volume과는 개념적으로 조금 다르다. (물론 이름이 Persistent 이기 때문에 영구적이라고 생각할 수 있겠지만 일반적인 Volume* 타입에서도 영구적으로 Volume을 만들 수 있다.)

* 매니페스트 파일에서 kind가 PersistentVolume 타입이 아닌 것

일반적인 Volume은 Volume을 생성하기 위해서는 mount 대상의 spec을 알아야 한다. 즉 Pod의 각 Container에서 Volume Target을 정의해야 한다. 

한 가지 예를 들어보면,


volumes:

 - name: mongodb-data

    nfs:

     server: 123.123.123.123

     path: /apple/banana 

위에 정의된 매니페스트 파일은 NFS Volume를 정의하였다. 그런데 NFS을 Volume으로 mount 하기 위해서는 서버의 IP 및 경로까지 알고 있어야 한다. 이와 같이 일반적인 Volume은 Target 에 대한 관련 정보를 알고 있어야 mount가 가능하다. 이러한 불편함(?) 해결하기 위해 등장한 Volume 타입이 PersistenVolume이다. 


PersistentVolume은 미리 필요한 Storage를 k8s에 요청하여 영구적인(Persistent) Storage를 만든다. 즉, k8s에서 만들어준 Storage을 가져와서 사용한다. (추상화된 Storage 인터페스를 제공하기 때문에 Volume의 상세 spec을 알 필요가 없다.)

그림 1. Persistent Volume


그림 1을 보고 다시 이해를 해보면, k8s는 개념적으로 관리자와 개발자라는 2가지 관점을 가지고 있다. 관리자의 역할은 k8s의 인프라를 및 Master Node를 관리한다. 반면에 개발자는 Container Application과 같이 비즈니스 로직을 개발*한다. (물론 DevOps의 등장으로 관리자와 개발자의 역할이 모호 할 수도 있긴 하지만 이 부분은 범위를 넘어가는 것이니 논외로 한다.)

*개략적으로 구분 하는 것이지 명확히 두 역할을 구분 하는 것은 아니다.

위에서 언급한 것처럼 k8s에 Storage를 요청한다는 것은 관리자에게 해당 Cluster에 Storage를 만들어달라는 것이다. (일반 Volume은 개발자가 만든 것이다.) 생성된 이후에 개발자가 만든 Container 로직에서 접근 할 수 있도록 한다.


 apiVersion: v1

kind: PersistentVolume

metadata:

  name: mongodb-pv

spec:

  capacity:

    storage: 1Gi // 크기 정의

  accessModes:

    - ReadWriteOnce // 단일 클라이언트가 Read & Write

    - ReadOnlyMany // 여러 클라이언트가 Read

  persistentVolumeReclaimPolicy: Retain

  hostPath:

    path: /tmp/mongodb // mount 경로

해당 매니페스트 파일은 PersistentVolume을 만드는 정의이다. (관리자가 만드는 Storage) 해당 파일에서 볼 수 있듯이 PersistentVolume을 생성 할 때 여러 리소스 및 권한 등을 미리 정의한다. 그리고 해당 파일을 실행하면 k8s에서 아래와 같은 결과를 확인 할 수 있다.


특히 속성 중에 Reclaim Policy를 살펴보면


그림 2. k8s Persistent Volume


PersistentVolumeClaim (PVC)

관리자에 의해 영구적인 Volume이 생성되었다면 각 Container에서는 생성된 Volume을 사용해야 한다. 이를 위해 필요한 것이 PersistentVolumeClaim이다.

그림 3. PersistentVolumeClaim


그림 3에서 확인 할 수 있듯이 순차적으로 따라가보면, 관리자에 의해 PersistentVolume이 생성되고 생성된 Volume을 개발자(사용자)가 PersistentVolumeClaim을 통해 사용한다 그런데 PersistentVolume은 일반 Volume과 같이 Pod 매니페스트 정의를 통해 사용 할 수 없다. 즉, 따로 정의를 해야한다.


apiVersion: v1

kind: PersistentVolumeClaim

metadata:

  name: mongodb-pvc // Pod에서 Volume 지정할 떄 사용

spec:

  resources:

    requests:

      storage: 1Gi

  accessModes:

  - ReadWriteOnce

  storageClassName: "" 

위와 같이 매니페스트 파일을 통해 PersistentVolueClaim을 정의하면 아래와 같이 결과값을 확인 할 수 있다.


그림 4. k8s PersistentVolumeClaim


이렇듯 그림 4를 보면 PersistentVolumeClaim이 생성된 것을 확인 할 수 있다. 그런데 전에도 설명해듯이 PersistentVolumeClaim은 생성된 PersistentVolume을 사용하기 위한 리소스이다. 따라서 PersistentVolume을 확인해보면 상태가 바뀐 것을 확인 할 수 있다.

그림 5. PersistentVolumeClaim


그림 5를 면밀히 살펴보면 Status가 Available -> Bound로 바뀌었고 Claim에 값이 추가 된 것을 확인 할 수 있다. (내부 자세한 것은 뒤에 알아보겠다.)

이렇게 만들어진 PersistentVolume 및 PersistentVolumeClaim륿 바탕으로 Pod에서 사용하면 아래와 같은 매니페스트 정의가 필요하다.


apiVersion: v1

kind: Pod

metadata:

  name: mongodb

spec:

  containers:

  - image: mongo

    name: mongodb

    ...

  volumes:

  - name: mongodb-data

    persistentVolumeClaim:

      claimName: mongodb-pvc 

일반적인 Pod의 매니페스트 파일로 Volume 타입이 PersistentVolumeClaim이다. 즉, PersistentVolumeClaim의해 연결된 PersistentVolume을 Pod의 Volume으로 사용하는 것이다. Pod를 실행하고 실제 결과를 확인해보면 아래와 같다.

그림 6. Pod Volume


그럼 Pod - PersistentVolumeClaim - PersistentVolume이 정상적으로 연결되었는지 확인하기 위해 Pod에서 생성된 Container에 들어가서 확인해보면.

그림 7. Pod Execute


(mongodb 명령어를 잘 모르는 관계로..) 그림 7을 확인해보면 DB에 값을 Write & Read 하는 것을 알 수 있다. (Volume이 연결되었다는 의미)


추가로, 그림 5에서 살펴보았던 PersistentVolume의 Claim을 확인해보면 default/mongodb-pvc라고 되어 있다. 해당 포맷은 {namespace}/{pvc name}의 형태로 구성되는데 그 이유는 PersistentVolumeClaim이 namespace에 속하는 리소스이기 때문이다. 

그림 8. Namespace

(불필요하게 책을 캡처했지만.. 이것만큼 잘 그려져있는 이미지를 찾을 수 없어..) 그림 8을 보면 Node와 PersistentVolume은 namespace에 속하는 리소스가 아니다. 그렇지만 PersistentVolumeClaim과 Pod는 namespace에 속할 수 있다. 따라서 PersistentVolumeClaim에 namespace를 지정하지 않으면 Pod와 같이 default namespace에 속하게 된다.


Reference

https://thenewstack.io/strategies-running-stateful-applications-kubernetes-persistent-volumes-claims/

https://github.com/luksa/kubernetes-in-action/

https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistent-volumes

https://sites.google.com/site/edxkubernetes/kubernetes-volume

https://github.com/luksa/kubernetes-in-action

https://keithtenzer.com/2015/08/20/openshift-v3-unlocking-the-power-of-persistent-storage/

'IT > Kubernetes' 카테고리의 다른 글

[Kubernetes] Liveness & Readiness Probe  (0) 2019.04.26
[Kubernetes] Storage - StorageClass  (0) 2019.04.21
[Kubernetes] Storage - Volume  (0) 2019.04.21
[Kubernetes] Logging  (0) 2019.04.10
[Kubernetes] Monitoring  (0) 2019.04.10

댓글