Kubernetes 스토리지 볼륨 - EmptyDir, HostPath, PV

이숭늉·2025년 5월 30일
0

DevOps

목록 보기
13/19
post-thumbnail

🗄️ 쿠버네티스 스토리지 볼륨 - emptyDir, HostPath, PV

이번 글에서는 쿠버네티스 스토리지 볼륨의 세 가지 유형인 emptyDir, HostPath, PersistentVolume(PV)에 대해 알아보고 간단한 실습까지 진행해볼 것이다.

스토리지 볼륨

쿠버네티에서 컨테이너는 기본적으로 비영속적이다. 파드가 삭제되거나 재실행되면 기존 컨테이너 내부의 파일 시스템도 초기화된다. 즉, 컨테이너 안에서 생성한 파일은 파드의 생명주기와 함께 사라지는 일시적 저장소이다.
따라서, 쿠버네티스에서는 이러한 문제점을 해결하기 위해 파드 외부와 데이터를 공유하거나 데이터를 보다 오래 유지할 수 있도록 볼륨(Volume)이라는 개념을 제공한다. 볼륨은 크게 다음과 같은 방식으로 제공될 수 있다.

  • 파드가 실행 중인 노드 내부의 디스크 일부를 활용 (ex: emptyDir, hostPath)
  • 외부 스토리지 시스템과 연동 (ex: PersistentVolume)

볼륨 유형

쿠버네티스 볼륨은 크게 EmptyDir, HostPath, PV로 나뉘어진다.

1️⃣ EmptyDir

  • 파드 생명주기 동안 임시로 사용하는 디스크

  • 파드가 노드에 최초로 할당될 때, 노드의 로컬 디스크에 빈 디렉터리를 생성한다.

  • 해당 볼륨은 파드가 살아있는 동안만 존재하며, 파드가 삭제되면 함께 사라진다.

  • 동일한 파드 내부의 여러 컨테이너가 데이터를 공유할 수 있다.

  • 디렉터리는 대개 노드의 다음 경로에 생성된다 :
    /var/lib/kubelet/pods/<pod-id>/volumes/kubernetes.io~empty-dir/<volume-name>

  • 사용 예시 : 컨테이너 간에 로그 공유, 임시 캐시 데이터 저장

  • YAML 예시

    apiVersion: v1	
    kind: Pod
    metadata:
      name: nginx-volume-01	
    spec:	
      containers:	
      - name: nginx-01
        image: nginx:latest	
        volumeMounts:
        - name: empty-volume
          mountPath: /volume01
      volumes:
      - name: empty-volume
        emptyDir: {}
    

2️⃣ HostPath

  • 파드에 실행 중인 호스트 노드의 파일 시스템 경로(특정 디렉터리)를 직접 마운트한다.

  • 노드 내부 경로에 볼륨을 두므로, 동일한 노드에서 실행되는 파드 간에는 데이터를 공유할 수 있다.

  • 하지만 다음과 같은 이유로 Kubernetes 공식 문서에서는 hostPath 사용을 권장하지 않으며, 반드시 신뢰할 수 있는 환경에서만 제한적으로 사용할 것을 권고한다.

    • 노드 종속적 : 파드가 가른 노드로 이동하면 동일한 데이터에 접근할 수 없음.
    • 보안 위험 : 컨테이너가 노드의 파일 시스템을 직접 접근하므로 민감한 디렉터리에 접근할 수 있음.
  • 간단 실습

    # hostpath-volume.yaml
    apiVersion: v1	
    kind: Pod	
    metadata:
      name: nginx-volume-02		
    spec:	
      nodeSelector:	
        kubernetes.io/hostname: k8s-worker2
      containers:	
      - name: nginx-container-01	
        image: nginx:latest	
        volumeMounts:
        - name: hostpath-volume	
          mountPath: /volume02
      volumes:	
      - name: hostpath-volume	
        hostPath:	
          path: /home/ubuntu/host-volume
          type: DirectoryOrCreate
            
     kubectl apply -f hostpath-volume.yaml
     kubectl exec -it nginx-volume-02 -- /bin/bash
     cd volume02
     echo "hello world 01" > ./test01.txt
    
     exit
     # 노드 내부 디렉터리에서 test01.txt 확인 가능
     ssh k8s-worker2
     cd host-volume
     ls
    
     # 종료 후 다시 실행해도 test01.txt 확인 가능 
     kubectl delete -f volume-test02.yaml
     kubectl apply -f hostpath-volume.yaml
     kubectl exec -it nginx-volume-02 -- /bin/bash
     cd volume02

