클라우드/Docker & Kubernetes

Managing Data & Volumes with k8s

mini'scloud 2025. 8. 8. 14:45

State

  • 애플리케이션에서 손실되어서는 안되는 생성되고 사용되는 데이터임

  • 컨테이너가 종류 후, 재시작할때도 존재해야하는 데이터가 있기에 volumes이 필요함

 

k8s & volumes

  • k8s는 컨테이너 안에 volumes를 mount할 수 있음
  • 다양한 종류의 볼륨 타입/드라이버를 지원함
    • 로컬(노드)에 있는 볼륨
    • 클라우드 공급자 전용 볼륨
  • 볼륨의 생명 주기는 Pod의 생명 주기에 따라 달라짐
    • 볼륨은 컨테이너가 재시작(또는 삭제)되어도 유지됨
    • pod가 삭제될때 volume도 삭제됨
  • k8s volumes vs docker volumes
  • k8s volumes 
    • 다양한 종류의 드라이버와 타입을 지원함
    • 볼륨이 반드시 영구적인 것은 아님 (pod삭제시)
    • 볼륨은 컨테이너가 재시작되거나 삭제되어도 그대로 유지됨
  • docker volumes
    • 사실상 드라이버나 타입을 별도로 지원하지 않음
    • 볼륨은 사용자가 직접 삭제하지 않으면 계속 남아 있음
    • 볼륨은 컨테이너가 재시작되거나 삭제되어도 그대로 유지됨

emptyDir Type

  • emptyDir Type volume은 가장 기본적인 임시 volume임
  • deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: story-deployment
spec: 
  replicas: 1
  selector:
    matchLabels:
      app: story
  template:
    metadata:
      labels:
        app: story
    spec:
      containers:
        - name: story
          image: devminii/kube-data-demo:1
          volumeMounts:
            - mountPath: /app/story
              name: story-volume
      volumes:
        - name: story-volume
          emptyDir: {}
  • volumes는 pod 단위에서 공유할 수 있는 저장소를 정의하는 곳
    • story-volume으로 volume을 생성했음
    • emptyDir을 통해 pod가 노드에서 생성시 임시 디렉토리를 형성함 (pod삭제시 당연히 없어짐)
    • 이 디렉토리를 여러 컨테이너가 공유해서 사용할 수 있음
    • 통 앱 실행 중 임시 파일 저장, 캐시, 임시 데이터 처리 등에 활용
  • volumeMounts는 컨테이너가 앞서 정의된 볼륨(story-volume)을 실제 경로로 연결해서 쓸 수 있게 하는 설정
    • name 부분에 내가 쓸 volume을 명시해주면됨
    • mountPath를 통해 컨테이너 내부에서 해당 경로로 접근하면 실제 pod의 volume 디렉토리를 가리킴

 

hostPath Type

  • hostPath type
    • pod가 올라가 있는 k8s 노드의 파일 시스템 상 실제 경로를 pod의 컨테이너 내부 경로에 직접 마운트하는 방식
    • 즉 /data (노드 경로)가 컨테이너 안의 /app/story에 직접 연결됨
  • deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: story-deployment
spec: 
  replicas: 2
  selector:
    matchLabels:
      app: story
  template:
    metadata:
      labels:
        app: story
    spec:
      containers:
        - name: story
          image: devminii/kube-data-demo:1
          volumeMounts:
            - mountPath: /app/story
              name: story-volume
      volumes:
        - name: story-volume
          hostPath:
            path: /data
            type: DirectoryOrCreate #/data 디렉토리가 없으면 새로 생성하라는 명령어
  • pod가 할당된 노드의 특정 파일 시스템 경로를 직접 파드에 마운트
  • pod를 삭제해도 그 노드의 해당 경로에 있던 데이터는 삭제되지 않고 남아 있음
  • 만약 pod가 다른 노드로 옮겨가면 그 노드의 동일 경로에 접근하게 되므로, 데이터가 "공유"되는 것이 아니라 실제로는 노드별로 별도 관리됨
  • 노드 로컬 파일에 직접 접근하거나, 파드가 삭제되어도 데이터를 보존해야 할 때 사용
    (ex: 로그 수집, 노드-파드간 파일 공유 등) 
  • 하지만 단일 노드에서만 좋지, 다중 노드에서는 사용 불가능함(공식문서 참고)

 

CSI Type(Container Storage Interface)

  • k8s를 포함한 다양한 컨테이너 오케스트레이션 플랫폼과 여러 스토리지 시스템(블록, 파일, 클라우드 스토리지 등) 사이를 연결하기 위한 표준화된 스토리지 인터페이스
    • 플러그인 표준화: 스토리지 공급자가 각 플랫폼마다 따로 드라이버를 구현할 필요 없이, 한 번 CSI 규격만 맞추면 여러 플랫폼에서 동일하게 동작할 수 있음
    • 확장성/유연성: k8s 내장 코드와 분리되어(out-of-tree), 새로운 스토리지 시스템이 등장해도 쿠버네티스 업그레이드 없이 드라이버만 따로 설치·업데이트할 수 있음
    • 스토리지 연동 작업 표준화: 볼륨 생성/삭제, 마운트/언마운트, 스냅샷 등 스토리지 볼륨의 생명주기 작업을 위한 표준 API(gRPC 프로토콜 기반)를 정의함
    • 동적 프로비저닝 지원: 파드 실행 시 자동으로 볼륨을 생성하거나, 자동 확장/반납 등 고도화된 스토리지 관리를 쉽게 구현할 수 있음

