개발놀이터

쿠버네티스 이론 : 볼륨 (EmptyDir, HostPath, PV / PVC) 본문

배포/kubernetes

쿠버네티스 이론 : 볼륨 (EmptyDir, HostPath, PV / PVC)

마늘냄새폴폴 2024. 9. 2. 22:22

이번 포스팅은 쿠버네티스의 저장소 볼륨입니다. 파드가 컨테이너를 가지고 애플리케이션을 구동한다면 볼륨은 그 애플리케이션이 사용할 각종 파일들이나 정보들을 저장해놓는 공간입니다. 

 

파드, 서비스만 하더라도 굉장히 굵직한 기능이었는데 다른 기술이었으면 파드와 서비스로 실서비스를 할 수 있는 정도일겁니다. 그런데 쿠버네티스 이놈은 이런 오브젝트들이 수십개가 있습니다. 정말 미X놈이 아닐 수가 없습니다. 

 

이번 포스팅에선 그 중에서 볼륨에 대해서 공부하고 정리해보겠습니다. 

 

Volume (볼륨)

 

볼륨에는 EmptyDir, HostPath, PV / PVC 이렇게 세가지가 존재합니다. 하나씩 한번 살펴보도록 하겠습니다. 

 

EmptyDir

EmptyDir은 파드 안에서 각각의 컨테이너가 공통으로 바라보는 저장소로서 파드안에 생성되기 때문에 파드가 사라지면 데이터도 같이ㅏ 삭제된다는 특징이 있습니다. 

 

이렇게 파드안에 컨테이너가 같은 볼륨을 바라보는 경우 컨테이너끼리 특별히 다른 설정을 해주지 않아도 서로 파일을 주고 받을 수 있게 됩니다. 도커의 볼륨과 비슷하네요. 

 

파드가 사라지면 데이터도 같이 삭제되기 때문에 휘발성 데이터를 넣는 것이 일반적입니다. 

 

apiVersion: v1
kind: Pod
metadata:
  name: pod-volume-1
spec:
  containers:
  - name: container1
    image: tmkube/init
    volumeMounts:
    - name: empty-dir
      mountPath: /mount1
  - name: container2
    image: tmkube/init
    volumeMounts:
    - name: empty-dir
      mountPath: /mount2
  volumes:
  - name: empty-dir
    emptyDir: {}

 

위의 설정에서는 각각 컨테이너들이 다른 path를 바라보고 있는데 name이 empty-dir로 일치하기 때문에 실질적으로는 같은 저장소를 바라본다고 볼 수 있습니다. 

 

HostPath

HostPath는 파드별로 생성되던 EmptyDir과 다르게 노드마다 생성되는 볼륨입니다. 

 

파드별로 생성되는건 정없죠. 파드는 언제든지 삭제될 수 있으니까요. 조금 더 오래 유지되는 데이터를 저장하고 싶은 니즈가 있고 이를 HostPath로 실현할 수 있습니다. 

 

이렇게 노드별로 생성된 볼륨은 그 노드에 들어있는 파드가 사용할 수 있으며 이렇기 때문에 파드가 죽어도 사라지지 않는다는 특징이 있습니다. 

 

하지만 HostPath도 문제가 없는 것은 아닌 것이 노드스케줄러에 의해 파드가 재생성되고 노드에 재배치될 때 같은 노드에 재생성된다는 보장이 없습니다. 

 

때문에, HostPath는 노드가 구동되기위해 사요오디는 시스템 파일들을 저장해야하는 경우에 사용됩니다. 

 

주의해야 하는 점은 파드의 볼륨을 HostPath로 설정하는 경우 실제로 노드에 볼륨이 존재해야 파드를 생성할 수 있습니다. 

 

apiVersion: v1
kind: Pod
metadata:
  name: pod-volume-2
