🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

StorageClass와 동적 프로비저닝 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 11. 29. · 14 Views

StorageClass와 동적 프로비저닝 완벽 가이드

Kubernetes에서 스토리지를 자동으로 생성하고 관리하는 StorageClass와 동적 프로비저닝의 개념을 초급 개발자도 쉽게 이해할 수 있도록 설명합니다. 클라우드 환경에서 볼륨을 효율적으로 다루는 방법을 배워봅니다.


목차

  1. StorageClass_개념
  2. 프로비저너_이해
  3. 동적_프로비저닝_설정
  4. 기본_StorageClass_지정
  5. 볼륨_바인딩_모드
  6. 클라우드별_스토리지_설정

1. StorageClass 개념

김개발 씨는 쿠버네티스 클러스터에 애플리케이션을 배포하던 중 난감한 상황에 빠졌습니다. 파드가 필요로 하는 스토리지를 매번 수동으로 만들어야 하니, 배포할 때마다 운영팀에 요청하고 기다려야 했습니다.

"이거 자동화할 방법이 없나요?"라고 선배에게 물었습니다.

StorageClass는 한마디로 스토리지의 등급표입니다. 마치 호텔을 예약할 때 스탠다드, 디럭스, 스위트룸 중에서 고르듯이, 개발자가 원하는 스토리지 종류를 선택할 수 있게 해줍니다.

이것을 제대로 이해하면 스토리지 관리가 완전히 자동화되어 개발 생산성이 크게 향상됩니다.

다음 코드를 살펴봅시다.

# StorageClass 정의 예제
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-storage
# 스토리지를 생성할 프로비저너 지정
provisioner: kubernetes.io/aws-ebs
# 스토리지 파라미터 설정
parameters:
  type: gp3
  fsType: ext4
# 볼륨 회수 정책: Delete 또는 Retain
reclaimPolicy: Delete
# 볼륨 확장 허용 여부
allowVolumeExpansion: true

김개발 씨는 입사 6개월 차 주니어 개발자입니다. 오늘도 새로운 마이크로서비스를 배포하려는데, 데이터베이스용 스토리지가 필요했습니다.

예전에는 운영팀에 티켓을 열고, 스토리지가 준비될 때까지 며칠씩 기다려야 했습니다. 선배 개발자 박시니어 씨가 다가와 말했습니다.

"아직도 그렇게 하고 있어요? StorageClass를 사용하면 스토리지가 자동으로 생성되는데요." 그렇다면 StorageClass란 정확히 무엇일까요?

쉽게 비유하자면, StorageClass는 마치 커피숍의 메뉴판과 같습니다. 메뉴판에는 아메리카노, 라떼, 모카 등 다양한 종류가 있고, 손님은 원하는 메뉴를 주문하면 됩니다.

바리스타가 알아서 커피를 만들어주죠. 손님이 직접 원두를 볶고 에스프레소를 추출할 필요가 없습니다.

이처럼 StorageClass도 개발자가 원하는 스토리지 종류를 선택하면, 쿠버네티스가 알아서 스토리지를 생성해줍니다. StorageClass가 없던 시절에는 어땠을까요?

관리자가 미리 PersistentVolume을 수동으로 생성해 두어야 했습니다. 개발자가 스토리지를 요청하면, 미리 만들어둔 볼륨 중에서 적합한 것을 찾아 연결했습니다.

만약 맞는 크기나 성능의 볼륨이 없으면? 관리자가 새로 만들 때까지 기다려야 했습니다.

프로젝트가 커지고 팀이 늘어날수록 이 병목 현상은 심각해졌습니다. 바로 이런 문제를 해결하기 위해 StorageClass가 등장했습니다.

StorageClass를 사용하면 동적 프로비저닝이 가능해집니다. 개발자가 스토리지를 요청하는 순간, 쿠버네티스가 자동으로 볼륨을 생성합니다.

관리자는 StorageClass만 미리 정의해두면 됩니다. 마치 자판기에 메뉴와 레시피를 등록해두면, 손님이 버튼을 누를 때마다 음료가 나오는 것과 같습니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 metadata.name에서 이 StorageClass의 이름을 정합니다.

