6. 쿠버네티스 볼륨
책/Kubernetes In Action

6. 쿠버네티스 볼륨

728x90
반응형

Kubernetes in Action 6장 읽고 정리한 내용만 기록.

6.1 Kubernetes Volume (볼륨)

  • 파드 내부에는 프로세스가 실행되며, 리소스를 공유하는 논리적 호스트와 유사하다.
  • 프로세스간에 디스크는 공유하지 않는다.
    • 파드 내부의 각 컨테이너는 컨테이너 이미지에서 제공되는 고유한/분리된 FS를 가진다.
    • 즉, 컨테이너가 시작할 때마다 컨테이너 이미지를 빌드할 때 추가한 파일들을 갖는 컨테이너로 시작
      (새로 시작한 컨테이너는 기존 컨테이너와 다른 파일시스템 상태)

그렇다면 기존 컨테이너의 종료된 위치에서 새로운 컨테이너가 계속되길 원하는 시나리오가 있을 땐 어떻게 할까?

  • 스토리지 볼륨은 파드의 일부분으로 정의되어 파드와 동일한 라이프사이클을 가짐
    • 따라서 파드가 시작되면 볼륨이 생성되고, 파드가 삭제되면 볼륨도 삭제된다.
    • 이 때문에 볼륨의 콘텐츠는 컨테이너를 다시 시작해도 지속되는 것이다.
  • 또한 파드가 여러 컨테이너를 가지는 경우, 모든 컨테이너가 볼륨을 공유할 수 있다.

Volume

볼륨은 파드의 구성 요소로 컨테이너와 동일하게 파드 스펙에 정의

  • 볼륨은 독립적인 쿠버네티스 오브젝트가 아님 (따라서 자체 생성/삭제 불가)
  • 볼륨은 파드의 모든 컨테이너에서 사용 가능
  • but, 접근하는 컨테이너에서 각각 마운트돼야한다.

볼륨의 동작을 보다 쉽게 이해하기 위해 어떤 파드에 Web Server, Content Agent, Log Rotator 기능을 하는 컨테이너 3개가 존재한다고 가정

  • Web Server는 /var/htdocs 디렉터리에 HTML 페이지를 서빙하고 /var/logs 에 액세스 로그를 기록.
  • Content Agent는 Web Server가 서빙할 HTML 파일을 /var/html 에 생성.
  • Log Rotator는 /var/logs 디렉터리의 로그를 처리합니다. 이 컨테이너들이 서로의 파일 시스템을 공유할 수 있게 다음과 같이 publicHTML, logVol 두 볼륨을 추가할 수 있다.

두 볼륨은 빈 상태로 초기화되므로 emptyDir 이란 유형의 볼륨을 사용할 수 있음.

  • 쿠버네티스에선 볼륨을 초기화하며 외부 소스의 내용을 채우거나,
    볼륨 내부에 기존에 존재하는 디렉터리를 마운트하는 것과 같은 다른 유형의 볼륨도 지원.
    볼륨을 채우거나 마운트하는 프로세스는 파드의 컨테이너가 시작되기 전에 수행된다.

 

사용 가능한 볼륨 목록

쿠버네티스의 볼륨 지원

  • emptyDir: 일시적인 데이터를 저장하는 데 사용되는 간단한 빈 디렉터리
  • hostPath: 워커 노드의 파일 시스템을 파드의 디렉터리로 마운트하는데 사용
  • nfs: NFS 공유 파드에 마운트
  • gcePersistentDisk(GCE Persistent Disk), awsElasticBlockStore(AWS EBS Volume), azureDist(MS Azure Disk Volume): 클라우드 제공자의 전용 스토리지를 마운트
  • cinder, cephfs, iscsi, glusterfs, quobyte, rbd, flexVolume, vsphereVolume, photonPersistentDisk: 다른 유형의 네트워크 스토리지를 마운트
  • configMap, secret, downwardAPI: 쿠버네티스 리소스나 클러스터 정보를 파드에 노출하는 데 사용되는 특별한 유형의 볼륨
  • persistentVolumeClaim: 사전에 혹은 동적으로 프로비저닝된 퍼시스턴트 스토리지를 사용하는 방법