Persistent Volumes

  • 보통 pod가 파괴되면 volume역시 없어짐
  • 그래서 pod와 독립적인 volumes이 필요함

노드에서 완전히 독립적인 volume을 형성할 수 있음

Defining a Persistent Volume

host-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: host-pv
spec:
  capacity:
    storage: 4Gi
  volumeMode: Filesystem
  storageClassName: standard
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /data
    type: DirectoryOrCreate
# 우리는 단일 노드에서만 지금 실습을하기에 hostpath를 사용해서 함!!
# 멀티 노드에서는 hostpath불가임!!
  • storageClassName
    • 서로 다른 스토리지 백엔드(예: AWS EBS, GCE PD, NFS, 로컬 디스크 등)와 스토리지 공급자를 추상화한 개념
    • k8s 클러스터에는 여러 StorageClass가 있을 수 있으며, 기본 스토리지 클래스를 지정할 수 있음
    • 자동 프로비저닝 기능을 통해 PVC 요청 시 자동으로 PV를 생성하는 데 StorageClass가 중요한 역할
  •  ReadWriteOnce
    • 이 PV는 단 한개의 노드에서만 읽기/쓰기가 동시에 가능함
    • 즉, 하나의 노드에서 마운트된 pod들이 그 볼륨에 읽고 쓸 수 있음
      • 여러 노드에서 동시에 읽거나 쓸 수는 없음
  • ReadWriteMany
    • 여러 노드에서 동시에 읽기/쓰기 가능
    • 즉, 여러 노드의 파드들이 동시에 같은 볼륨을 마운트해서 데이터를 읽고 쓸 수 있음
  • ReadOnlyMany
    • 읽기만 가능

Persistent Volume Claim

  • PVC: 사용자가 클러스터 스토리지 요청을 하기 위한 리소스임
  • PVC는 "이런 크기와 접근 모드를 가진 스토리지를 내게 할당해 주세요"라고 신청하는 선언적 요청
  • k8s가 PVC 요청에 맞는 PV를 찾아서 bind해줌

host-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: host-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 4Gi
  volumeName: host-pv

 

이렇게 생성한 pvc를 쓰기위해 deployment.yaml의 volumes부분도 아래처럼 수정해줘야함

apiVersion: apps/v1
kind: Deployment
metadata:
  name: story-deployment
spec: 
  replicas: 2
  selector:
    matchLabels:
      app: story
  template:
    metadata:
      labels:
        app: story
    spec:
      containers:
        - name: story
          image: devminii/kube-data-demo:1
          volumeMounts:
            - mountPath: /app/story
              name: story-volume
      volumes:
        - name: story-volume
          persistentVolumeClaim:
            claimName: host-pvc

 

실행을 해보자

kubectl apply -f=host-pv.yaml
kubectl apply -f=host-pvc.yaml
kubectl apply -f=deployment.yaml

 

kubectl get pv

  • pod가 2개 생성되었고 pod각각에 볼륨을 가지고 있음
  • 그러나, 두 pod가 같은 PVC를 마운트하므로 같은 PersistentVolume을 참조하고 있음
  • 우리 실습에서는 단일 노드니깐 두 pod가 동시에 pv에 접근할 수 있음
  • 하지만, 멀티 노드에서
    • accessMode가 ReadWriteOnce이면, 한번에 한노드에서만 읽고 쓰므로
    • pod2개가 서로 다른 노드에 있으면 둘 다 연결을 할 수 없게됨

Normal Volumes vs Persistent Volumes

  • Normal Volumes
    • pod가 살아있으면 살아있고, 죽으면 죽음
    • 여러 pod에 데이터를 저장하려면 각 pod마다 볼륨을 따로 정의해야 하므로 관리가 불편함
  • Persistent Volumes
    • PV는 pod와는 독립적으로 클러스터 내에 미리 만들음
    • PVC를 만들어서 필요한 크기/용도를 요청하면, k8s가 적절한 PV를 연결해줌
    • 동일한 PV/PVC 조합을 여러 pod, 여러 상황에서 계속 사용할 수 있음
    • 데이터가 pod 삭제나 재시작에도 남아 있음

 

 

'클라우드 > Docker & Kubernetes' 카테고리의 다른 글

Virtualization  (0) 2025.08.19
k8s-Deployment (AWS EKS)  (0) 2025.08.11
k8s core concepts & setup (2)  (0) 2025.08.07
k8s Core Concepts & setup  (0) 2025.08.07
Kubernetes Concepts  (0) 2025.08.06