spec:
  containers:
  - name: container
    image: tmkube/init
    volumeMounts:
    - name: host-path
      mountPath: /mount1
  volumes:
  - name: host-path
    hostPath:
      path: /node-v
      type: Directory

 

위 설정처럼 파드를 생성할 때만약 hostPath설정을 주어 볼륨을 설정하면 host-path라는 볼륨이 존재해야 이 파드가 생성된다는 의미입니다. 

 

PVC / PV

PVC (Persistant Volume Claim)와 PV (Persistant Volume)는 파드가 영속적인 볼륨에 접근할 수 있도록 도와줍니다. 

 

볼륨의 종류는 로컬이 될 수도 있고 Git이 될 수도 있고 AWS, NFS등이 될 수도 있습니다. 

 

쿠버네티스 관리자는 PV를 만들고 사용자는 PVC를 만들어서 파드와 연결해서 사용해야합니다. 

 

그런데 왜 PV를 만들고 이를 곧바로 파드에 연결하지 않고 PVC를 통해서 연결하게 되는 것일까요? 

 

그 이유는 쿠버네티스는 모든 개념을 사용자의 관점과 관리자의 관점으로 나누어서 관리하고 있기 때문입니다. 때문에 볼륨 생성과 PV생성은 관리자, 파드 생성과 PVC생성은 사용자로 나눌 수 있습니다. 

 

apiVersion: v1
kind: PersistentVolume
meatadata:
  name: pv-01
spec:
  capacity:
    storage: 1G
    accessModes:
    - ReadWriteOnce
    local:
      path: /node-v
    modeAffinity:
      required:
        nodeSelectorTerms:
        - matchExpressions:
          - {key: node, operator: in, value: [node1]}

 

위의 PV설정은 로컬 스토리지를 사용하는 경우에 해당하는 설정입니다. 만약 AWS나 StorageOS와 같은 온프레미스 스토리지 솔루션을 사용한다면 다른 설정을 가질 수 있습니다. 추후에 실습을 할 때 한번 본격적으로 다뤄보도록 하겠습니다. 자세한 내용은 쿠버네티스 실습 : 볼륨 편에서 진행하도록 하겠습니다. 

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-01
spec:
  accessModes:
  - ReacWriteOnce
  resources:
    requests:
      storage: 1G
storageClassName: ""

 

위의 PVC 설정에서 눈여겨 봐야 할 것이 storageClassName을 "" 이렇게 빈칸으로 냅둔 것인데, 빈칸으로 냅두지 않으면 다르게 동작하기 때문입니다. 이에 대해서는 다음 섹션인 볼륨 (심화) 에서 다루도록 하겠습니다. 

 

apiVersion: v1
kind: Pod
metadata:
  name: pod-volume-3
spec:
  containers:
  - name: container
    mountPath: /volume
  volumes:
  - name: pvc-pv
    persistentVolumeClaim:
      claimName: pvc-01

 

이렇게 PVC와 PV를 만들고 파드에 이를 연결하면 영속적인 볼륨을 가질 수 있습니다. 

 

여기까지 볼륨에 대한 간단한 개요를 알아봤습니다. 이제 뒤이어 심화버전을 알아보도록 하겠습니다. 

 

볼륨 (심화)

볼륨 심화편을 들어가기에 앞서 볼륨에 대해서 간단하게 정리하고 넘어가겠습니다. 

 

볼륨이란?

볼륨은 EmptyDir, HostPath, PV / PVC 이렇게 세 가지 타입이 있습니다. 

 

EmptyDir은 파드에 한정된 볼륨입니다. 

 

HostPath는 노드에 한정된 볼륨이구요. 

 

때문에 우리는 PV / PVC를 많이 사용하게 됩니다. 

 

먼저 쿠버네티스 관리자가 PV를 만듭니다. PV를 만들 때 스토리지 용량과 AccessMode를 설정하고 PVC를 만들면 AccessMode에 맞는 PV를 선택해서 사용할 수 있습니다. 

 

