
쿠버네티스에서 스토리지는 크게 두 축으로 나뉜다.
이 둘이 어떻게 다른지, 그리고 실제 예제까지 한 번에 정리.
쿠버네티스에서 Volume은 컨테이너가 데이터를 읽고 쓸 수 있는 저장 공간을 말한다.
emptyDir, configMap, secret 등그중 emptyDir은 가장 단순한 형태의 볼륨이다.
Pod가 생성될 때 비어 있는 디렉터리로 시작
Pod가 삭제되면 그 안의 데이터도 같이 삭제
주로
상황
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로 동시에 마운트된다.
# 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
→ emptyDir는 Pod 생명주기와 함께 사라지는 임시 저장소라는 점이 핵심.
PersistentVolume(PV)
클러스터 수준에서 관리되는 실제 스토리지 자원
(NFS, 호스트 디렉터리, 클라우드 디스크 등)
PersistentVolumeClaim(PVC)
애플리케이션(Pod)이 “스토리지 좀 달라”라고 요청하는 객체
용량, 접근 모드(ReadWriteOnce 등)를 명시
관계로 정리하면:
이 구조 덕분에 스토리지와 Pod의 라이프사이클이 분리된다.
호스트의 /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 → 노드의 로컬 디렉터리를 사용하는 방식(실습용에 적합)애플리케이션이 사용할 스토리지 요청.
# pvc-mysql.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-mysql
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
pv-mysql)와 자동 매칭(Binding)# 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
/var/lib/mysql 경로가 PVC에 연결/mnt/mysql-data (호스트 디렉터리)에 실제로 저장# 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;
testdb와 test 테이블, 데이터가 그대로 남아 있다→ Pod 수명과 상관없이 데이터가 유지되는 영속 스토리지를 제공하는 구조.
마지막으로 한 번에 정리하면:
Volume
emptyDir는 Pod가 삭제되면 데이터도 같이 사라지는 타입PersistentVolume(PV)
PersistentVolumeClaim(PVC)
쿠버네티스에서 일시적인 데이터는 Volume(emptyDir)로,
절대 사라지면 안 되는 데이터(DB 등)는 PV + PVC 조합으로 다루는 것이 기본 패턴이다.