개발자들은 이 이름을 사용해서 스토리지를 요청하게 됩니다. provisioner는 실제로 스토리지를 생성할 드라이버를 지정합니다.

AWS EBS, GCP Persistent Disk, Azure Disk 등 클라우드 제공자마다 다른 프로비저너를 사용합니다. parameters 섹션에서는 스토리지의 세부 사양을 정합니다.

SSD인지 HDD인지, 파일 시스템은 무엇을 쓸지 등을 지정할 수 있습니다. reclaimPolicy는 볼륨을 다 쓴 후 어떻게 할지 정합니다.

Delete면 자동 삭제, Retain이면 보존합니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 전자상거래 서비스를 운영한다고 가정해봅시다. 데이터베이스에는 빠른 SSD 스토리지가 필요하고, 로그 저장용에는 저렴한 HDD 스토리지면 충분합니다.

이럴 때 fast-storage와 slow-storage라는 두 개의 StorageClass를 만들어두면, 개발팀이 용도에 맞게 선택할 수 있습니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 reclaimPolicy를 Delete로 설정해두고 중요한 데이터를 저장하는 것입니다. 파드를 삭제하면 볼륨도 함께 삭제되어 데이터가 사라질 수 있습니다.

프로덕션 환경에서는 반드시 Retain 정책이나 별도의 백업 전략을 세워야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 설명을 들은 김개발 씨는 눈이 반짝였습니다. "아, 이제 운영팀 기다리지 않아도 되겠네요!" StorageClass를 제대로 이해하면 스토리지 관리의 자동화라는 큰 이점을 얻을 수 있습니다.

개발 속도가 빨라지고, 운영팀의 부담도 줄어듭니다.

실전 팁

💡 - StorageClass 이름은 용도를 알 수 있게 명확하게 지정하세요 (예: fast-ssd, standard-hdd)

  • 프로덕션 환경에서는 reclaimPolicy를 Retain으로 설정하는 것을 고려하세요
  • allowVolumeExpansion을 true로 설정하면 나중에 용량 확장이 가능합니다

2. 프로비저너 이해

박시니어 씨가 StorageClass를 설명해주었지만, 김개발 씨는 한 가지 의문이 생겼습니다. "그런데 provisioner라는 건 정확히 뭐예요?

이게 실제로 스토리지를 만드는 건가요?" 좋은 질문이었습니다. 프로비저너를 이해해야 StorageClass의 진정한 힘을 알 수 있습니다.

프로비저너는 실제로 스토리지를 생성하는 일꾼입니다. 마치 음식점에서 주문을 받는 사람과 요리하는 셰프가 다르듯이, StorageClass는 메뉴를 정의하고 프로비저너는 실제 스토리지를 만듭니다.

각 클라우드 환경마다 다른 프로비저너가 있으며, 이를 통해 다양한 종류의 스토리지를 생성할 수 있습니다.

다음 코드를 살펴봅시다.

# AWS EBS 프로비저너 사용 예제
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: aws-ebs-gp3
# AWS EBS CSI 드라이버 (최신 권장 방식)
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  # IOPS 설정 (gp3는 최대 16000)
  iops: "3000"
  # 처리량 설정 (MB/s)
  throughput: "125"
  encrypted: "true"
volumeBindingMode: WaitForFirstConsumer

김개발 씨는 카페에 앉아 커피를 주문했습니다. 카운터에서 주문을 받은 직원이 "아메리카노 한 잔이요!"라고 외치자, 뒤에서 바리스타가 에스프레소를 추출하기 시작했습니다.

문득 이 장면이 쿠버네티스의 스토리지 시스템과 비슷하다는 생각이 들었습니다. 박시니어 씨가 설명을 이어갔습니다.

"StorageClass가 메뉴판이라면, 프로비저너는 바리스타예요. 실제로 주문을 만드는 사람이죠." 그렇다면 프로비저너는 어떻게 동작하는 걸까요?

