Overview
Kubernetes에서 퍼시스턴트 스토리지(Persistent Storage)를 구성할 때 가장 먼저 마주하는 질문은 "어떤 스토리지 타입을 선택해야 할까?" 이다. NFS는 간단하지만 성능이 걱정되고, iSCSI는 빠르다지만 설정이 복잡해 보인다. 클라우드 환경이라면 또 다른 선택지들이 있다.
이 글에서는 Kubernetes 환경에서 사용되는 주요 스토리지 타입들의 특징과 장단점을 비교하고, 상황에 맞는 최적의 선택을 할 수 있도록 가이드를 제공한다. 실무 경험을 바탕으로 각 스토리지 타입이 어떤 워크로드에 적합한지 구체적인 사례와 함께 살펴보겠다.

1. 스토리지 타입의 기본 개념
블록 스토리지 (Block Storage) vs 파일 스토리지 (File Storage)
스토리지를 이해하려면 먼저 두 가지 근본적인 접근 방식을 알아야 한다.
블록 스토리지
- 데이터를 고정 크기의 블록으로 나누어 저장
- OS가 직접 파일 시스템을 관리
- 낮은 레이턴시와 높은 IOPS
- 예: iSCSI, Ceph RBD, AWS EBS
파일 스토리지
- 파일과 디렉토리 구조로 데이터 저장
- 네트워크를 통해 파일 시스템 공유
- 여러 클라이언트가 동시 접근 가능
- 예: NFS, SMB/CIFS
2. NFS (Network File System)
특징
NFS는 1984년 Sun Microsystems가 개발한 분산 파일 시스템 프로토콜이다. 네트워크를 통해 원격 파일 시스템을 로컬처럼 마운트할 수 있다.
# NFS PV 예시
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteMany # 여러 Pod 동시 접근
nfs:
server: 192.168.1.100
path: /data/k8s
mountOptions:
- nfsvers=4.1
- hard
- timeo=600
장점
간단한 설정: 별도의 클라이언트 소프트웨어 설치 불필요
ReadWriteMany 지원: 여러 Pod가 동시에 읽기/쓰기 가능
낮은 진입 장벽: 대부분의 NAS가 기본 지원
운영 편의성: 파일 시스템 레벨에서 직접 관리 가능
단점
낮은 성능: 네트워크 오버헤드로 인한 레이턴시
단일 장애점: NFS 서버가 다운되면 모든 클라이언트 영향
제한적인 IOPS: 동시 접속이 많으면 성능 저하
파일 락 이슈: 동시 쓰기 시 데이터 정합성 문제 가능
적합한 사용 사례
- 공유 설정 파일: ConfigMap 대체용 대용량 설정
- 정적 컨텐츠: 이미지, CSS, JS 등 웹 에셋
- 로그 수집: 여러 Pod의 로그를 중앙 집중화
- ML 데이터셋: 학습용 데이터 공유
실무 팁
# NFS 성능 최적화 옵션
mountOptions:
- nfsvers=4.1 # NFSv4.1 사용 (성능 향상)
- hard # 서버 장애 시 재시도 (soft는 데이터 손실 위험)
- timeo=600 # 타임아웃 60초
- retrans=2 # 재전송 횟수
- rsize=1048576 # 읽기 버퍼 1MB
- wsize=1048576 # 쓰기 버퍼 1MB
- tcp # TCP 사용 (UDP보다 안정적)
- noatime # 액세스 타임 업데이트 비활성화 (성능 향상)
3. iSCSI (Internet Small Computer System Interface)
특징
iSCSI는 IP 네트워크를 통해 SCSI 명령을 전송하는 블록 레벨 스토리지 프로토콜이다. SAN(Storage Area Network)의 저렴한 대안으로 널리 사용된다.
# iSCSI PV 예시 (Synology CSI 사용)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
accessModes:
- ReadWriteOnce # 단일 노드만 접근
storageClassName: synology-iscsi
resources:
requests:
storage: 50Gi
장점
높은 성능: 블록 레벨 접근으로 낮은 레이턴시
높은 IOPS: 데이터베이스 워크로드에 적합
동적 프로비저닝: CSI 드라이버로 자동 볼륨 생성
스냅샷 지원: 백업/복구 용이
단점
복잡한 설정: initiator 설치 및 설정 필요
ReadWriteOnce만 지원: 한 노드만 마운트 가능
네트워크 의존성: 네트워크 품질에 성능 영향
멀티패스 설정 복잡: HA 구성 시 추가 작업 필요
적합한 사용 사례
- 데이터베이스: PostgreSQL, MySQL, MongoDB
- 고성능 워크로드: Elasticsearch, Redis
- 단일 인스턴스 애플리케이션: 상태 저장 앱
- 가상 머신 이미지: KubeVirt 등에서 사용
실무 팁
# 노드에 iSCSI initiator 설치 필요
# Ubuntu/Debian
apt-get install open-iscsi
# RHEL/CentOS
yum install iscsi-initiator-utils
# initiator name 확인
cat /etc/iscsi/initiatorname.iscsi
# iSCSI 서비스 시작
systemctl enable --now iscsid
systemctl enable --now open-iscsi
iSCSI가 ReadWriteOnce만 지원하는 기술적 이유
iSCSI는 왜 여러 노드에서 동시 마운트가 불가능할까요? 이는 블록 디바이스의 근본적인 특성 때문이다.
1. 파일 시스템 메타데이터 충돌
┌─────────────┐ ┌─────────────┐
│ Node 1 │ │ Node 2 │
│ │ │ │
│ ext4 FS │ │ ext4 FS │
└──────┬──────┘ └──────┬──────┘
│ │
└───────┐ ┐───────┘
│ │
┌─────▼───────▼─────┐
│ iSCSI Volume │
│ (블록 디바이스) │
└───────────────────┘
문제 상황
- Node 1이 파일을 생성하면 파일 시스템 메타데이터(inode, 블록 할당 테이블) 업데이트
- Node 2는 이 변경사항을 모르고 동일한 블록에 쓰기 시도
- 결과: 파일 시스템 손상
2. 캐시 일관성 문제
일반 파일 시스템(ext4, xfs 등)은 단일 호스트에서 사용하도록 설계되었다.
# Node 1의 동작
1. 블록 A를 읽어서 메모리 캐시에 저장
2. 캐시의 내용을 수정
3. 나중에 디스크에 flush (write-back)
# Node 2의 동작 (동시에)
1. 동일한 블록 A를 읽음 (오래된 데이터)
2. 수정하고 디스크에 쓰기
3. Node 1의 변경사항이 사라짐 ❌
3. 락(Lock) 메커니즘 부재
NFS는 네트워크 락 매니저(NLM)를 통해 파일 락을 관리하지만, 일반 블록 디바이스는 이런 메커니즘이 없다.
NFS:
Client 1 → "파일 A 잠금 요청" → NFS Server
↓
[Lock Manager]
↓
Client 2 → "파일 A 접근 시도" → "대기..."
iSCSI:
Client 1 → 직접 블록 쓰기 → ┐
├→ [충돌!] ❌
Client 2 → 직접 블록 쓰기 → ┘
4. 해결 방법: 클러스터 파일 시스템
ReadWriteMany를 블록 스토리지에서 사용하려면 클러스터 파일 시스템이 필요하다.
GFS2 (Red Hat)
# 분산 락 매니저 필요
pacemaker + dlm + gfs2
OCFS2 (Oracle)
# O2CB 클러스터 스택 필요
o2cb + ocfs2
이러한 파일 시스템들은
- 분산 락 메커니즘 내장
- 캐시 일관성 프로토콜 구현
- 메타데이터 동기화 지원
- 하지만 복잡하고 오버헤드가 크다
요약
| 특성 | NFS (파일 레벨) | iSCSI (블록 레벨) |
| 락 관리 | NFS 서버가 중앙 관리 | 없음 |
| 메타데이터 | 서버가 일원화 관리 | 각 클라이언트가 독립적 |
| 캐시 동기화 | NFS 프로토콜로 처리 | 불가능 |
| 다중 접근 | 안전 ✅ | 위험 ❌ |
결론: iSCSI는 블록 디바이스를 직접 노출하기 때문에, 일반 파일 시스템으로는 다중 노드 접근이 불가능하다. 이것이 ReadWriteOnce만 지원하는 근본적인 이유
4. Ceph RBD (RADOS Block Device)
특징
Ceph는 오픈소스 분산 스토리지 시스템으로, 블록, 파일, 오브젝트 스토리지를 모두 제공한다. RBD는 Ceph의 블록 스토리지 인터페이스이다.
# Ceph RBD StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ceph-rbd
provisioner: rbd.csi.ceph.com
parameters:
clusterID: your-cluster-id
pool: kubernetes
imageFeatures: layering
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
reclaimPolicy: Delete
allowVolumeExpansion: true
장점
고가용성: 데이터 복제로 장애 허용
확장성: 페타바이트 규모까지 확장 가능
자가 치유: 자동 복구 기능
볼륨 확장: 온라인 크기 조정 지원
스냅샷/클론: 효율적인 백업
단점
운영 복잡도: 클러스터 관리가 어려움
리소스 소모: 최소 3대 이상의 노드 필요
학습 곡선: Ceph 전문 지식 필요
디버깅 어려움: 문제 발생 시 원인 파악 복잡
적합한 사용 사례
- 온프레미스 프라이빗 클라우드: OpenStack 환경
- 대규모 클러스터: 수백 대 이상의 노드
- 고가용성 필수: 데이터 유실 불가 환경
- 하이브리드 스토리지: 블록/파일/오브젝트 통합 관리
5. 클라우드 네이티브 스토리지
AWS EBS (Elastic Block Store)
# AWS EBS StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-gp3
provisioner: ebs.csi.aws.com
parameters:
type: gp3
iops: "3000"
throughput: "125"
encrypted: "true"
allowVolumeExpansion: true
특징
- SSD 타입: gp3 (범용), io2 (고성능), st1 (처리량 최적화)
- 최대 16,000 IOPS (io2 Block Express는 256,000)
- 자동 백업 (스냅샷)
- 가용영역(AZ) 종속
GCP Persistent Disk
# GCP PD StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: pd-ssd
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-ssd
replication-type: regional-pd # 리전 간 복제
allowVolumeExpansion: true
특징
- 타입: pd-standard (HDD), pd-ssd (SSD), pd-extreme (NVMe)
- Regional PD로 다중 AZ 지원
- 자동 암호화
- 최대 100,000 IOPS
Azure Managed Disk
# Azure Disk StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azure-disk-premium
provisioner: disk.csi.azure.com
parameters:
storageaccounttype: Premium_LRS
kind: Managed
allowVolumeExpansion: true
특징
- 타입: Standard HDD, Standard SSD, Premium SSD, Ultra Disk
- Zone-redundant storage (ZRS) 지원
- 최대 160,000 IOPS (Ultra Disk)
6. 스토리지 타입 비교표
| 항목 | NFS | iSCSI | Ceph RBD | 클라우드 블록 |
| Access Mode | RWO, RWX, ROX | RWO | RWO | RWO |
| 성능 (IOPS) | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 레이턴시 | 5-20ms | 1-5ms | 1-5ms | <1ms |
| 설정 난이도 | ⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| 운영 복잡도 | ⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐ |
| 고가용성 | ❌ (단일 서버) | △ (멀티패스) | ✅ | ✅ |
| 동적 프로비저닝 | △ | ✅ | ✅ | ✅ |
| 볼륨 확장 | ❌ | ✅ | ✅ | ✅ |
| 스냅샷 | △ | ✅ | ✅ | ✅ |
| 비용 | 💰 | 💰💰 | 💰💰💰 | 💰💰💰💰 |
7. 선택 가이드: 당신의 상황에 맞는 스토리지는?
시나리오별 추천
"여러 Pod에서 설정 파일을 공유하고 싶어요"
→ NFS 선택
- ReadWriteMany 필요
- 성능 요구사항 낮음
- 간단한 설정
"PostgreSQL 데이터베이스를 운영할 거예요"
→ iSCSI 또는 클라우드 블록 스토리지
- 높은 IOPS 필요
- 낮은 레이턴시 중요
- 단일 인스턴스
"온프레미스에서 프로덕션 클러스터를 구축해요"
→ Ceph RBD 고려
- 고가용성 필수
- 충분한 하드웨어 리소스 있음
- 전문 운영 인력 확보
"클라우드(AWS/GCP/Azure)에서 실행해요"
→ 클라우드 네이티브 스토리지 강력 추천
- 관리 오버헤드 최소화
- 자동 백업/복구
- 최고 성능
의사결정 플로우차트
클라우드 환경인가?
├─ YES → 클라우드 네이티브 스토리지 사용
└─ NO
└─ ReadWriteMany 필요한가?
├─ YES → NFS
└─ NO → 높은 성능 필요한가?
├─ YES → iSCSI (소규모) or Ceph (대규모)
└─ NO → NFS로 충분
실무 예시: Synology NAS와 CSI Driver
많은 중소기업과 홈랩 사용자들이 Synology NAS를 Kubernetes 스토리지로 활용한다. Synology는 iSCSI와 NFS를 모두 지원하며, CSI 드라이버를 통해 동적 프로비저닝도 가능하다.
Synology CSI Chart 소개
Synology CSI Chart는 Synology 공식 CSI 드라이버를 Helm으로 쉽게 설치할 수 있도록 만든 커뮤니티 프로젝트이다.
주요 기능
동적 프로비저닝: PVC 생성 시 자동으로 LUN 생성
2개의 StorageClass 자동 생성:
- synology-csi-delete: PVC 삭제 시 볼륨도 삭제
- synology-csi-retain: PVC 삭제해도 볼륨은 유지
스냅샷 지원: VolumeSnapshot으로 백업/복구
커스터마이징 가능: affinity, nodeSelector, tolerations 설정
설치 방법
1. 사전 요구사항
# 모든 노드에 iSCSI initiator 설치 필요
# Ubuntu/Debian
sudo apt-get install open-iscsi
# RHEL/CentOS
sudo yum install iscsi-initiator-utils
# 서비스 시작
sudo systemctl enable --now iscsid
Synology NAS 설정
- DSM 7: SAN Manager 패키지 설치
- DSM 6: iSCSI Manager 패키지 설치
- 관리자 권한 가진 전용 사용자 생성 권장
2. Helm 저장소 추가
helm repo add synology-csi-chart https://christian-schlichtherle.github.io/synology-csi-chart
helm repo update
3. values.yaml 설정
# custom-values.yaml
clientInfoSecret:
clients:
- host: 192.168.1.100 # Synology NAS IP
port: 5000 # DSM 포트 (HTTPS는 5001)
https: false # HTTPS 사용 여부
username: k8s-csi-user # DSM 사용자
password: "your-password" # 비밀번호
storageClasses:
- name: synology-iscsi-delete
reclaimPolicy: Delete
volumeBindingMode: Immediate
parameters:
protocol: iscsi # 프로토콜: iscsi
fsType: ext4
# 성능 테스트 활성화
test: true
- name: synology-iscsi-retain
reclaimPolicy: Retain
parameters:
protocol: iscsi
fsType: ext4
# iSCSI 타겟 설정 (선택사항)
node:
tolerations:
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
4. 설치
helm install synology-csi synology-csi-chart/synology-csi \
--namespace synology-csi \
--create-namespace \
-f custom-values.yaml
5. 설치 확인
# CSI Controller 확인
kubectl get pods -n synology-csi -l app=synology-csi-controller
# CSI Node 확인 (모든 노드에서 실행)
kubectl get pods -n synology-csi -l app=synology-csi-node
# StorageClass 확인
kubectl get storageclass
# 출력 예시:
# NAME PROVISIONER RECLAIMPOLICY
# synology-iscsi-delete csi.san.synology.com Delete
# synology-iscsi-retain csi.san.synology.com Retain
사용 예시
데이터베이스용 PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: synology-iscsi-retain # 데이터 보호
resources:
requests:
storage: 50Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16
env:
- name: POSTGRES_PASSWORD
value: "password"
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
ports:
- containerPort: 5432
volumes:
- name: data
persistentVolumeClaim:
claimName: postgres-data
스냅샷 생성 및 복구
# 스냅샷 생성
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: postgres-snapshot-20250114
spec:
volumeSnapshotClassName: synology-snapshotclass
source:
persistentVolumeClaimName: postgres-data
---
# 스냅샷에서 복구
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data-restored
spec:
accessModes:
- ReadWriteOnce
storageClassName: synology-iscsi-retain
dataSource:
name: postgres-snapshot-20250114
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
resources:
requests:
storage: 50Gi
Synology CSI vs 순수 NFS 비교
| 항목 | Synology CSI (iSCSI) | 순수 NFS |
| 동적 프로비저닝 | ✅ 자동 | ❌ 수동 PV 생성 |
| 성능 | ⭐⭐⭐⭐ | ⭐⭐ |
| ReadWriteMany | ❌ (iSCSI), ✅ (NFS 모드) | ✅ |
| 스냅샷 | ✅ | ❌ |
| 볼륨 확장 | ✅ | ❌ |
| 설정 복잡도 | 중간 | 낮음 |
추천
- DB, 고성능: Synology CSI (iSCSI 모드)
- 공유 파일: Synology CSI (NFS 모드) 또는 순수 NFS
- 간단한 테스트: 순수 NFS
8. 실무 체크리스트
성능 요구사항 확인
- 필요한 IOPS 계산 (예: DB는 보통 1000+ IOPS)
- 레이턴시 요구사항 (예: 실시간 처리는 5ms 이하)
- 처리량(Throughput) 확인 (MB/s)
가용성 요구사항
- RTO/RPO 목표 설정
- 데이터 복제 필요 여부
- 백업/복구 전략 수립
접근 패턴
- 단일 Pod 접근 vs 다중 Pod 접근
- 읽기 위주 vs 쓰기 위주
- 순차 접근 vs 랜덤 접근
운영 역량
- 운영팀의 기술 수준
- 24/7 모니터링 가능 여부
- 장애 대응 절차 수립
9. 하이브리드 전략
실무에서는 단일 스토리지 타입만 사용하지 않는다. 워크로드 특성에 따라 혼합 사용하는 것이 일반적이다.
예시: 전자상거래 플랫폼
# 데이터베이스 - iSCSI (고성능)
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
storageClassName: iscsi-high-performance
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 100Gi
---
# 상품 이미지 - NFS (공유)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: product-images-pvc
spec:
storageClassName: nfs-shared
accessModes: [ReadWriteMany]
resources:
requests:
storage: 500Gi
---
# 로그 수집 - NFS (중앙화)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: logs-pvc
spec:
storageClassName: nfs-logs
accessModes: [ReadWriteMany]
resources:
requests:
storage: 200Gi
10. 트러블슈팅 가이드
NFS 성능 이슈
# NFS 마운트 옵션 확인
mount | grep nfs
# NFS 서버 상태 확인
showmount -e nfs-server-ip
# 네트워크 레이턴시 측정
ping -c 100 nfs-server-ip
# NFS 성능 테스트
dd if=/dev/zero of=/mnt/nfs/testfile bs=1M count=1024
iSCSI 연결 문제
# initiator 상태 확인
systemctl status iscsid
# 세션 확인
iscsiadm -m session
# 타겟 재스캔
iscsiadm -m node --rescan
# 로그 확인
journalctl -u iscsid -f
Ceph 클러스터 상태
# 클러스터 상태
ceph status
# OSD 상태
ceph osd tree
# Pool 상태
ceph osd pool stats
# 성능 통계
ceph osd perf
마무리
Kubernetes 스토리지 선택은 단순히 기술적 사양만으로 결정되지 않는다. 팀의 운영 역량, 예산, 성능 요구사항, 그리고 미래의 확장 계획까지 종합적으로 고려해야 한다.
핵심 요약
클라우드 환경이라면 고민할 필요 없이 클라우드 네이티브 스토리지를 사용하면된다. AWS EBS, GCP PD, Azure Disk는 최고의 성능과 안정성을 제공하며, 운영 부담도 최소화된다.
온프레미스 환경이라면 워크로드를 분석해보자.
- 공유 파일이 필요하면 NFS
- 데이터베이스나 고성능 워크로드는 iSCSI
- 대규모 프로덕션 환경이고 전문 인력이 있다면 Ceph
가장 중요한 것은 작게 시작해서 점진적으로 확장하는 것이다. 처음부터 완벽한 스토리지 아키텍처를 구축하려 하지 말자. NFS로 시작해서 성능 병목이 생기면 iSCSI로 마이그레이션하는 것도 충분히 합리적인 접근이다.
스토리지는 Kubernetes 환경에서 가장 복잡하고 중요한 영역 중 하나이다. 하지만 각 타입의 특성을 이해하고, 실무 경험을 쌓아가다 보면 어느새 최적의 선택을 자신 있게 할 수 있게 될 것이다.
Remember: 완벽한 스토리지는 없다. 상황에 맞는 최선의 선택이 있을 뿐이다.
Reference
- Kubernetes Storage Classes Documentation
- CNCF Storage Landscape
- Linux NFS Performance Tuning
- iSCSI Best Practices
- Synology Helm Chart
Somaz | DevOps Engineer | Kubernetes & Cloud Infrastructure Specialist
'Container Orchestration > Kubernetes' 카테고리의 다른 글
| ingress-nginx → nginx-gateway-fabric 마이그레이션 실전 기록 (온프레미스 K8s, 11개 인스턴스) (0) | 2026.05.14 |
|---|---|
| EKS 프로덕션 배포 가이드: 502 에러 제로 달성기 (0) | 2026.05.12 |
| Public Helm Chart Repository 구축하기 — 로컬 차트에서 ArtifactHub까지 (0) | 2026.04.24 |
| Kubernetes 1.34.x gRPC etcd Warning 버그 상세 분석 (0) | 2026.04.20 |
| Kubernetes 클러스터 업그레이드하기 (kubespray 2026v.) (0) | 2026.04.13 |