Kubernetes 볼륨 완벽 가이드 - 개발자 관점
📚 개요
“평범한” hostPath 실습에서 시작해서 “복잡한” PV/PVC/StorageClass까지, 쿠버네티스 스토리지의 진화 과정을 개발자 관점에서 분석합니다.
🎯 왜 볼륨이 필요한가?
컨테이너의 본질적 한계
컨테이너 = 임시적(Ephemeral)
├─ 컨테이너 재시작 → 데이터 손실 💥
├─ Pod 재스케줄링 → 데이터 손실 💥
└─ 업데이트/롤백 → 데이터 손실 💥
애플리케이션의 데이터 지속성 요구사항
- 데이터베이스: 데이터 영구 보존
- 로그 파일: 분석 및 모니터링
- 캐시: 성능 최적화
- 설정 파일: 외부 주입
📈 스토리지 진화 단계
Level 1: hostPath (오늘의 실습 수준)
# 장점: 간단함, 직관적
# 단점: 노드 종속성, 확장성 한계
volumes:
- name: host-logs
hostPath:
path: /var/log
type: Directory사용 시기:
- 개발/테스트 환경
- 로그 수집 (DaemonSet과 조합)
- 노드별 고유 데이터 접근
Level 2: PV/PVC (내일의 학습 목표)
# 장점: 추상화, 포터빌리티
# 단점: 수동 관리, 복잡성
kind: PersistentVolumeClaim
metadata:
name: app-data
spec:
resources:
requests:
storage: 10Gi혁신점:
- Infrastructure as Code 완성
- 환경별 동일한 YAML 사용
- 개발↔운영 환경 일관성
Level 3: StorageClass + Dynamic Provisioning (고급)
# 장점: 완전 자동화, 클라우드 네이티브
# 복잡성: CSI 드라이버, 클라우드 API
kind: StorageClass
metadata:
name: fast-ssd
provisioner: ebs.csi.aws.com
parameters:
type: gp3
iopsPerGB: "50"게임 체인저:
- 서비스형 스토리지 (Storage as a Service)
- 개발자는 요구사항만 명시
- 플랫폼이 구체적 구현 처리
🔧 실무 관점: 스토리지 패턴 분석
패턴 1: 사이드카 로깅 (emptyDir)
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: logs
mountPath: /var/log/nginx
- name: log-shipper # 사이드카
image: fluentd
volumeMounts:
- name: logs
mountPath: /var/log/nginx
volumes:
- name: logs
emptyDir: {} # Pod 내부에서만 공유언제 사용?
- 동일 Pod 내 컨테이너 간 데이터 공유
- 임시 파일, 캐시 데이터
- 컨테이너 재시작 시 데이터 초기화 원함
패턴 2: 설정/시크릿 통합 (Projected Volume)
volumes:
- name: config-and-secrets
projected:
sources:
- configMap:
name: app-config
- secret:
name: db-credentials
- serviceAccountToken:
path: token
expirationSeconds: 3600혁신적인 이유:
- 여러 소스를 하나의 디렉터리로 통합
- 실시간 업데이트 (60초 주기)
- 복잡한 마운트 구조 단순화
패턴 3: 데이터베이스 클러스터 (StatefulSet + volumeClaimTemplates)
spec:
serviceName: mysql
replicas: 3
volumeClaimTemplates:
- metadata:
name: data
spec:
storageClassName: fast-ssd
resources:
requests:
storage: 10Gi실행 결과:
mysql-0 → data-mysql-0 → 독립적인 10GB 디스크
mysql-1 → data-mysql-1 → 독립적인 10GB 디스크
mysql-2 → data-mysql-2 → 독립적인 10GB 디스크
개발자 가치:
- 진짜 분산 데이터베이스 구현
- 데이터 격리 자동 보장
- 스케일링 시 데이터 일관성 유지
🚀 내일 학습할 핵심 포인트
1. PV/PVC의 진짜 의미
개발자 관점: "내가 스토리지 구현 몰라도 됨"
운영자 관점: "개발자가 인프라 몰라도 됨"
플랫폼 관점: "추상화를 통한 확장성"
2. AccessModes의 현실적 선택
| Mode | 설명 | 실제 사용 사례 | 지원 스토리지 |
|---|---|---|---|
| RWO | 한 노드만 읽기/쓰기 | 데이터베이스, 앱 데이터 | 거의 모든 스토리지 |
| RWX | 여러 노드 읽기/쓰기 | 공유 파일시스템, 미디어 | NFS, CephFS, EFS |
| ROX | 여러 노드 읽기만 | 설정파일, 정적 자산 | 대부분 스토리지 |
3. 동적 프로비저닝의 마법
# 개발자가 작성하는 것
apiVersion: v1
kind: PersistentVolumeClaim
spec:
storageClassName: "fast-ssd" # 요구사항만 명시
resources:
requests:
storage: 10Gi
# 플랫폼이 자동으로 하는 일
# 1. AWS EBS gp3 10GB 볼륨 생성
# 2. PV 객체 자동 생성
# 3. PVC-PV 자동 바인딩
# 4. Pod 스케줄링 시 볼륨 어태치4. volumeBindingMode의 숨겨진 중요성
# WaitForFirstConsumer (AWS EBS 기본값)
volumeBindingMode: WaitForFirstConsumer
# 의미: Pod 스케줄링 후 해당 AZ에 볼륨 생성
# Immediate (NFS 등)
volumeBindingMode: Immediate
# 의미: PVC 생성 즉시 PV 생성왜 중요한가?
문제 상황 (Immediate):
PVC 생성 → us-east-1a에 EBS 생성
Pod 생성 → us-east-1b 노드에 스케줄됨
결과 → FailedAttachVolume (다른 AZ라서 어태치 불가)
해결 (WaitForFirstConsumer):
Pod 스케줄링 → us-east-1b 노드 선택됨
PV 생성 → us-east-1b에 EBS 생성
결과 → 성공적 어태치 ✅
🛠 실무 트러블슈팅 시나리오
문제 1: PVC가 Pending 상태
$ kubectl get pvc
NAME STATUS VOLUME STORAGECLASS
app-data Pending - fast-ssd
$ kubectl describe pvc app-data
Events:
Warning ProvisioningFailed no volume plugin matched해결 플로우:
1. StorageClass 존재 확인
→ kubectl get sc fast-ssd
2. CSI 드라이버 설치 확인
→ kubectl get pods -n kube-system | grep csi
3. volumeBindingMode 확인
→ WaitForFirstConsumer라면 Pod 생성 필요
문제 2: 다중 노드에서 동시 접근 실패
# 문제가 되는 설정
spec:
accessModes:
- ReadWriteOnce # 한 노드에서만 접근 가능
# Deployment replicas: 3 (여러 노드에 분산)
# 결과: 2개 Pod가 Pending 상태해결책:
# Option 1: ReadWriteMany 사용 (NFS 필요)
spec:
accessModes:
- ReadWriteMany
# Option 2: StatefulSet으로 변경 (각자 PVC)
kind: StatefulSet
spec:
volumeClaimTemplates: ...📊 스토리지 선택 가이드
| 사용 사례 | 추천 볼륨 타입 | 이유 |
|---|---|---|
| 임시 빌드 공간 | Generic Ephemeral | 동적 생성, 자동 정리 |
| 로그 수집 | emptyDir + 사이드카 | Pod 내 공유, 단순함 |
| 설정 통합 | Projected Volume | 여러 소스 통합, 실시간 업데이트 |
| 데이터베이스 | PVC + StatefulSet | 영구 보존, 데이터 격리 |
| 공유 파일 | PVC (RWX) + NFS | 다중 접근, 일관성 |
| 정적 자산 | PVC (ROX) | 읽기 전용 공유 |
💡 모던 쿠버네티스 스토리지 트렌드
1. CSI 생태계 확장
- AWS EFS CSI: 관리형 NFS 서비스
- Secrets Store CSI: 외부 시크릿 저장소 연동
- Local Path Provisioner: 로컬 스토리지 동적 프로비저닝
2. 스토리지 정책 자동화
# VolumeSnapshot: 백업 자동화
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: daily-backup
spec:
source:
persistentVolumeClaimName: app-data3. 멀티 클러스터 스토리지
- Rook-Ceph: 분산 스토리지 오케스트레이션
- Portworx: 엔터프라이즈 스토리지 플랫폼
🎯 학습 로드맵
기초 → 중급
- emptyDir, hostPath 마스터
- PV/PVC 개념 이해
- StorageClass 동적 프로비저닝
- StatefulSet 패턴 활용
중급 → 고급
- CSI 드라이버 커스터마이징
- VolumeSnapshot 백업 전략
- 스토리지 모니터링 및 최적화
- 멀티 클러스터 스토리지 관리
📝 핵심 요약
개발자 관점의 가치
hostPath: "간단하지만 환경 종속적"
PV/PVC: "추상화로 환경 독립성 확보"
StorageClass: "완전 자동화로 운영 효율성"
StatefulSet: "상태 유지 앱의 완벽한 해답"
내일 학습할 때 주목할 점
- PV/PVC는 단순한 볼륨이 아닌 “인프라 추상화 레이어”
- StorageClass는 **“Storage as a Service”**의 구현체
- volumeClaimTemplates는 **“데이터 격리 자동화”**의 핵심
기억할 것: 복잡해 보이는 PV/PVC/StorageClass는 결국 개발자의 삶을 단순하게 만들기 위한 추상화입니다. 한 번 이해하면 모든 클라우드에서 동일하게 사용할 수 있는 강력한 도구가 됩니다.
작성일: 2025-11-17
실습 기반: hostPath → PV/PVC/StorageClass 진화 과정