본문 바로가기
MinIO

[MinIO] Rack Awareness: StorageClass,PVC를 활용한 분산 배치 적용

by interlude-3 2025. 9. 26.

MinIO란?

S3 API를 지원하는 가볍고 빠른 오브젝트 스토리지로, 간단한 설정으로 확장 가능한 분산 스토리지를 쉽게 구축할 수 있습니다.

 

기본 구성의 한계

MinIO는 기본적으로 랙 단위 장애를 고려한 배치 전략을 제공하지 않습니다.

클러스터 규모가 커질수록 특정 Rack에 장애가 발생했을 때 데이터 가용성에 문제가 생길 수 있습니다.

 

해결 방법

이 문서에서는 MinIO의 데이터 저장 방식이 가진 한계를 살펴보고, Kubernetes의 PVC(Persistent Volume Claim)와 StorageClass 토폴로지 제약을 활용하여 랙 단위 내결함성을 확보하는 방법을 다룹니다.


1. MinIO의 기본 객체 저장 방식과 한계

Erasure Coding 기반 분산 저장

MinIO는 내부적으로 Erasure Coding 기술을 사용해 데이터를 저장합니다.

  • 객체는 데이터 조각(Data Shard)과 패리티 조각(Parity Shard)으로 나누어 서버 단위로 각 디스크에 하나씩 분산 저장 됩니다.
  • 쿼럼(Quorum)을 만족하는 수의 조각이 남아있으면 데이터 복구가 가능합니다.

Erasure Set Size(N) = Data Shard(K) + Parity Shard(M) 일 때,

Read/Write Quorum은 K (K:M=1:1 인 경우, Write Quorum은 K+1)

랙 단위 장애 시 취약점

MinIO의 기본 분산 저장 방식은 디스크나 서버 단위의 장애 상황엔 효과적이지만 랙 장애 상황시 대처가 불가합니다.

 

Erasure Set은 서버 ID 순서대로 연속적으로 그룹핑되는 방식으로 구성되는데, 서버가 올라간 파드가 각 노드에 무작위로 배포될 경우 같은 조각들이 동일 랙에 모일 수 있기 때문입니다.

 

하나의 객체를 구성하는 조각들이 우연히 같은 랙에 저장된 경우, 랙 전체가 다운되었을 때 여러개의 블록이 동시에 손실되어 데이터 접근이 불가합니다.


2. MinIO Erasure Set 구성 방식

MinIO는 Erasure Coding을 적용하기 위해 서버 또는 디스크를 Erasure Set 단위로 묶어 관리합니다.

  • 서버에 0부터 N까지 ID가 순서대로 부여됩니다.
  • ID 순서에 따라 erasure set size 단위로 그룹핑하여 Erasure Set을 구성합니다.
  • 예를 들어 Erasure Set Size가 4인 경우
    • 서버 ID 0~3 첫 번째 Erasure Set
    • 서버 ID 4~7 두 번째 Erasure Set

이처럼 연속된 서버들이 하나의 세트를 이루며 객체는 분산 저장됩니다.


3. PVC/StorageClass 기반 Rack Awareness 적용

앞서 설명했듯이 MinIO의 Erasure Set은 서버 ID 순서대로 연속적으로 그룹핑됩니다. 따라서 Kubernetes 환경에서 MinIO Pod가 무작위로 스케줄링되면, 동일한 Erasure Set을 구성하는 서버들이 우연히 같은 랙에 몰려 랙 단위 장애에 취약해질 수 있습니다. 이 문제를 해결하기 위해 Kubernetes의 PVC와 StorageClass 기능을 활용하여 데이터 볼륨의 물리적 배치를 제어합니다.

RA 적용 핵심은 PVC와 StorageClass

랙 장애 대응을 위해서는 pod 배치도 중요하지만, 특히 로컬 PV 환경에서는 데이터 볼륨(PV/PVC) 위치가 매우 중요합니다.

  • Pod: MinIO 프로세스를 실행하는 일시적인 컨테이너입니다. 스케줄링은 프로세스가 어느 노드에 실행될지만 결정합니다.
  • 볼륨 (PV/PVC): MinIO의 실제 데이터(Erasure Coding 조각)가 저장되는 영구적인 물리 디스크를 나타냅니다. 최대한 서로 다른 랙의 디스크에 저장되도록 구현해야 랙 단위 장애로부터 데이터를 보호할 수 있습니다.

따라서 랙 단위 장애에 대비하려면 데이터 볼륨(PV/PVC)이 랙 단위로 균등하게 분산되도록 강제해야 합니다.