프로비저너는 크게 두 가지 유형이 있습니다. 첫 번째는 인트리 프로비저너로, 쿠버네티스에 기본 내장된 것들입니다.

kubernetes.io/aws-ebs나 kubernetes.io/gce-pd 같은 것들이 여기에 해당합니다. 하지만 이들은 점차 deprecated 되고 있습니다.

두 번째는 CSI 프로비저너입니다. CSI는 Container Storage Interface의 약자로, 쿠버네티스와 스토리지 시스템 사이의 표준 인터페이스입니다.

마치 USB가 다양한 기기를 컴퓨터에 연결할 수 있게 해주듯이, CSI는 다양한 스토리지 시스템을 쿠버네티스에 연결할 수 있게 해줍니다. 왜 CSI가 등장했을까요?

예전에는 새로운 스토리지 시스템을 지원하려면 쿠버네티스 자체를 수정해야 했습니다. 이건 매우 번거롭고 시간이 오래 걸리는 작업이었습니다.

CSI가 도입되면서 스토리지 벤더들이 독립적으로 드라이버를 개발하고 배포할 수 있게 되었습니다. 쿠버네티스의 릴리스 주기와 무관하게 빠르게 기능을 추가할 수 있게 된 것입니다.

위의 코드에서 ebs.csi.aws.com이 바로 AWS EBS CSI 드라이버입니다. 이 프로비저너는 AWS API를 호출해서 실제 EBS 볼륨을 생성합니다.

parameters 섹션의 값들이 그대로 AWS에 전달됩니다. type: gp3는 최신 범용 SSD 타입이고, iops와 throughput으로 성능을 세밀하게 조절할 수 있습니다.

실무에서 프로비저너를 선택할 때는 몇 가지를 고려해야 합니다. 첫째, 사용하는 클라우드 환경에 맞는 프로비저너를 선택해야 합니다.

AWS면 ebs.csi.aws.com, GCP면 pd.csi.storage.gke.io, Azure면 disk.csi.azure.com을 사용합니다. 온프레미스 환경이라면 NFS, Ceph, OpenEBS 등의 프로비저너를 사용할 수 있습니다.

둘째, CSI 드라이버가 클러스터에 설치되어 있어야 합니다. 관리형 쿠버네티스 서비스(EKS, GKE, AKS)를 사용한다면 보통 기본 제공되지만, 직접 설치해야 하는 경우도 있습니다.

하지만 주의할 점이 있습니다. 초보 개발자들이 자주 하는 실수는 프로비저너 이름을 잘못 적는 것입니다.

오타가 있으면 스토리지 생성이 실패하고, 파드는 Pending 상태로 멈춰 있게 됩니다. 에러 메시지도 직관적이지 않아서 원인을 찾기 어려울 수 있습니다.

항상 공식 문서에서 정확한 프로비저너 이름을 확인하세요. 김개발 씨가 물었습니다.

"그럼 CSI 드라이버가 설치되어 있는지 어떻게 확인하죠?" 박시니어 씨가 답했습니다. "kubectl get csidrivers 명령을 실행하면 설치된 CSI 드라이버 목록을 볼 수 있어요." 프로비저너를 제대로 이해하면 StorageClass의 동작 원리를 명확하게 알 수 있습니다.

문제가 발생했을 때 어디서부터 디버깅해야 하는지도 파악할 수 있게 됩니다.

실전 팁

💡 - 새 프로젝트에서는 인트리 프로비저너 대신 CSI 프로비저너를 사용하세요

  • kubectl get csidrivers로 설치된 CSI 드라이버를 확인할 수 있습니다
  • 프로비저너가 지원하는 parameters는 공식 문서에서 반드시 확인하세요

3. 동적 프로비저닝 설정

이제 김개발 씨는 StorageClass와 프로비저너가 무엇인지 알게 되었습니다. 하지만 실제로 어떻게 사용하는 걸까요?

박시니어 씨가 말했습니다. "이제 실전이에요.

PVC를 만들어서 동적 프로비저닝이 어떻게 동작하는지 직접 보여드릴게요."

