[Kubernetes] Volume (PV, PVC)

배창민·2025년 12월 4일
post-thumbnail

쿠버네티스 Volume, PV, PVC 핵심 정리

쿠버네티스에서 스토리지는 크게 두 축으로 나뉜다.

  • Pod 라이프사이클에 묶인 일시적인 Volume
  • 클러스터 단위로 관리되는 PersistentVolume / PersistentVolumeClaim

이 둘이 어떻게 다른지, 그리고 실제 예제까지 한 번에 정리.


1. Volume 개념과 emptyDir 예제

1-1. Volume이란

쿠버네티스에서 Volume은 컨테이너가 데이터를 읽고 쓸 수 있는 저장 공간을 말한다.

  • 기본적으로 Pod 안에서 여러 컨테이너가 데이터를 공유할 때 사용
  • Pod가 재시작해도 볼륨 내용이 유지될 수 있지만
    Pod 자체가 삭제되면 볼륨도 함께 사라지는 타입이 많다
  • 대표적인 예: emptyDir, configMap, secret

그중 emptyDir은 가장 단순한 형태의 볼륨이다.

  • Pod가 생성될 때 비어 있는 디렉터리로 시작

  • Pod가 삭제되면 그 안의 데이터도 같이 삭제

  • 주로

    • 컨테이너 간 임시 데이터 공유
    • 로그 파일 공유
    • 임시 작업 디렉터리
      에 사용

1-2. emptyDir + 사이드카 패턴 예제

상황

  • web-app 컨테이너: 로그를 /var/log/webapp.log에 계속 기록
  • log-monitor 컨테이너: 같은 파일을 실시간으로 모니터링
  • 두 컨테이너는 emptyDir 볼륨을 통해 /var/log를 공유
# log-collector.yml
apiVersion: v1
kind: Pod
metadata:
  name: log-collector
spec:
  containers:
  - name: web-app
    image: busybox
    command: ["sh", "-c", "while true; do echo $(date) Hello from web app >> /var/log/webapp.log; sleep 5; done"]
    volumeMounts:
    - name: logs
      mountPath: /var/log

  - name: log-monitor
    image: busybox
    command: ["sh", "-c", "tail -f /var/log/webapp.log"]
    volumeMounts:
    - name: logs
      mountPath: /var/log

  volumes:
  - name: logs
    emptyDir: {}

여기서 logs라는 이름의 emptyDir 볼륨이 두 컨테이너에 /var/log로 동시에 마운트된다.


1-3. 동작 확인 흐름

# Pod 생성
kubectl apply -f log-collector.yml

# log-monitor 컨테이너가 web-app 로그를 잘 읽는지 확인
kubectl logs log-collector -c log-monitor

# Pod 삭제
kubectl delete pod log-collector

# 다시 생성
kubectl apply -f log-collector.yml

# 다시 로그 확인
kubectl logs log-collector -c log-monitor
  • Pod를 삭제했다가 다시 만들면 emptyDir 볼륨도 새로 생성
  • 이전에 쌓였던 로그는 사라지고, 새 로그부터 기록되기 시작

emptyDir는 Pod 생명주기와 함께 사라지는 임시 저장소라는 점이 핵심.


2. PersistentVolume(PV) & PersistentVolumeClaim(PVC)

2-1. 개념 정리

  • PersistentVolume(PV)
    클러스터 수준에서 관리되는 실제 스토리지 자원
    (NFS, 호스트 디렉터리, 클라우드 디스크 등)

  • PersistentVolumeClaim(PVC)
    애플리케이션(Pod)이 “스토리지 좀 달라”라고 요청하는 객체
    용량, 접근 모드(ReadWriteOnce 등)를 명시

관계로 정리하면:

  • PV: “실제 하드디스크”
  • PVC: “이 정도 스펙의 디스크를 쓰고 싶다”는 요청서
  • Pod: PVC를 참조해서 스토리지를 사용

이 구조 덕분에 스토리지와 Pod의 라이프사이클이 분리된다.


2-2. MySQL용 PV/PVC 설정 예제

1) PersistentVolume 정의

호스트의 /mnt/mysql-data 디렉터리를 2Gi 크기의 PV로 제공하는 예제.

# pv-mysql.yml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-mysql
spec:
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/mysql-data"
  • storage: 2Gi → 2Gi 용량
  • ReadWriteOnce → 하나의 노드에서 읽기/쓰기 용도로 마운트 가능
  • hostPath → 노드의 로컬 디렉터리를 사용하는 방식(실습용에 적합)

2) PersistentVolumeClaim 정의

애플리케이션이 사용할 스토리지 요청.

# pvc-mysql.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-mysql
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
  • PVC가 2Gi를 요청하면
  • 조건에 맞는 PV(pv-mysql)와 자동 매칭(Binding)

3) MySQL Pod에서 PVC 사용

# mysql.yml
apiVersion: v1
kind: Pod
metadata:
  name: mysql
spec:
  containers:
  - name: mysql
    image: mysql:5.7
    env:
      - name: MYSQL_ROOT_PASSWORD
        value: "my-secret-pw"
    volumeMounts:
    - name: mysql-storage
      mountPath: /var/lib/mysql
  volumes:
  - name: mysql-storage
    persistentVolumeClaim:
      claimName: pvc-mysql
  • MySQL 컨테이너의 /var/lib/mysql 경로가 PVC에 연결
  • DB 파일은 /mnt/mysql-data (호스트 디렉터리)에 실제로 저장

2-3. 데이터 보존 테스트 흐름

# PV, PVC, MySQL Pod 생성
kubectl apply -f pv-mysql.yml
kubectl apply -f pvc-mysql.yml
kubectl apply -f mysql.yml

# MySQL 접속 후 데이터 생성
kubectl exec -it mysql -- mysql -u root -p
Enter password: my-secret-pw

mysql> CREATE DATABASE testdb;
mysql> USE testdb;
mysql> CREATE TABLE test (id INT, name VARCHAR(20));
mysql> INSERT INTO test VALUES (1, 'Kubernetes');
mysql> SELECT * FROM test;

# Pod 삭제
kubectl delete pod mysql

# 동일 설정으로 다시 생성
kubectl apply -f mysql.yml

# 다시 접속 후 데이터 확인
kubectl exec -it mysql -- mysql -u root -p
Enter password: my-secret-pw

mysql> USE testdb;
mysql> SELECT * FROM test;
  • MySQL Pod를 삭제해도, PV에 데이터가 남아 있기 때문에
  • 재생성 후에도 testdbtest 테이블, 데이터가 그대로 남아 있다

Pod 수명과 상관없이 데이터가 유지되는 영속 스토리지를 제공하는 구조.


3. 정리

마지막으로 한 번에 정리하면:

  1. Volume

    • Pod 내부에서 컨테이너 간 데이터 공유, 임시 저장소 역할
    • emptyDir는 Pod가 삭제되면 데이터도 같이 사라지는 타입
  2. PersistentVolume(PV)

    • 클러스터가 가진 실제 스토리지 자원
    • NFS, 클라우드 디스크, 호스트 디렉터리 등 다양하게 연결 가능
    • Pod와 독립적으로 존재
  3. PersistentVolumeClaim(PVC)

    • 애플리케이션이 “이만큼의 스토리지 필요”라고 요청하는 객체
    • PVC가 PV와 바인딩되면, Pod는 PVC를 통해 스토리지를 사용

쿠버네티스에서 일시적인 데이터Volume(emptyDir)로,
절대 사라지면 안 되는 데이터(DB 등)PV + PVC 조합으로 다루는 것이 기본 패턴이다.

profile
개발자 희망자

0개의 댓글