StatefulSet 순차성과 토폴로지 제약 활용

랙 단위 분산 배포를 위해 StatefulSet(STS)이 보장하는 Pod와 PVC의 순차적인 인덱싱을 기반으로, 볼륨이 특정 랙에 순서대로 바인딩되도록 Kubernetes 스케줄러를 유도합니다.

 

1단계. 노드 라벨링

 

Kubernetes 관리자는 각 노드에 해당 노드가 속한 랙 정보를 라벨로 등록합니다.

  • 예: kubectl label node <node-name> topology.kubernetes.io/rack=rack1

2단계. StorageClass 설정 (바인딩 시점, Rack 제약)

 

랙 분산을 위한 핵심적인 제약 조건은 MinIO가 사용할 StorageClass에 정의됩니다. 랙 수만큼 StorageClass를 만들고 각 SC는 해당 랙만 허용하도록 allowedTopologies를 설정합니다.

  • volumeBindingMode: WaitForFirstConsumer: 이 설정은 PVC가 생성되자마자 PV를 바인딩하는 것을 지연시킵니다. 대신, 해당 PVC를 사용하는 MinIO Pod가 노드에 스케줄링된 후에 바인딩이 시작되도록 하여 스케줄러가 노드 정보를 활용할 수 있도록 합니다.
  • allowedTopologies: 이 필드에 랙 라벨 키(topology.kubernetes.io/rack)를 정의하여, 해당 StorageClass를 요청하는 PVC는 정의된 랙 라벨을 가진 노드에만 바인딩될 수 있도록 제약합니다.

3단계: STS와 PVC 매핑 특징 활용

 

STS의 배포 동작을 활용하여 데이터 볼륨의 랙 배치를 순서대로 강제합니다.

  1. PVC 수동으로 미리 생성 (정적 프로비저닝):
    • MinIO의 Erasure Set 인덱스 순서를 랙 순서에 정확히 맞추기 위해, 관리자는 STS 배포 전 STS의 명명 규칙에 맞는 PVC(data-minio-0, data-minio-1 등)를 미리 수동으로 생성해 놓습니다.
    • 이 PVC들은 StorageClass를 지정하거나, 이미 특정 랙에 있는 PV와 연결되도록 설계됩니다.
  2. StatefulSet(MinIO 서버) 배포:
    • STS는 순서대로 minio-0, minio-1, ... Pod를 생성합니다.
    • minio-0 Pod는 data-minio-0 PVC와 매핑
    • minio-1 Pod는 data-minio-1 PVC와 매핑
    • ...
  3. 바인딩 및 랙 분산 적용:
    • STS에 Pod Anti-Affinity를 설정하여 Pod들이 각 노드에 분산되어 배포되도록 합니다.
    • PVC는 이미 순서대로 정렬되어 있고 WaitForFirstConsumer를 통해 Pod가 배치된 후 PV와 바인딩되면서 물리적 랙 정보가 PV에 반영됩니다.
    • minio-0은 자신이 참조하는 data-minio-0 PVC를 통해 해당 Rack에만 바인딩될 수 있습니다.

결론

MinIO의 기본 분산 저장 방식은 디스크/노드 장애에는 강하지만, 랙 단위 내결함성은 보장하지 않습니다.

대규모 클러스터 환경에서 Rack Awareness는 데이터 안정성을 위한 필수 요소입니다.


Kubernetes 환경에서 MinIO의 Rack Awareness는 StorageClass의 Topology 제약을 통해 데이터 볼륨의 물리적 배치를 제어함으로써 효과적으로 구현할 수 있고 이를 통해 랙 단위의 내결함성과 고가용성을 확보할 수 있습니다.

 

Rack별로 StorageClass를 따로 만들고 PVC를 직접 관리하지 않아도, 단일 StorageClass와 동적 프로비저닝만으로 구성이 가능합니다. 이 경우 모든 Rack을 allowedTopologies에 포함한 StorageClass를 하나 생성하고, volumeBindingMode: WaitForFirstConsumer를 설정합니다. StatefulSet의 volumeClaimTemplates를 사용하면 Pod가 생성될 때 PVC도 자동으로 만들어지며, Kubernetes 스케줄러는 Pod Anti-Affinity 규칙과 WFFC 모드를 통해 랙별 StorageClass 없이도 MinIO Pod를 균형 있게 분산시킵니다. 이 방식은 랙 인식 구조를 단순화하면서도 스토리지 관리 효율성을 높일 수 있습니다.