동적 프로비저닝은 PersistentVolumeClaim이 생성될 때 자동으로 PersistentVolume이 만들어지는 메커니즘입니다. 마치 온라인 쇼핑몰에서 주문하면 창고에서 상품이 자동으로 포장되어 배송되듯이, 개발자가 스토리지를 요청하면 클러스터가 알아서 볼륨을 생성하고 연결해줍니다.

다음 코드를 살펴봅시다.

# PersistentVolumeClaim 정의
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-app-data
spec:
  # 사용할 StorageClass 지정
  storageClassName: fast-storage
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      # 요청할 스토리지 용량
      storage: 10Gi
---
# 파드에서 PVC 사용
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
    - name: app
      image: nginx
      volumeMounts:
        - mountPath: /data
          name: data-volume
  volumes:
    - name: data-volume
      persistentVolumeClaim:
        claimName: my-app-data

박시니어 씨가 화이트보드에 그림을 그리기 시작했습니다. "동적 프로비저닝의 흐름을 그려볼게요." 첫 번째 단계는 PVC 생성입니다.

개발자가 kubectl apply 명령으로 PVC를 생성합니다. PVC에는 원하는 용량과 접근 모드, 그리고 사용할 StorageClass 이름이 적혀 있습니다.

두 번째 단계는 프로비저너 호출입니다. 쿠버네티스 컨트롤러가 PVC를 발견하고, 지정된 StorageClass의 프로비저너를 호출합니다.

"10GB짜리 gp3 볼륨 만들어줘"라고 요청하는 것이죠. 세 번째 단계는 실제 볼륨 생성입니다.

프로비저너가 클라우드 API를 호출해서 실제 스토리지를 생성합니다. AWS라면 EBS 볼륨이, GCP라면 Persistent Disk가 만들어집니다.

네 번째 단계는 PV 생성과 바인딩입니다. 볼륨이 생성되면 쿠버네티스가 자동으로 PersistentVolume 객체를 만들고, PVC와 연결(바인딩)합니다.

이제 파드에서 이 스토리지를 사용할 수 있습니다. 김개발 씨가 코드를 살펴보며 질문했습니다.

"accessModes가 뭔가요?" accessModes는 볼륨에 접근하는 방식을 정의합니다. ReadWriteOnce(RWO)는 하나의 노드에서만 읽고 쓸 수 있습니다.

ReadOnlyMany(ROX)는 여러 노드에서 읽기만 가능합니다. ReadWriteMany(RWX)는 여러 노드에서 읽고 쓸 수 있습니다.

대부분의 블록 스토리지는 RWO만 지원하고, NFS 같은 파일 스토리지는 RWX를 지원합니다. 위의 코드 두 번째 부분은 파드에서 PVC를 사용하는 방법입니다.

volumes 섹션에서 PVC를 볼륨으로 정의하고, volumeMounts에서 컨테이너 내부의 어느 경로에 마운트할지 지정합니다. 위 예제에서는 /data 경로에 스토리지가 마운트됩니다.

컨테이너 내부에서 /data에 파일을 쓰면, 그 데이터는 PV에 저장됩니다. 실무에서 동적 프로비저닝의 진가가 발휘되는 순간은 StatefulSet을 사용할 때입니다.

예를 들어 MySQL 클러스터를 3개의 레플리카로 운영한다고 가정해봅시다. 각 레플리카는 독립적인 스토리지가 필요합니다.

StatefulSet과 volumeClaimTemplates를 사용하면, 각 파드마다 자동으로 PVC가 생성되고 볼륨이 프로비저닝됩니다. 수동으로 3개의 볼륨을 만들 필요가 없습니다.

하지만 주의할 점도 있습니다. 동적 프로비저닝된 볼륨의 reclaimPolicy가 Delete이면, PVC를 삭제할 때 볼륨도 함께 삭제됩니다.

실수로 PVC를 지우면 데이터가 영구적으로 사라질 수 있습니다. 중요한 데이터라면 반드시 백업 전략을 세워두세요.

또 하나, storageClassName을 지정하지 않으면 클러스터의 기본 StorageClass가 사용됩니다. 의도치 않은 타입의 스토리지가 생성될 수 있으니, 명시적으로 지정하는 습관을 들이세요.

