쿠버네티스에서 영구 스토리지 구현을 위한 간단 가이드
컨테이너 오케스트레이션의 세계에서 쿠버네티스는 재시작이나 스케일링 이벤트 사이에 데이터를 유지할 필요가 없는 무상태(stateless) 애플리케이션 관리에 탁월합니다. 하지만 데이터베이스, 메시지 큐, 키-값 저장소와 같은 많은 최신 애플리케이션은 본질적으로 상태 저장(stateful) 방식입니다. 이러한 애플리케이션은 이를 실행하는 파드(Pod)가 재스케줄링되거나 교체되더라도 데이터를 영구적으로 저장하고 액세스할 수 있는 안정적인 방법을 필요로 합니다. 바로 이 지점에서 쿠버네티스 영구 스토리지(Persistent Storage)가 중요하게 작용합니다.
이 가이드는 쿠버네티스에서 영구 스토리지를 관리하는 핵심 구성 요소인 영구 볼륨(PersistentVolumes, PV)과 영구 볼륨 클레임(PersistentVolumeClaims, PVC)의 개념을 명확히 설명할 것입니다. 실제 YAML 예제를 통해 스토리지 정의, 요청 및 파드에 바인딩하는 방법을 단계별로 안내하여 쿠버네티스 클러스터에 상태 저장 애플리케이션을 자신 있게 배포할 수 있도록 도울 것입니다.
영구 볼륨(PV) 및 영구 볼륨 클레임(PVC) 이해
구현에 앞서 PV와 PVC의 역할을 이해하는 것이 중요합니다.
- 영구 볼륨 (PV): PV는 관리자가 프로비저닝했거나 스토리지 클래스(StorageClasses)를 사용하여 동적으로 프로비저닝된 클러스터 내의 스토리지입니다. PV는 노드(Nodes)와 마찬가지로 클러스터 리소스입니다. PV는 해당 PV를 사용하는 개별 파드의 수명 주기와는 독립적인 수명 주기를 가집니다. PV는 기본 스토리지 구현 세부 정보(예: NFS, iSCSI, 클라우드 공급자 블록 스토리지)를 추상화합니다.
- 영구 볼륨 클레임 (PVC): PVC는 사용자의 스토리지 요청입니다. 이는 PV로서 클러스터에서 사용 가능한 스토리지 리소스를 사용합니다. PVC는 컴퓨팅 리소스를 소비한다는 점에서 파드와 유사하며, 네임스페이스에 범위가 지정됩니다. PVC는 원하는 스토리지 용량, 액세스 모드 및 선택적으로 스토리지 클래스를 지정합니다.
이러한 역할 분리 덕분에 클러스터 관리자는 스토리지 리소스를 독립적으로 프로비저닝하고 관리할 수 있으며, 애플리케이션 개발자는 기본 구현 세부 정보를 알 필요 없이 스토리지를 요청할 수 있습니다.
주요 개념: 액세스 모드 및 스토리지 클래스
PV와 PVC를 사용할 때 파악해야 할 두 가지 중요한 개념은 액세스 모드(Access Modes)와 스토리지 클래스(StorageClasses)입니다.
액세스 모드
액세스 모드는 볼륨이 파드에 마운트되는 방식을 정의합니다. 사용 가능한 액세스 모드는 다음과 같습니다.
ReadWriteOnce(RWO): 볼륨은 단일 노드에 의해 읽기-쓰기(read-write)로 마운트될 수 있습니다.ReadOnlyMany(ROX): 볼륨은 여러 노드에 의해 읽기 전용(read-only)으로 마운트될 수 있습니다.ReadWriteMany(RWX): 볼륨은 여러 노드에 의해 읽기-쓰기(read-write)로 마운트될 수 있습니다.
이러한 모드에 대한 실제 지원 여부는 기본 스토리지 공급자에 따라 달라진다는 점에 유의해야 합니다.
스토리지 클래스
스토리지 클래스는 관리자가 제공하는 스토리지의 "클래스"를 설명하는 방법을 제공합니다. 다양한 클래스는 서비스 품질 수준, 백업 정책 또는 클러스터 관리자가 결정하는 임의의 정책에 매핑될 수 있습니다. 스토리지 클래스에는 스토리지를 프로비저닝하는 프로비저너와 프로비저너에 대한 매개변수 집합이 있습니다. 특정 PV 없이 PVC가 생성되고 스토리지 클래스를 요청하면 쿠버네티스는 지정된 스토리지 클래스를 사용하여 PV를 동적으로 프로비저닝합니다.
영구 스토리지 구현: 단계별
파드를 위한 영구 스토리지를 요청하고 사용하는 일반적인 시나리오를 살펴보겠습니다.
1단계: 영구 볼륨 클레임(PVC) 정의
먼저 스토리지 요구 사항을 지정하는 PVC를 생성해야 합니다. 이 PVC는 애플리케이션의 스토리지 요청 역할을 할 것입니다.
pvc.yaml 예시:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
이 예시에서:
name: my-pvc: 이것은 우리의 PVC 이름입니다.accessModes: - ReadWriteOnce: 우리는 단일 노드에 의해 읽기-쓰기(read-write)로 마운트될 수 있는 스토리지를 요청하고 있습니다.resources.requests.storage: 1Gi: 우리는 1기가바이트의 스토리지를 요청하고 있습니다.
PVC 적용:
위 내용을 pvc.yaml이라는 파일로 저장하고 클러스터에 적용합니다.
kubectl apply -f pvc.yaml
적용 후 PVC의 상태를 확인할 수 있습니다.
kubectl get pvc my-pvc
적합한 PV를 사용할 수 있거나 동적으로 프로비저닝된 경우 PVC가 Bound 상태임을 나타내는 출력을 볼 수 있을 것입니다.
2단계: PVC를 사용하는 파드 생성
이제 우리의 PVC가 요청한 스토리지를 활용할 파드를 생성해 봅시다. 우리는 PVC가 제공하는 볼륨을 컨테이너 내의 특정 디렉토리에 마운트할 것입니다.
pod-with-pv.yaml 예시:
apiVersion: v1
kind: Pod
metadata:
name: my-stateful-pod
spec:
containers:
- name: my-container
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: my-persistent-storage
mountPath: /usr/share/nginx/html
volumes:
- name: my-persistent-storage
persistentVolumeClaim:
claimName: my-pvc
이 예시에서:
volumes: 우리는my-persistent-storage라는 이름의 볼륨을 정의합니다.persistentVolumeClaim.claimName: my-pvc: 이것은 우리의 볼륨을 이전에 생성한 PVC에 연결합니다.volumeMounts: 컨테이너 정의 내에서 이 볼륨이 마운트되어야 할 위치(mountPath: /usr/share/nginx/html)를 지정합니다.
파드 적용:
위 내용을 pod-with-pv.yaml이라는 파일로 저장하고 적용합니다.
kubectl apply -f pod-with-pv.yaml
이제 nginx 컨테이너는 /usr/share/nginx/html 경로에서 my-pvc에 의해 정의된 영구 스토리지에 액세스할 수 있습니다. 컨테이너 내 이 경로에 작성된 모든 데이터는 PVC와 기본 PV가 유지되는 한, 파드가 삭제되고 다시 생성되더라도 영구적으로 유지됩니다.
스토리지 클래스를 사용한 동적 프로비저닝
PV를 수동으로 생성하는 것은 번거로울 수 있습니다. 쿠버네티스는 기존 PV로 충족될 수 없는 스토리지를 PVC가 요청할 때 PV가 자동으로 생성되는 동적 프로비저닝을 제공합니다. 이는 스토리지 클래스를 통해 이루어집니다.
대부분의 클라우드 공급자(AWS, GCP, Azure)는 사전 구성된 스토리지 클래스를 제공합니다. 다음 명령으로 확인할 수 있습니다.
kubectl get storageclass
동적 프로비저닝을 사용하려면 PVC 정의에 storageClassName 필드를 추가하기만 하면 됩니다.
pvc-dynamic.yaml 예시:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-dynamic-pvc
spec:
storageClassName: standard # Replace 'standard' with an actual StorageClass name
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
이 PVC를 적용하면 쿠버네티스는 standard라는 이름의 스토리지 클래스(또는 사용자가 지정한 이름)를 찾아 해당 프로비저너에게 5Gi의 새 PV를 생성하고 이 PVC에 바인딩하도록 지시할 것입니다.
팁 및 모범 사례
- 올바른 액세스 모드 선택: 애플리케이션에 필요한 액세스 모드를 신중하게 고려하십시오.
ReadWriteOnce는 단일 복제본 데이터베이스에 일반적으로 사용되며,ReadWriteMany는 여러 파드에서 사용되는 공유 파일 시스템에 필요합니다. - 스토리지 성능 이해: 다양한 스토리지 공급자 및 스토리지 클래스는 다양한 성능 특성(IOPS, 처리량)을 제공합니다. 애플리케이션의 성능 요구 사항을 충족하는 스토리지 클래스를 선택하십시오.
- 백업 전략: 영구 스토리지가 자동으로 백업을 의미하지는 않습니다. 중요한 데이터의 경우 영구 볼륨에 대한 강력한 백업 전략을 구현하십시오.
- PV 회수 정책: PV에는
reclaimPolicy가 있으며, 이는Delete(기본값),Retain또는Recycle(더 이상 사용되지 않음)이 될 수 있습니다.Retain은 PV가 삭제되더라도 기본 스토리지가 여전히 존재하는 경우 데이터가 손실되지 않도록 하는 데 유용합니다. - 네임스페이스 고려 사항: PVC는 네임스페이스 범위입니다. 바인딩이 발생하려면 파드와 PVC가 동일한 네임스페이스에 있는지 확인하십시오.
결론
영구 스토리지 구현은 쿠버네티스에서 상태 저장 애플리케이션을 실행하기 위한 근본적인 요구 사항입니다. 영구 볼륨과 영구 볼륨 클레임, 그리고 스토리지 클래스의 유연성을 이해하고 활용함으로써 애플리케이션 데이터를 안정적으로 관리할 수 있습니다. 이 가이드는 시작하는 데 필요한 기초 지식과 실제 예시를 제공하여 쿠버네티스에 더욱 정교하고 탄력적인 상태 저장 워크로드를 배포할 수 있도록 할 것입니다.