이외 secret, downwardAPI, configMap 볼륨은 데이터 저장에 사용되지 않고 메타데이터를 파드에 실행 중인 어플리케이션에 노출하는데 사용된다.
또한 단일 파드는 동시에 여러 유형의 여러 볼륨 사용 가능하며, 파드의 각 컨테이너는 볼륨을 마운트 선택 가능

 

HostPath 볼륨

hostpath 볼륨 : 파드가 다시 떠도 동일한 볼륨을 마운트해서 계속 보고 있음 (node 의 hostpath 볼륨을 바라보고 있어서 그렇다)
- 보통 파드의 저장을 위해서 해당 hostPath 를 사용하진 않는다. 단지 노드 데이터에 접근하기 위해 사용할 뿐
- 따라서 노드의 시스템 파일에 읽기/쓰기를 위해 hostPath 볼륨을 사용한다.

  • emptyDir / gitRepo 의 경우에는 파드가 죽으면 볼륨 내 컨텐츠는 삭제된다.

 

6.4 퍼시스턴트 스토리지

 

NAS(Network-Attaced-Storage) : 모든 클러스터 노드도 접근 가능한 스토리지

  • 파드에서 실행중인 애플리케이션이 디스크에 데이터를 유지 혹은 파드가 다른 노드로 재스케줄링 되는 경우에도 동일한 데이터 사용이 필요할 때 사용하는 스토리지 (해당 경우는 앞단 hostPath 도 사용불가하다)

 

6.5 기반 스토리지 기술과 파드 분리

  • 앞서 설명한 모든 퍼시스턴트 볼륨 유형을 위해서는 파드 개발자가 실제 네트워크 스토리지 인프라에 관한 내용을 알고 있어야 하고,

NFS 기반 볼륨 생성은 NFS 익스포트가 위치하는 실제 서버를 알아야 함

  • 이것은 서비스 개발자가 인프라를 숨기는 쿠버네티스의 기본적 아이디어에 반대된다.
    인프라 관리는 쿠버네티스 클러스터 관리자만 알아야 한다.

 

6.5.1 퍼시스턴트 볼륨과 퍼시스턴트볼륨 클레임

  • 인프라 세부사항 처리 없이 애플리케이션이 k8s 클러스터에 스토리지 요청할 수 있도록 퍼시스턴트 볼륨(PV), 퍼시스턴트볼륨 클레임(PVC) 가 도입

클러스터 관리자가 퍼시스턴트 볼륨을 프로비저닝 → 사용자의 파드는 퍼시스턴트볼륨클레임(PVC가 PV 를 바인딩함)을 통해 이를 사용

단계적 절차

  1. k8s 관리자가 NFS 익스포트와 같은 네트워크 스토리지 유형 설정
  2. 관리자가 k8s API 에 PV 디스크립터를 게시해 PV 생성
  3. 사용자는 PVC 생성
  4. k8s 는 PV 를 찾아 PVC 를 PV에 바인딩
  5. 사용자는 PVC 를 참조하는 볼륨을 가진 파드 생성 (PVC 를 파드의 내부 볼륨으로 사용)

 

6.5.2 퍼시스턴트볼륨 생성

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-hostpath
spec:
  capacity:
    storage: 2Gi # 스토리지 용량 2GB
  volumeMode: Filesystem # 파일 시스템 형식
  accessModes: # 읽기/쓰기 옵션
  - ReadWriteOnce
    - ReadOnlyMany 
  storageClassName: manual
  persistentVolumeReclaimPolicy: Retain # PVC 해제된 후 PV 유지 
  hostPath:
    path: /tmp/k8s-pv # 스토리지를 연결할 Path