김개발 씨가 직접 PVC를 생성해보았습니다. kubectl get pvc 명령을 실행하니 STATUS가 Bound로 표시되었습니다.

"와, 정말 자동으로 볼륨이 만들어졌네요!" 박시니어 씨가 웃으며 말했습니다. "이게 동적 프로비저닝의 마법이에요.

개발자 생산성이 확 올라가죠."

실전 팁

💡 - kubectl get pvc와 kubectl get pv로 프로비저닝 상태를 확인하세요

  • 중요한 데이터는 reclaimPolicy: Retain을 사용하거나 별도 백업을 설정하세요
  • storageClassName을 명시적으로 지정하여 의도한 스토리지를 사용하세요

4. 기본 StorageClass 지정

김개발 씨가 동료의 코드를 보다가 이상한 점을 발견했습니다. PVC에 storageClassName이 없는데도 볼륨이 잘 생성되어 있었습니다.

"어떻게 된 거죠? StorageClass를 안 적어도 되나요?" 박시니어 씨가 설명했습니다.

"그건 기본 StorageClass가 설정되어 있기 때문이에요."

기본 StorageClass는 PVC에 storageClassName을 지정하지 않았을 때 자동으로 사용되는 StorageClass입니다. 마치 카페에서 "커피 한 잔 주세요"라고만 해도 기본 메뉴인 아메리카노가 나오듯이, 개발자가 스토리지 종류를 명시하지 않아도 기본값이 적용됩니다.

다음 코드를 살펴봅시다.

# 기본 StorageClass로 지정하기
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
  annotations:
    # 이 어노테이션이 기본 StorageClass로 지정
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
---
# storageClassName 없이 PVC 생성
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: default-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  # storageClassName 생략 시 기본 StorageClass 사용

관리형 쿠버네티스 서비스를 사용해본 분이라면 이미 기본 StorageClass를 경험했을 겁니다. AWS EKS에는 gp2라는 기본 StorageClass가 있고, GKE에는 standard가 기본입니다.

이 덕분에 처음 쿠버네티스를 배우는 개발자도 복잡한 설정 없이 스토리지를 사용할 수 있습니다. 기본 StorageClass를 지정하는 방법은 간단합니다.

StorageClass의 annotations에 **storageclass.kubernetes.io/is-default-class: "true"**를 추가하면 됩니다. 위 코드의 첫 번째 부분이 그 예시입니다.

이렇게 설정하면 이 StorageClass가 클러스터의 기본값이 됩니다. 기본 StorageClass를 변경해야 하는 상황은 언제일까요?

가장 흔한 경우는 비용 최적화입니다. 예를 들어 EKS의 기본 StorageClass인 gp2보다 gp3가 더 저렴하고 성능도 좋습니다.

팀에서 새로운 gp3 기반 StorageClass를 만들고 이를 기본값으로 설정하면, 모든 신규 PVC가 자동으로 더 효율적인 스토리지를 사용하게 됩니다. 기존 기본 StorageClass를 변경하려면 두 단계가 필요합니다.

먼저 기존 기본 StorageClass의 어노테이션을 "false"로 변경합니다. 그다음 새로운 StorageClass에 "true" 어노테이션을 추가합니다.

주의할 점은 동시에 두 개의 기본 StorageClass가 있으면 안 된다는 것입니다. 쿠버네티스가 어느 것을 사용할지 모르기 때문에 오류가 발생할 수 있습니다.

김개발 씨가 물었습니다. "그럼 기본 StorageClass를 아예 안 쓰고 싶으면요?" 좋은 질문입니다.

storageClassName에 **빈 문자열("")**을 명시적으로 지정하면 기본 StorageClass를 사용하지 않습니다. 이 경우 동적 프로비저닝이 동작하지 않고, 미리 생성된 PV 중에서 조건에 맞는 것을 찾아 바인딩합니다.

특수한 요구사항이 있을 때 유용합니다. 실무에서 기본 StorageClass 관리는 플랫폼 팀의 중요한 역할 중 하나입니다.