AccessMode에는 ReadWriteOnce (RWO), ReadOnlyMany (ROM), ReadWriteMany (RWM) 이렇게 세 가지가 존재합니다. 이에 대해서는 자세히 짚고 넘어가지 않겠습니다. 그냥 읽기 쓰기에 대한 권한을 부여한다고 간단하게 짚고 넘어가겠습니다. 

 

하지만 이 대목에서 관리자가 PV가 필요할 때마다 PV를 만들어서 PVC와 연결해주기는 굉장히 번거롭습니다. 

 

이를 위해 쿠버네티스에선 Dynamic Provisioning이라는 기술이 볼륨을 동적으로 할당해줍니다. 

 

이 기능을 사용하면 PVC만 만들어주면 자동으로 PV를 할당해줍니다. 

 

이때 PV는 온프레미스 솔루션인 StorageOS일 수도 있고, NFS일 수도 있고, 클라우드 환경에 존재한느 스토리지일 수도 있습니다. 

 

그럼 쿠버네티스는 PVC만 만들었는데 어떻게 그에 걸맞는 PV를 자동으로 연결해줄 수 있는 것일까요? 바로 StorageClass라는 이름을 지어주면 됩니다. 우리가 위에서 잠깐 언급했던 그 StorageClass 맞습니다. 

 

만약 StorageClass를 fast라고 적어주고 PVC를 만들 때 스토리지 용량과 AccessMode, StorageClassName을 fast로 연결해주면 설정한 스토리지 용량과 AccessMode를 할당해주고 스토리지 클래스를 이용해서 PV를 이어줍니다. 

 

볼륨의 상태에서는, 정확히는 PV의 상태, Available, Bound, Released, Failed 이렇게 네 가지가 있습니다. 

 

PV가 생성되고 맨 처음에는 Available이라는 상태값을 가집니다. 이후 PVC가 생성되면 Bound상태가 됩니다. 이렇게 생성된 PVC에 파드가 연결되면 이 파드가 볼륨을 사용할 수 있게 됩니다. 

 

이 상황에서 만약 파드가 죽어버리더라도 PVC, PV가 살아있기 때문에 파드의 상태에 영향을 받지 않는 것입니다. 이 PV는 PVC가 없어져야 비로소 반응하게 되는데 이 때의 상태값이 다시 세개로 나누어집니다. 이때의 상태값을 ReclaimPolicy라고 합니다. 

 

  • Retain : StorageClass를 사용하지 않았을 때의 기본 정책이고 PVC가 삭제되더라도 데이터는 보존됩니다. 하지만 PVC가 삭제되더라도 PV로 삭제가 전파되지 않아 데이터는 보존되지만 다른 PVC를 연결해서 사용할 수는 없습니다. 

    Retain의 경우 PVC가 삭제되면 다른 PVC를 연결해서 사용할 수 없기 때문에 PV를 직접 생성했던 것과 마찬가지로 직접 PV를 삭제해줘야합니다. 
  • Delete : StorageClass를 사용할 때의 기본 정책이고 PVC가 삭제되면 PV가 같이 삭제됩니다. 때문에, 데이터가 보존되지 않고 재사용할 수도 없습니다. 
  • Recycle : 이 정책은 PVC가 삭제되면 PV는 데이터를 전부 지워버리고 다시 재사용 가능한 PV로 만들어버립니다. 

 

마치며

이번 포스팅에선 쿠버네티스의 볼륨에 대해서 알아봤습니다. 쿠버네티스를 공부하면 할수록 왜 이 기술이 표준이 되었는지 알게되었습니다. 오브젝트들 하나하나의 기능이 정말 강력하네요. 

 

다음 포스팅은 Authentication, Authorization입니다. 인증과 인가에 관련한 내용도 풍부하게 있으니 다음 포스팅에서 뵐게요! 긴 글 읽어주셔서 감사합니다. 오늘도 즐거운 하루 되세요!