pv 조회

$ kubectl get pv
NAME         CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
mongodb-pv   1Gi        RWO,ROX        Retain           Available

Note: PVC는 네임스페이스에 속하지만, PV는 특정 네임스페이스에 속하지 않는다.

 

6.5.3 PVC 생성 및 PV 요청

  • 관리자가 아닌 개발자의 입장으로 바라봅시다. 퍼시스턴트 스토리지가 필요한 파드를 배포
  • 이전에 생성한 PV를 사용할 것인데, 직접 사용할 수 없고 클레임을 먼저 해야 합니다.
  • 이 때 파드가 재스케줄링 되더라도 동일한 PVC를 사용 가능한 상태로 유지되기를 원하므로 PV에 대한 클레임은 파드를 생성하는 것과 별개의 프로세스.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  # persistentVolumeClaim 의 이름으로 나중에 파드의 볼륨을 요청할 때 사용합니다
  name: mongodb-pvc
spec:
  resources:
    # 1GiB의 스토리지를 요청합니다
    requests:
      storage: 1Gi
  # 단일 클라이언트를 지원하는 스토리지로 읽기/쓰기를 모두 수행합니다
  accessModes:
    - ReadWriteOnce
  # 이 부분은 이후 동적 프로비저닝에서 설명 
  storageClassName: ''
  • 위 디스크립터를 API 서버에 게시하면 PVC가 생성되자마자 쿠버네티스는 적잘한 PV를 찾고 클레임에 바인딩 진행
  • PV의 용량은 PVC의 요청을 수용할 만큼 커야 하며 접근 모드는 PVC에서 요청한 접근 모드를 모두 포함하고 있어야 합니다.
  • 위의 경우 PVC가 요청한 1GiB 용량과 ReadWriteOnce 접근 모드를 PV가 모두 만족하므로 PV는 PVC에 바인딩
$ kubectl get pvc
NAME          STATUS   VOLUME       CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mongodb-pvc   Bound    mongodb-pv   1Gi        RWO,ROX                       3s

 

6.5.4 Pod 에서 PVC 사용

apiVersion: v1
kind: Pod
metadata:
  name: mongodb
spec:
  containers:
    - image: mongo
      name: mongodb
      volumeMounts:
        - name: mongodb-data
          mountPath: /data/db
      ports:
        - containerPort: 27017
          protocol: TCP
  volumes:
    - name: mongodb-data
      # 파드 볼륨에서 이름으로 PVC를 참조합니다
      persistentVolumeClaim:
        claimName: mongodb-pvc

6.5.5 PV 와 PVC 사용 장점

직접 퍼시스턴트 디스크 사용 vs PVC & PV 사용의 차이

  • 퍼시스턴트 스토리지를 직접 사용하는 것에 비해 PV와 PVC를 사용하는 것을 이를 생성하는 추가 절차가 필요
    but 개발자가 실제 스토리지 기술을 알 필요가 없음.
    동일한 파드와 클레임 매니페스트는 인프라와 관련된 어떤 것도 참조하지 않으므로 다른 쿠버네티스 클러스터에서 활용할 수 있다.

 

6.5.6 PV 재사용

앞서 PV 생성 시, persistentVolumeReclaimPolicy : Retain 으로 설정하였기 때문에 PVC 를 삭제하고 다시 생성하게 될 때는 자동으로 PV 에 바인딩 되지 않는다.

  • 이유는 이미 볼륨을 이전 PVC 에서 사용했기 때문에 데이터를 가지고 있고 관리자가 해당 볼륨을 완전히 비우지 않는다면, 동일한 PV 를 사용하는 파드는
    다른 네임스페이스에서 클레임과 파드가 생성되어도 이전 파드가 저장한 데이터를 읽을 수 있는 환경이다.
    따라서 Retain 인 경우 재사용의 유일한 방법은 해당 PV 의 리소스를 삭제하고 다시 생성하는 것 뿐이다.