개발팀이 일일이 StorageClass를 신경 쓰지 않아도 합리적인 기본값이 적용되도록 설정해두면 생산성이 높아집니다. 동시에 특별한 요구사항이 있는 팀을 위해 추가적인 StorageClass도 제공합니다.

fast-ssd, archival-hdd 같은 이름으로 용도에 맞는 옵션을 준비해두는 것이죠. 주의할 점도 있습니다.

기본 StorageClass를 변경해도 이미 생성된 PVC와 PV에는 영향이 없습니다. 새로 생성되는 PVC에만 적용됩니다.

기존 볼륨의 스토리지 타입을 변경하려면 데이터를 마이그레이션해야 합니다. 박시니어 씨가 정리했습니다.

"기본 StorageClass는 편리하지만, 중요한 서비스에서는 항상 명시적으로 지정하는 게 좋아요. 누군가가 기본값을 바꿔도 영향받지 않거든요."

실전 팁

💡 - kubectl get sc 명령으로 현재 기본 StorageClass를 확인하세요 (default 표시가 있음)

  • 클러스터에는 하나의 기본 StorageClass만 두세요
  • 중요한 워크로드에서는 storageClassName을 명시적으로 지정하세요

5. 볼륨 바인딩 모드

김개발 씨가 새로운 서비스를 배포했는데, 파드가 Pending 상태로 멈춰 있었습니다. 로그를 확인해보니 "volume node affinity conflict"라는 에러가 보였습니다.

박시니어 씨가 와서 보더니 말했습니다. "볼륨 바인딩 모드 때문이에요.

이거 한 번 제대로 알아볼까요?"

볼륨 바인딩 모드는 PVC와 PV가 언제 연결되는지를 결정합니다. Immediate 모드는 PVC가 생성되자마자 바인딩하고, WaitForFirstConsumer 모드는 파드가 스케줄링될 때까지 기다립니다.

마치 택배를 미리 보내놓느냐, 받는 사람이 집에 있을 때 보내느냐의 차이와 같습니다.

다음 코드를 살펴봅시다.

# WaitForFirstConsumer 모드 설정
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: zone-aware-storage
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
# 파드 스케줄링 시점까지 바인딩 지연
volumeBindingMode: WaitForFirstConsumer
# 허용된 토폴로지 제한 (선택적)
allowedTopologies:
  - matchLabelExpressions:
      - key: topology.kubernetes.io/zone
        values:
          - ap-northeast-2a
          - ap-northeast-2c

클라우드 환경에서 스토리지는 특정 **가용영역(Availability Zone)**에 생성됩니다. 예를 들어 AWS의 ap-northeast-2a 영역에 EBS 볼륨이 만들어지면, 그 볼륨은 같은 영역의 EC2 인스턴스에만 연결할 수 있습니다.

다른 영역인 ap-northeast-2c의 인스턴스에서는 사용할 수 없습니다. 여기서 문제가 발생합니다.

Immediate 모드에서는 PVC가 생성되는 즉시 볼륨이 만들어집니다. 이때 쿠버네티스는 파드가 어느 노드에 배치될지 모릅니다.

만약 볼륨이 ap-northeast-2a에 생성되었는데, 스케줄러가 파드를 ap-northeast-2c의 노드에 배치하려고 하면? 볼륨을 연결할 수 없어서 파드가 Pending 상태로 멈춥니다.

김개발 씨가 겪은 문제가 바로 이것이었습니다. WaitForFirstConsumer 모드는 이 문제를 해결합니다.

이름 그대로 "첫 번째 소비자(파드)를 기다린다"는 뜻입니다. PVC를 생성해도 바로 볼륨이 만들어지지 않습니다.

파드가 스케줄링되어 어느 노드에 배치될지 결정된 후에야 볼륨이 생성됩니다. 그래서 항상 파드와 같은 영역에 볼륨이 위치하게 됩니다.

비유하자면 이렇습니다. Immediate 모드는 마치 친구에게 선물을 미리 보내놓는 것과 같습니다.