3️⃣ PersistentVolume(PV)

  • 클러스터 외부의 스토리지를 추상화한 객체로, AWS EBS, NFS 등 다양한 백엔드를 지원한다.

  • 파드가 외부 스토리지와 연결되기 위해서는 다음 리소스들이 필요하다.

    • PV : 관리자가 생성해 놓은 실제 스토리지 자원을 추상화한 쿠버네티스 리소스
    • PVC(Persistent Volume Claim) : 파드에서 요청하는 스토리지의 크기, 접근 방식 등의 요구사항 정의
  • 리소스 간 관계

    • PVC <-> PV : 1:1 바인딩(하나의 PVC는 하나의 PV에 바인딩)
    • PVC <-> Pod : N:1 가능 (하나의 Pod가 여러 PVC 참조 가능)
    • BUT 하나의 PVC를 여러 Pod가 동시에 사용하는지는 접근 모드(ReadWriteOnce, ReadWriteMany, ...)에 따라 달라진다.
  • 파드는 PVC를 통해 PV에 접근하므로, 스토리지 백엔드가 변경되더라도 PVC를 유지하면 어플리케이션 영향 최소화 가능

  • 간단 실습

    이 실습에서는 편의상 별도로 외부 스토리지를 사용하지 않고, 클러스터 내의 다른 워커 노드를 NFS 서버로 사용하였다.

    # pv.yaml
    apiVersion: v1	
    kind: PersistentVolume	
    metadata:
      name: pv-01	
    spec:	
      accessModes:	
      - ReadWriteOnce # 읽기/쓰기 권한이 있는 단일 파드에만 마운트 가능
      capacity:
        storage: 100Mi
      persistentVolumeReclaimPolicy: Retain	# PVC 삭제되더라도, PV 유지
      storageClassName: pv-test-01 # 이 PV를 사용할 PVC의 storageClassName과 일치해야 함
      nfs:
        server: 10.0.2.8
        path: /tmp/k8s-pv
    
    # pvc.yaml
    apiVersion: v1	
    kind: PersistentVolumeClaim	
    metadata:	
      name: pvc-01	
    spec:	
      accessModes:	
      - ReadWriteOnce
      resources:
        requests:	
          storage: 30Mi 
      storageClassName: pv-test-01
    
    # pod.yaml
    apiVersion: v1
    kind: Pod	
    metadata:	
      name: nginx-volume-03
    spec:	
      nodeSelector:	
        kubernetes.io/hostname: k8s-worker1
      containers:	
      - name: nginx-volume-container-01	
        image: nginx:latest	
        volumeMounts:
        - name: nfs-pv-01
          mountPath: /volume01	
      volumes:
      - name: nfs-pv-01	
        persistentVolumeClaim:
          claimName: pvc-01 # 볼륨은 pvc-01라는 pvc를 참조
    kubectl apply -f pv.yaml
    kubectl apply -f pvc.yaml
    kubectl apply -f pod.yaml
    
    kubectl exect -it nginx-volume-03 -- /bin/bash
    cd volume01
    echo "hello nfs pv" > ./test02.txt
    exit
    
    # 마운트한 nfs 서버에서 text02.txt 확인 가능
    ssh k8s-worker2
    cd /tmp/k8s-pv
    ls
    exit
    
    # 삭제 후에도 nfs 서버에서 test02.txt 확인 가능
    # pv를 삭제해도 그저 k8s 리소스만 삭제되는 것이며, 
    # nfs는 k8s 외부 시스템이므로 k8s는 이를 삭제할 권한도 능력도 없음.
    kubectl delete -f pod.yaml
    kubectl delete -f pvc.yaml
    kubectl delete -f pv.yaml
    
    ssh k8s-worker2
    cd /tmp/k8s-pv
    ls

이번 글에서는 쿠버네티스 볼륨의 세 가지 유형인 emptyDir, hostPath, 그리고 PersistentVolume 대해 알아보았다. 이번 글을 마지막으로 쿠버네티스 리소스에 대한 글을 마치겠다.

profile
부지런히 살자

0개의 댓글