2025.01.07 - [개발 환경 및 운영/Kubernetes] - Kubernetes의 네트워크 리소스: Ingress (with ALB)
이번 시간에는 쿠버네티스에서 제공하는 스토리지 리소스에 대해 알아보려고 한다. 특정 데이터를 보유해야 하는 stateful한 애플리케이션의 경우 데이터를 영구적으로 보관하고 관리할 수 있어야 한다. 이는 단순 로컬 볼륨만으로는 어렵기 때문에 볼륨을 네크워트로 연결해 계속 사용할 수 있도록 도와주는 Persistent Volume과 Persistent Volume Claim이라는 오브젝트에 대해 공부해보자.
로컬 볼륨
로컬 디스크를 볼륨으로 활용하는 방법으로, 개발환경이나 간단히 테스트할 때 유용하다. 노드나 pod이 삭제되면 데이터가 손실되므로 데이터의 영속성이 필요한 경우에는 적합하지 않다.
로컬 볼륨 타입
- hostPath :
- 워커 노드 특정 디렉터리를 컨테이너에 마운트해서 사용.
- 예를 들어 워커 노드의 /tmp/test 디렉터리를 Pod 내부에서 /data로 마운트하면 이 둘은 동일한 디렉터리로서 사용된다.
- 노드 종속적이기 때문에 pod이 다른 노드로 이동시 데이터에 접근 불가하며, pod이 삭제되도 노드가 살아있다면 데이터 유지.
- emptyDir
- Pod 내의 컨테이너끼리 데이터를 공유할수 있는 임시 디렉터리.
- pod이 삭제되면 데이터도 함께 삭제됨.
네트워크 볼륨
로컬 볼륨은 영속성 보장이 되지 않기 때문에, 클러스터 외부에 스토리지를 따로 두고 네트워크로 연결해 사용한다. 네트워크로 접근할 수 있는 스토리지를 포괄적으로 네트워크 볼륨이라고 부르기 때문에 종류가 엄청나게 많다. NFS(Network File System), 클라우드 기반 블록 스토리지(AWS EBS, GCP PD ..), 오브젝트 스토리지(AWS S3, Cloud Storage) 등등.. 여기서는 스토리지 유형에 대해 자세히 알아볼건 아니기 때문에 대략 저런 외부 스토리지가 존재한다는 것을 알고 다음으로 넘어가보자.
PV(Persistent Volume), PVC(Persistent Volume Claim)
등장 배경
네트워크 볼륨만 사용할 경우 클러스터 사용자 입장에서 스토리지 설정이 복잡할 수 있다. 아래 예제와 같이 yaml에 직접 볼륨 정의를 하게 되면 NFS 서버의 정보가 고정되어 있어 의존성이 생기게 된다. 다른 네트워크 볼륨을 사용하고 싶다면 각 스토리지 유형에 맞는 새 yaml 파일을 또 만들어야 한다. 이렇게 되면 스토리지 유형을 변경하거나 관리하기가 어려워진다. 그래서 PV, PVC 를 통해 네트워크 볼륨을 한 단계 더 추상화해 분리하여 관리와 재사용성을 높이는 것이다.
yaml 예제
네트워크 볼륨 직접 사용하는 경우
volumes:
- name: nfs-volume
nfs:
server: nfs-server.example.com # 서버 주소 직접 명시
path: /data/nfs
PVC 사용하는 경우
volumes:
- name: nfs-volume
persistentVolumeClaim: # 스토리지 요구사항으르 모아 추상화 해둔 PVC만 정의
claimName: mypvc
PV
- 스토리지 제공자가 정의하는 리소스
- NFS, EBS 등 다양한 유형의 스토리지를 정의하고 관리
- 인프라 관리자는 PV를 통해 스토리지 리소스를 프로비저닝하고 관리한다.
PVC
- 사용자가 요청하는 스토리지 리소스
- 사용자는 스토리지 세부사항을 알 필요 없이, 스토리지 크기와 접근방식만 정의
쿠버네티스에서는 기존에 생성해둔 PV와 PVC의 요구사항이 일치한다면 두개 리소스를 매칭시켜 연결한다. Pod에서 PVC를 볼륨으로 정의해놨다면, 해당 PVC를 사용해 컨테이너 내부에 볼륨이 마운트 된 상태로 생성된다.
처음에 좀 헷갈릴 수 있는데 PV는 스토리지 정보 자체에 대한 정의, PVC는 스토리지 사용자의 요청에 대한 정의로, 사용성이 더 좋도록 두 단계로 나눠서 추상화했다고 생각하면 된다.
PVC & PV 연결 조건
- 스토리지 크기(PVC에서 요청한 크기 이상)
- 접근모드 일치
- ReadWriteOnce(RWO) : 1:1 마운트, 읽기 및 쓰기. EBS볼륨은 1:1만 가능하기 때문에 해당모드 사용.
- ReadOnlyMany(ROX) : 1:N 마운트, 읽기 전용.
- ReadWriteMany(RWX) : 1:N 마운트, 읽기 및 쓰기. NFS서버는 1:N 마운트가 가능하기 때문에 해당 모드로 사용.
- 스토리지 클래스 일치
이외에도 스토리지 클래스 이름이나 라벨 셀렉터를 이용해 PV와 PVC를 바인딩 할수도 있다.
YAML 예제
PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 10Gi # 용량
accessModes:
- ReadWriteOnce # 접근 모드
nfs:
path: /data
server: nfs-server.example.com # 스토리지 서버 정의
PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: example-pvc
spec:
accessModes:
- ReadWriteOnce # 접근 모드 RWO 일치
resources:
requests:
storage: 10Gi # 용량 일치
Pod에서 PVC 사용
kind: Pod
metadata:
name: example-pod
spec:
containers:
- name: app-container
image: nginx
volumeMounts: # 컨테이너 내부에 볼륨을 마운트할 경로
- name: data-volume
mountPath: /usr/share/nginx/html # 컨테이너 내부에서 볼륨이 연결될 디렉터리 경로
volumes: # pod 전체에서 사용할 볼륨 정의
- name: data-volume
persistentVolumeClaim:
claimName: example-pvc # 참조할 pvc
PV 라이프사이클과 Recliam Policy
PV 상태 유형
- Available: PVC와 바인딩되지 않은 상태.
- Bound: PVC와 바인딩된 상태.
- Released: PVC가 삭제되었지만 PV의 데이터는 유지된 상태.
- Failed: PV가 더 이상 사용할 수 없는 상태.
Reclaim Policy: PVC가 삭제된 후 PV를 어떻게 처리할지 결정
- Retain: 데이터와 PV를 그대로 유지.
- Delete: PVC 삭제 시 PV와 데이터도 함께 삭제.
다이나믹 프로비저닝과 StorageClass
다이나믹 프로비저닝
- PVC에서 요구하는 조건과 일치하는 PV가 존재하지 않는다면, StarageClass를 참조하여 조건에 맞는 PV를 자동으로 생성해주는 기능.
- 아무 스토리지나 동적 프로비저닝을 사용할 수 있는 것은 아니고 프로비저너가 있어야 동작함. AWS EBS, GCP PD, Azure Disk 같은 클라우드 네이티브 스토리지는 프로비저너를 기본 제공하지만, NFS 같은 경우 외부 플러그인 따로 설치 필요.
StarageClass
- 스토리지 프로비저닝을 자동화하기 위한 쿠버네티스 리소스.
- PVC가 생성될때 특정 스토리지 클래스를 지정하면, 스토리지 클래스에 따라 PV가 동적으로 생성된다.
PVC 요청
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: fast-storage # 사용할 스토리지 클래스
스토리지 클래스 정의
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-storage
provisioner: kubernetes.io/aws-ebs # EBS 프로비저너 정의
parameters:
type: gp2
reclaimPolicy: Retain
PVC가 참조하는 fast-storage라는 스토리지 클래스 확인 > 스토리지 클래스에 정의된 provisioner 호출 > 프로비저너는 실제 PVC 요청에 따라 EBS 볼륨 및 PV생성 > 생성된 PV와 PVC 바인딩
이상으로 PV와 PVC에 대해 알아보았다. 처음에는 persistent 하게 사용할 수 있는 스토리지를 따로 제공해주는 그런 기능인줄 알았는데, 네트워크 볼륨을 추상화하는 기능이라는 것을 알게 되었다. 사실 개발하면서 이 부분까지 와서 설정해줘야 하는 경우는 많지는 않은데, 이번에 airbyte나 milvus 같은 새로운 인프라를 설치하면서 디버깅하다보니 PV의 역할이 뭔지 좀 정확히 이해할 필요성을 느꼈다. 특히 PV랑 PVC가 무슨 차이인지 모르고, helm 설치하면 알아서 설정해주니까 되는대로 사용했었는데 이제는 명확히 구분할 수 있다. 다음 시간에 이어서 쿠버네티스에 대해 계속해서 알아보도록 하자.
'개발 환경 및 운영 > Kubernetes' 카테고리의 다른 글
Kubernetes의 리소스 관리와 설정(namespace, Configmap, Secret) (0) | 2025.04.06 |
---|---|
Kubernetes의 네트워크 리소스: Ingress (with ALB) (0) | 2025.01.07 |
Kubernetes의 서비스(Service) (1) | 2025.01.01 |
Kubernetes의 구성요소 알아보기 (Pod, ReplicaSet, Deployment) (1) | 2024.12.23 |
Docker에서 Kubernetes로 (1) | 2024.12.19 |