친구가 이사를 가버리면 선물을 받을 수 없죠. WaitForFirstConsumer 모드는 친구가 어디 있는지 확인한 후에 그 주소로 선물을 보내는 것입니다.

확실하게 전달됩니다. 위 코드의 allowedTopologies는 볼륨이 생성될 수 있는 영역을 제한합니다.

특정 영역에만 볼륨을 만들고 싶을 때 사용합니다. 예를 들어 비용이나 규정상의 이유로 특정 영역에서만 운영해야 하는 경우에 유용합니다.

하지만 대부분의 경우 이 설정 없이 WaitForFirstConsumer만 사용해도 충분합니다. 실무에서는 언제 어떤 모드를 사용해야 할까요?

WaitForFirstConsumer는 거의 모든 상황에서 권장됩니다. 특히 다중 가용영역을 사용하는 프로덕션 환경에서는 필수입니다.

이 모드를 사용하면 스케줄러가 노드 자원, 어피니티 규칙, 토폴로지 제약 등을 모두 고려한 후에 볼륨이 생성되므로 문제가 발생할 가능성이 줄어듭니다. Immediate 모드가 유용한 경우도 있습니다.

단일 가용영역만 사용하는 환경이나, 볼륨을 미리 프로비저닝해두고 싶을 때입니다. 하지만 이런 경우는 드뭅니다.

kubectl get pvc 명령으로 PVC 상태를 확인할 때 차이가 있습니다. Immediate 모드에서는 PVC가 바로 Bound 상태가 됩니다.

WaitForFirstConsumer 모드에서는 파드가 생성되기 전까지 Pending 상태로 남아 있습니다. 이게 정상이니 당황하지 마세요.

파드가 스케줄링되면 자동으로 Bound로 바뀝니다. 박시니어 씨가 조언했습니다.

"새 StorageClass를 만들 때 습관적으로 WaitForFirstConsumer를 사용하세요. 나중에 골치 아픈 문제를 예방할 수 있어요."

실전 팁

💡 - 다중 가용영역 환경에서는 항상 WaitForFirstConsumer를 사용하세요

  • PVC가 Pending 상태여도 WaitForFirstConsumer 모드에서는 정상입니다
  • 볼륨 바인딩 문제는 kubectl describe pvc로 이벤트를 확인하세요

6. 클라우드별 스토리지 설정

김개발 씨의 회사는 AWS를 메인으로 사용하지만, 최근 멀티클라우드 전략을 추진하고 있습니다. GCP와 Azure에서도 서비스를 운영하게 되었는데, 각 클라우드마다 StorageClass 설정이 다르다는 것을 알게 되었습니다.

"클라우드마다 어떻게 다른 건가요?" 박시니어 씨가 비교표를 만들어주기로 했습니다.

각 클라우드 제공자마다 스토리지 서비스와 CSI 드라이버가 다릅니다. AWS는 EBS와 EFS, GCP는 Persistent Disk와 Filestore, Azure는 Azure Disk와 Azure Files를 제공합니다.

프로비저너 이름과 파라미터도 클라우드마다 다르므로, 환경에 맞는 설정을 알아두어야 합니다.

다음 코드를 살펴봅시다.

# AWS EBS StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: aws-fast
provisioner: ebs.csi.aws.com
parameters:
  type: gp3  # io1, io2, gp2, gp3, sc1, st1
  iops: "3000"
  throughput: "125"
---
# GCP Persistent Disk StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gcp-fast
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-ssd  # pd-standard, pd-ssd, pd-balanced
---
# Azure Disk StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: azure-fast
provisioner: disk.csi.azure.com
parameters:
  skuName: Premium_LRS  # Standard_LRS, Premium_LRS, StandardSSD_LRS

멀티클라우드 시대에 각 클라우드의 스토리지 특성을 이해하는 것은 중요합니다. 같은 목적의 스토리지라도 이름과 설정 방법이 다르기 때문입니다.

하나씩 살펴보겠습니다. 먼저 AWS입니다.