만약 자동으로 다시 PVC 바인딩을 하고자 한다면, 리클레임 정책으로 RecycleDelete 로 지정해주면 된다.

 

6.6 퍼시스턴트볼륨의 동적 프로비저닝

앞서서 여전히 클러스터 관리자 입장에서는 실제 스토리지를 미리 프로비저닝 해야한다. 이를 위해 k8s 의 PV 는 동적 프로비저닝을 지원한다.

클러스터 관리자는 PV 생성 대신, PV 프로비저너를 배포하고 사용자가 선택 가능한 PV 타입을 하나 이상의 스토리지 클래스(이하 SC) 오브젝트로 정의하면
이후에 PVC 를 통해 요청할 떄 새로운 PV 를 생성하게 된다.

이에 대한 이점이 PV 가 부족할 일이 없음 (단, PV 생성으로 인해 스토리지 용량은 부족할 수 있음)

 

스토리지클래스 리소스를 통한 사용 가능한 스토리지 유형 정의

SC 리소스는 PVC 가 SC 요청시 어떤 프로비저너가 PV 를 프로비저닝 해야할지 지정해야함

  • SC 정의시 파라미터들이 프로비저너에 전달된다.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
# 퍼시스턴트볼륨 프로비저닝을 위해 사용되는 볼륨 플러그인
provisioner: kubernetes.io/gce-pd
# 파라미터가 프로비저너로 전달
parameters:
  type: pd-ssd
  zone: europe-west1-b

 

PVC 에서 SC 요청

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongodb-pvc
spec:
  resources:
    requests:
      storage: 100Mi
  accessModes:
    - ReadWriteOnce
  # PVC는 사용자 정의 스토리지 클래스를 요청힙니다("" -> fast)
  storageClassName: fast # SC에 정의한 metadata.name 
  • 앞서 작성한 fast SC를 생성하고 위 클레임을 생성하면 fast SC에 참조된 프로비저너가 PV를 생성.
  • 프로비저너는 수동으로 프로비저닝된 PV와 PVC를 매핑하는데도 사용된다.
  • storageClassName 속성을 지정하지 않고 PVC를 생성하면 standard 유형의 클래스가 디폴트로 선택됩니다.
  • storageClassName 를 맨 처음에는 "" 인 빈 문자열로 지정했었는데, 이 경우 PVC가 새로운 PV를 동적으로 프로비저닝하지 않고 미리 프로비저닝된 PV에 바인딩 되도록 강제할 수 있습니다(위에선 PVC와 PV의 연결을 보여주고자 이렇게 하였습니다).

PVC, PC, SC 를 통한 동적 프로비저닝 정리

 

6장 요약 

  • 볼륨을 파드에 추가하고 각 컨테이너에 마운트해 동일한 파일시스템을 참조할 수 있다
  • emptyDir 볼륨을 사용해 파드 내 임시, 비영구 데이터를 저장할 수 있다
  • hostPath 볼륨을 사용해 워커 노드의 파일시스템에 접근할 수 있다
  • 외부 스토리지를 볼륨에 마운트해 파드가 재시작 하더라도 파드의 데이터를 유지할 수 있다
  • 퍼시스턴트볼륨(PV)와 퍼시스턴트볼륨클레임(PVC)를 사용해 스토리지와 인프라를 분리할 수 있다
  • 각 PVC를 위해 PV를 원하는 스토리지 클래스(SC)로 동적으로 프로비저닝 할 수 있다
  • PVC를 미리 프로비저닝된 PV와 바인딩 하고자 할 때 동적 프로비저너가 간섭하는 것을 막을 수 있다
728x90
반응형

' > Kubernetes In Action' 카테고리의 다른 글

7. 컨피그맵(ConfigMap) 및 컨테이너 환경 변수  (3) 2024.01.07
5.5 Readiness Probe  (0) 2023.12.16
5.4 Ingress(인그레스)  (0) 2023.12.10