Overview
이번 포스팅에서는 Kubernetes에서 Persistent Volume(PV), Persistent Volume Claim(PVC), 그리고 이를 동적으로 제어할 수 있는 StorageClass 및 CSI(Container Storage Interface) 에 대해 알아보았다.
Kubernetes는 기본적으로 파드가 재시작되거나 삭제되면 그 안의 데이터는 사라지게 된다. 하지만 Stateful 애플리케이션을 운영할 때는 데이터가 유지되어야 하므로, 이때 필요한 것이 볼륨(Volume) 시스템이며, 특히 영구 저장소(Persistent Storage) 가 중요한 역할을 한다.
이번 글에서는 다음과 같은 핵심 개념을 다뤘다.
- PV와 PVC의 개념과 역할
- 접근 모드 및 Reclaim 정책
- PV/PVC의 생명주기
- StorageClass를 통한 동적 볼륨 프로비저닝
- CSI를 통한 클라우드 및 다양한 스토리지 시스템 연동
- hostPath, emptyDir 등 파드 내부 볼륨 옵션 소개
스토리지 시스템은 쿠버네티스의 기반 인프라를 얼마나 유연하게 설계할 수 있는지를 결정짓는 요소이므로, 반드시 짚고 넘어가야 할 핵심 주제이다.
Kubernetes Volumes
- Persistent Volumes(PV)은 관리자에 의해 프로비저닝되거나 스토리지 클래스를 사용하여 동적으로 프로비저닝된 클러스터 내의 저장소이다.
- PV는 노드처럼 클러스터의 리소스로 존재하며 사용자에 의해 클레임될 수 있다.
- 주요 특징:
- 파드와 독립적인 생명주기: PV는 사용하는 개별 파드의 생명주기와 독립적이다.
- 저장소 추상화: 저장소 프로비저닝 및 사용에 대한 세부 사항을 추상화한다.
- 다양한 접근 모드 지원: `ReadWriteOnce, ReadOnlyMany, ReadWriteMany` 등의 모드를 지원한다.
- `ReadWriteOnce` : 볼륨이 단일 노드에 의해 읽기-쓰기로 마운트될 수 있다.
- `ReadOnlyMany` : 볼륨이 여러 노드에 의해 읽기 전용으로 마운트될 수 있다.
- `ReadWriteMany` : 볼륨이 여러 노드에 의해 읽기-쓰기로 마운트될 수 있다.
- Persistent Volume Claims(PVC)은 사용자의 저장소 요청이다.
- 파드가 노드 리소스를 사용하는 것과 마찬가지로, PVC는 PV 리소스를 사용한다.
- 주요 특징:
- 저장소 요청: 사용자는 특정 크기와 접근 모드를 요청한다.
- 바인딩: PVC는 클러스터 내의 적합한 PV에 자동으로 바인딩된다.
- 파드에서의 사용: PVC는 포드 내에서 볼륨으로 사용되며 이름으로 참조한다.
- persistentVolumeReclaimPolicy
- PV에 설정된 이 필드는 클레임에서 해제된 후 볼륨에 대해 수행할 작업을 지정한다.
- 정책은 다음과 같다:
- Retain: 기본 정책으로 해제 후 볼륨을 유지하며 데이터를 보존한다.
- Delete: 동적으로 프로비저닝된 PV의 경우 PVC가 삭제될 때 기본 저장소에서 볼륨을 삭제한다.
- Recycle: 동적 프로비저닝을 위해 권장되지 않는다. 이 정책은 볼륨의 데이터를 스크러빙하고 새 클레임에 사용할 수 있도록 하는 데 사용되었다.
PV and PVC Lifecycle
- Provisioning(프로비저닝): 영구 볼륨(PV)은 스토리지 클래스를 통해 동적으로 프로비저닝되거나 관리자에 의해 수동으로 사전 프로비저닝될 수 있다.
- Binding(바인딩): 사용자는 특정 크기 및 접근 모드를 요청하는 영구 볼륨 클레임(PVC)을 생성한다. PVC는 사용 가능한 PV에 바인딩된다.
- Using(사용): 바인딩되면 PVC는 포드에 의해 사용될 수 있습니다. 포드는 PVC를 참조하고 기본 PV를 볼륨으로 마운트 한다.
- Releasing(릴리스): 사용자가 볼륨을 완료하면 PVC를 삭제할 수 있습니다. 회수 정책에 따라 기본 PV가 다시 사용 가능해지거나 삭제된다.
- Reclaiming(회수): Reclaim 정책이 Retain로 설정된 경우 PVC 삭제 후 PV는 클러스터에 유지되며, Delete인 경우 PV 및 외부 인프라의 관련 스토리지 자산이 삭제된다.
VolumeSnapshot (볼륨 스냅샷: 백업 및 복구)
`VolumeSnapshot` 은 PVC의 상태를 특정 시점에 저장해두는 기능이다. 이를 통해 백업을 수행하고, 복원 시에는 `VolumeSnapshot` 을 기반으로 PVC를 생성하여 데이터를 되살릴 수 있다.
예시 YAML
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: nginx-snapshot
spec:
volumeSnapshotClassName: csi-hostpath-snapclass
source:
persistentVolumeClaimName: nginx-pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pvc-restore
spec:
storageClassName: csi-hostpath-sc
dataSource:
name: nginx-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
VolumeExpansion (PVC 동적 확장)
`allowVolumeExpansion: true` 가 설정된 `StorageClass` 를 사용할 경우, PVC의 스토리지 용량을 동적으로 늘릴 수 있다. 이는 애플리케이션 운영 중에도 확장 가능하다는 점에서 유용하다.
StorageClass 예시
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: expandable-sc
provisioner: kubernetes.io/aws-ebs
allowVolumeExpansion: true
PVC 확장 예시
kubectl patch pvc my-pvc -p '{"spec": {"resources": {"requests": {"storage": "10Gi"}}}}'
- `k get pvc` 명령어로 상태를 확인하면 `FileSystemResizePending → Bound` 로 변경됨
ReadWriteMany(RWX) 활용
`ReadWriteMany` 는 여러 Pod에서 동시에 읽기/쓰기 가능한 접근 모드이다. 대부분의 기본 CSI는 `ReadWriteOnce` 만 지원하므로, NFS, Longhorn, CephFS 등과 함께 사용해야 한다.
예시: RWX PVC (NFS 기반)
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
nfs:
server: 10.0.0.100
path: "/exports"
persistentVolumeReclaimPolicy: Retain
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
- ReadWriteMany는 여러 노드에서 Pod가 동시에 동일한 PVC를 마운트할 때 반드시 필요함
Kubernetes StorageClass & CSI-Driver
StorageClass는 관리자가 제공하는 스토리지의 "클래스"를 설명하는 방법을 제공한다.
기본 스토리지 플랫폼의 세부정보를 추상화하고 PV를 동적으로 프로비저닝하는 표준화된 방법을 제공한다.
주요 특징
- 프로비저닝(Provisioning): 동적 또는 정적일 수 있으며 스토리지 할당 방법을 정의한다.
- 매개변수(Parameters): 기본 스토리지 제공자에 따라 다양한 StorageClass가 서로 다른 매개변수를 가질 수 있다.
- 바인딩(Binding): PVC는 StorageClass를 지정할 수 있습니다. 동일한 클래스의 PV만 PVC에 바인딩될 수 있다.
Container Storage Interface(CSI)
컨테이너 스토리지 인터페이스(CSI)는 쿠버네티스와 같은 컨테이너 오케스트레이션 시스템(COS)에서 다양한 블록 및 파일 스토리지 시스템을 컨테이너화된 워크로드에 노출시키기 위한 표준이다. CSI의 목표는 스토리지 솔루션을 위한 일관되고 표준화된 API를 제공하여 클라우드 네이티브 생태계에서 스토리지 제품을 쉽게 통합하고 사용할 수 있게 하는 것이다.
CSI에서의 볼륨 유형
- 블록 스토리지: 기본 블록 수준의 스토리지를 제공하며, 성능이 중요한 애플리케이션에 주로 사용된다.
- 파일 스토리지: 공유 또는 전용 파일 액세스를 제공하며, 공유 스토리지 시스템에 주로 사용된다.
- 오브젝트 스토리지: 평면 데이터 구조를 사용하여 각 객체를 별도의 데이터로 저장하며, 비정형 데이터에 주로 사용된다.
파드에서 사용할 수 있는 볼륨 유형
- hostPath: 호스트 노드의 파일 시스템에서 파일 또는 디렉토리를 파드 내부로 마운트한다. 특정 노드에 종속적인 데이터 또는 테스트에 적합하다.
- emptyDir: 파드의 수명과 공유되는 임시 디렉토리이다. 임시 저장소 및 동일 파드 내의 컨테이너 간 파일 공유에 유용하다.
StatefulSet + PVC 실습
StatefulSet은 Pod 이름이 고정되고, 각각의 Pod가 자신만의 PVC를 사용한다. `volumeClaimTemplates` 를 이용해 Pod 수만큼 자동으로 PVC가 생성한다.
예시 YAML
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "web"
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "standard"
resources:
requests:
storage: 1Gi
- 각 Pod에 대해 `www-web-0, www-web-1, www-web-2` 와 같은 PVC가 자동 생성됨
마무리: “Stateful 애플리케이션을 위한 스토리지 해법, Kubernetes Volumes”
Kubernetes는 기본적으로 Stateless 애플리케이션에 최적화되어 있지만, PV, PVC, StorageClass, CSI 같은 구성요소를 통해 Stateful 애플리케이션까지도 안정적으로 다룰 수 있는 생태계를 제공한다.
- 개발자는 PVC만 선언하고,
- 관리자는 StorageClass 및 CSI 드라이버를 구성하며,
- 클러스터는 이를 바탕으로 동적으로 볼륨을 생성 및 마운트한다.
이는 AWS EBS, GCP PD, NFS, Ceph, Longhorn 등 다양한 스토리지 백엔드와 연동되며, 운영 자동화, 플랫폼 확장성, 복구 안정성 측면에서도 큰 강점을 가진다.
Kubernetes의 스토리지 계층을 잘 이해하는 것이 곧 클러스터 운영의 핵심 경쟁력이 된다.
Reference
https://medium.com/@kadimasam/kubernetes-storage-pv-pvc-and-storage-class-c107eba9c232
'Container Orchestration > Kubernetes' 카테고리의 다른 글
Kubernetes Pod를 안전하게 종료하는 방법(cordon, uncordon, drain, scale) (0) | 2024.07.09 |
---|---|
Ingress Nginx란? (0) | 2024.07.04 |
Kubernetes Affinity 및 Scheduling 설정 가이드 (0) | 2024.04.19 |
Kubernetes Network (0) | 2024.02.17 |
Kubernetes 클러스터 구축하기(kubespray 2024v.) (0) | 2024.02.02 |