AWS의 블록 스토리지는 **EBS(Elastic Block Store)**입니다. CSI 프로비저너는 ebs.csi.aws.com을 사용합니다.

가장 많이 사용하는 볼륨 타입은 gp3입니다. gp2의 후속 버전으로, 같은 가격에 더 좋은 기본 성능을 제공합니다.

고성능이 필요하면 io2를 사용하고, 대용량 아카이브용에는 sc1이나 st1을 선택합니다. AWS에서 공유 파일 시스템이 필요하면 **EFS(Elastic File System)**를 사용합니다.

프로비저너는 efs.csi.aws.com이고, ReadWriteMany 접근 모드를 지원합니다. 여러 파드에서 동시에 읽고 쓸 수 있어서 웹 서버의 공유 스토리지 등에 적합합니다.

다음은 GCP입니다. GCP의 블록 스토리지는 Persistent Disk입니다.

프로비저너는 pd.csi.storage.gke.io입니다. 볼륨 타입으로 pd-standard(HDD), pd-balanced(균형 잡힌 SSD), pd-ssd(고성능 SSD)가 있습니다.

GKE를 사용하면 기본 StorageClass가 이미 설정되어 있어 바로 사용할 수 있습니다. GCP에서 공유 스토리지가 필요하면 Filestore를 사용합니다.

완전 관리형 NFS 서비스로, 여러 파드에서 동시 접근이 가능합니다. 마지막으로 Azure입니다.

Azure의 블록 스토리지는 Azure Disk입니다. 프로비저너는 disk.csi.azure.com입니다.

skuName 파라미터로 Standard_LRS(HDD), StandardSSD_LRS(표준 SSD), Premium_LRS(프리미엄 SSD)를 선택합니다. LRS는 Locally Redundant Storage의 약자로 단일 데이터센터 내 복제를 의미합니다.

Azure에서 공유 스토리지는 Azure Files를 사용합니다. SMB 프로토콜을 지원하는 완전 관리형 파일 공유 서비스입니다.

클라우드를 선택할 때 스토리지 비용도 고려해야 합니다. 같은 용량이라도 클라우드와 스토리지 타입에 따라 가격이 다릅니다.

예를 들어 AWS gp3는 gp2보다 20% 정도 저렴합니다. 프로덕션으로 가기 전에 각 클라우드의 가격 계산기로 비용을 예측해보세요.

실무에서 멀티클라우드 환경을 운영할 때 팁이 있습니다. StorageClass 이름을 추상화하는 것입니다.

예를 들어 각 클라우드에서 fast-storage, standard-storage라는 동일한 이름의 StorageClass를 만들되, 내부 설정만 클라우드에 맞게 다르게 합니다. 애플리케이션 매니페스트에서는 fast-storage만 참조하면 되므로, 어느 클라우드에 배포하든 동일한 YAML을 사용할 수 있습니다.

온프레미스 환경은 어떨까요? 온프레미스에서는 OpenEBS, Rook-Ceph, Longhorn 같은 오픈소스 스토리지 솔루션을 많이 사용합니다.

이들도 CSI 드라이버를 제공하므로 클라우드와 비슷한 방식으로 StorageClass를 설정할 수 있습니다. 박시니어 씨가 마무리했습니다.

"각 클라우드의 스토리지 특성을 알아두면 비용과 성능을 모두 최적화할 수 있어요. 공식 문서를 자주 확인하세요.

새로운 옵션이 계속 추가되거든요." 김개발 씨는 노트에 각 클라우드별 프로비저너 이름을 정리했습니다. 이제 어느 클라우드에서든 자신 있게 스토리지를 설정할 수 있을 것 같았습니다.

실전 팁

💡 - 각 클라우드의 최신 CSI 드라이버 버전과 지원 파라미터를 공식 문서에서 확인하세요

  • 멀티클라우드 환경에서는 StorageClass 이름을 추상화하여 이식성을 높이세요
  • 비용 최적화를 위해 각 스토리지 타입의 가격을 비교해보세요

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Kubernetes#StorageClass#DynamicProvisioning#PersistentVolume#CloudStorage#Kubernetes,Storage,StorageClass

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.