23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
데이터인프라팀은 데이터 수집, 가공, 저장, 연동 업무를 담당하며, 카프카(Kafka), 레디스(Redis) 등의 SaaS 솔루션도 제공합니다.
이 중 데이터 저장은 가장 기본적이며 중요한 작업입니다. 그동안 하둡과 HBase 기반 저장 시스템을 사용해왔으나,
최근 LLM 학습용 데이터 수집을 위해 대량의 이미지와 동영상 파일을 원본 그대로 저장하고 안정적으로 제공해야 하는 요구사항이 생겼습니다.
기존 시스템으로는 이를 처리하기 어려워 별도의 스토리지 시스템이 필요했습니다.
이에 오픈소스 오브젝트 스토리지 솔루션인 MinIO와 컨테이너 오케스트레이션 플랫폼인 Kubernetes(K8s)를 활용해 새로운 사내 스토리지 서비스를 구축하기로 했습니다.
이 글에서는 MinIO와 Kubernetes 기반 오브젝트 스토리지(이하 ‘OS’) 구축의 목적과 필요성, 그리고 구체적인 설계 및 구축, 운영 경험을 공유하고자 합니다.
출처: https://cloudian.com/blog/object-storage-care/
오브젝트 스토리지는 대규모 비정형 데이터 관리에 최적화된 시스템입니다.
데이터를 오브젝트 단위로 저장하며, 각 오브젝트는 데이터, 메타데이터, 고유 식별자로 구성됩니다. 이는 클라우드 환경에서 효율적인 데이터 관리를 가능하게 합니다.
NAS/NFS: 파일 단위 관리, 확장성 제한
SAN: 블록 단위 관리, 고성능이지만 복잡하고 고비용
오브젝트 스토리지: 오브젝트 단위 관리, 클라우드 환경에 최적화
확장성: 노드 추가로 용량 확장이 용이함
메타데이터 관리: 유연한 데이터 분류 및 검색 가능
비용 효율성: 저렴한 대규모 데이터 저장, 오픈소스 솔루션 활용 가능
출처: https://1week.tistory.com/106
사내 스토리지 시스템 구축을 위해 HDFS, CephFS, MinIO 등의 오픈소스 솔루션을 검토했습니다.
각 솔루션의 장단점을 고려하여 우리 팀의 요구사항에 가장 부합하는 옵션을 선택했습니다.
HDFS: 대용량 데이터 분산 저장에 최적화되었으나, 메타데이터 관리의 단일 장애점과 작은 파일 처리의 비효율성
CephFS: 높은 확장성과 안정성을 제공하지만, 설정과 운영이 복잡하고 리소스 요구량이 높음
S3 호환 API: 기존 애플리케이션과의 연동성 우수
간편한 설치 및 운영: 가벼운 리소스 요구량과 빠른 배포 가능
확장성 및 고가용성: Kubernetes와의 결합으로 쉽게 구현 가능
결론적으로, MinIO는 간편성, S3 호환성, 그리고 확장성이 우리 팀의 요구사항에 가장 부합하여 선택되었습니다.
현재 사내에서는 대용량 데이터를 각 부서와 개인이 개별적으로 저장하고 공유하고 있습니다.
AWS S3, FTP 서버, USB, 외장 하드디스크 등을 사용하고 있지만, 이는 여러 문제를 초래합니다.
첫째, 통합된 스토리지 시스템 부재로 부서 간 데이터 공유가 비효율적입니다. 개별 스토리지 사용은 관리 부담을 가중시키고 데이터 접근이 제한적입니다.
둘째, 보안 문제가 발생합니다. 외부 저장소에 데이터를 저장하면 유출 위험이 있으며, 물리적 장치 사용은 분실 시 보안 위협을 초래합니다.
셋째, 비용적인 비효율성이 존재합니다. 외부 스토리지 사용은 장기적으로 비용 부담이 큽니다.
이러한 문제를 해결하기 위해 MinIO 기반 사내 스토리지 서비스 구축이 필요합니다.
보안 강화: 데이터를 사내에 저장하여 외부 유출을 방지
비용 절감: 외부 스토리지 사용을 줄여 비용 절감
효율적인 데이터 공유: S3 호환 API로 부서 간 데이터 공유 용이, 중앙 집중식 관리로 중복 저장 방지
결론적으로, 보안, 비용, 데이터 관리 효율성을 고려한 사내 스토리지 시스템 구축은 필수적이며, 이를 통해 조직에 도움이 되는 서비스를 제공할 수 있습니다.
사내 스토리지 서비스는 Kubernetes 클러스터 위에 MinIO를 구성하는 방식으로 설계되었습니다.
MinIO Operator를 사용해 CRD(Custom Resource Definition)를 제출하고, 각 서버 노드에서 MinIO Object Storage Pool을 StatefulSet으로 관리합니다.
각 노드는 7.3TiB 크기의 디스크 12개를 사용해 Local Path Provisioner를 통해 PV(Persistent Volume)로 관리합니다.
이러한 구조는 데이터를 안정적으로 저장하고, 노드 간 데이터 복제 및 확장을 용이하게 합니다.
MinIO Object Storage Pool의 Pod들은 Kubernetes의 오버레이 네트워크를 통해 클러스터를 구성합니다.
MinIO에 접근하기 위해 MinIO Client API 서버를 배치해 사용자가 쉽게 데이터에 접근할 수 있도록 하였으며, 사용자 인증과 트래픽 제어는 API Gateway(APISIX)를 통해 관리됩니다.
API Gateway는 Keycloak과 연동되어 사용자 인증을 처리하며, Kubernetes의 Ingress Controller와 결합하여 작동합니다.
Ingress Controller는 L7 로드 밸런서를 통해 로드 밸런싱과 고가용성(HA)을 지원하여 트래픽을 안정적으로 분배하고 서비스의 연속성을 보장합니다.
위에서 오브젝트 스토리지와 MinIO에 대해 알아보았으며, 사내 스토리지 서비스의 필요성도 살펴보았습니다.
이제 OS 설계와 구성을 바탕으로 Kubernetes 위에 MinIO를 설치하고 운영하는 과정을 단계별로 살펴보겠습니다.
MinIO 설치 및 운영을 위해 미리 준비해야 할 것들:
Kubernetes: MinIO Operator v6.0.0부터 Kubernetes 최소 버전이 1.22 이상으로 변경되었으므로 주의하시기 바랍니다. OS 구축에는 Kubernetes 1.22 버전을 설치했습니다.
Ingress Controller: 클러스터 외부 사용자가 MinIO에 접근할 수 있도록 Ingress Controller를 설치해야 합니다. ingress-nginx/controller:v1.11.0을 설치했습니다.
Local Path Provisioner: 온프레미스로 오브젝트 스토리지를 구축할 때 동적 PV 생성을 위해, Local Path Provisioner는 매우 중요한 Kubernetes Operator입니다. Local Path Provisioner v0.0.28을 사용했습니다.
Prometheus Operator: MinIO 상태 모니터링을 위해 Prometheus를 설치합니다. Prometheus Operator를 이용해 설치했습니다. Prometheus Operator v0.76.2
MinIO Operator: MinIO 설치를 직접 진행할 수도 있지만, 편리하게 환경을 설치할 수 있도록 MinIO Operator를 설치하고, 이를 이용해 오브젝트 스토리지를 설정합니다. MinIO Operator v6.0.0을 사용했습니다.
Local Path Provisioner ConfigMap 각 서버 노드 환경 반영
오브젝트 스토리지를 구성하는 각 서버 노드에 장착한 디스크에 맞춰 ConfigMap을 업데이트해야 합니다.
예를 들어 각 노드에 디스크가 4개씩 마운트되어 있으면, 4개 디스크를 모두 사용할 수 있게 ConfigMap에 아래와 같은 형태로 각 디스크 경로를 추가합니다.
apiVersion: v1
data:
config.json: |-
{
"nodePathMap":[
{
"node":"DEFAULT_PATH_FOR_NON_LISTED_NODES",
"paths":[
"/data1/local-path-provisioner",
"/data2/local-path-provisioner",
"/data3/local-path-provisioner",
"/data4/local-path-provisioner"
]
}
]
}
MinIO 오브젝트 저장소로 사용할 PV/PVC 동적 생성을 위해 StorageClass 리소스 작성
StorageClass는 클러스터 관리자가 다양한 스토리지 옵션을 제공할 수 있도록 하는 Kubernetes 리소스로, PVC를 이용한 동적 PV 생성을 가능하게 합니다.
MinIO에서는 Local Path Provisioner를 이용하므로 아래와 같이 local-path StorageClass를 생성합니다.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-path
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
MinIO Operator Tenant CRD 배포하기
Tenant CRD를 작성하면 MinIO Operator가 CRD 설정에 따라 Kubernetes 내에 오브젝트 스토리지를 생성합니다.
CRD는 세부적으로 설정할 옵션이 많기 때문에 직접 작성하기보다는 Kustomize나 Helm을 이용해 구축자가 원하는 옵션만 추가하거나 변경하여 작성합니다.
OS 구축에는 Helm을 사용했습니다. Helm을 이용한 MinIO Tenant 배포를 참고했습니다.
Helm values.yml 스토리지 설정 (erasureCodingParity 기본값 EC:4)
pools:
- servers: 4
name: pool-0
volumesPerServer: 4
size: 7.3Ti
Erasure Coding
데이터를 여러 조각으로 나누고 추가적인 패리티 조각을 생성하여 데이터 손실을 복구하는 MinIO의 고가용성 기능입니다.
Erasure Coding에서는 데이터를 여러 개의 데이터 블록과 패리티 블록으로 분할합니다.
전체 블록 수(N) = 데이터 블록 수(K) + 패리티 블록 수(M)로 표현할 수 있습니다.
EC:4의 경우 N = K + 4가 성립합니다. 즉, 4개의 패리티 블록이 생성됨을 의미합니다.
예를 들어 EC:4에서 전체 16개 블록이 있다면, 12개는 데이터 블록(K=12)이고 4개는 패리티 블록(M=4)으로 구성됩니다.
MinIO Operator의 Erasure Coding 설정 (기본값)
erasureCodingParity: 4
이는 데이터 손실 없이 허용되는 드라이브 장애 수를 나타냅니다. 최대 4개의 드라이브 장애까지 데이터 손실 없이 복구 가능합니다.
Prometheus와 Grafana를 사용하여 OS의 상태를 모니터링하고 시각화합니다.
MinIO Operator에서는 기본적으로 클러스터, 버킷, 노드 등의 상태 메트릭을 수집할 수 있게 exporter 설정을 제공합니다.
Prometheus Operator를 먼저 설치했다면, 다음 문서를 참고하여 설정 가능합니다. MinIO 메트릭 수집 방법
알람은 Prometheus와 함께 설치한 AlertManager를 이용하여 설정한 룰에 맞춰 발생시킵니다.
OS는 위 사이트에서 제공하는 알람 설정을 기본으로 추가 룰을 등록해 사용합니다.
디스크 용량 부족 및 노드 확장
스토리지 서비스를 운영하면서 가장 쉽게 발생할 수 있는 문제가 디스크 사용량 증가에 따른 용량 부족입니다.
연간 디스크 사용량 예측을 통해 미리 디스크 가용량을 확보하는 정책을 취하고 있지만, 만일의 상황에 대비하여 '모니터링 및 알람'에서 디스크 가용량의 80% 이상 사용 시 알람을 발생하게 했고,
해당 알람 발생 시 Kubernetes 노드(디스크)를 추가하여 대응합니다.
디스크 장애 및 노드 장애 대응
디스크 장애와 노드 장애(CPU, 메모리) 역시 스토리지 운영 시 자주 발생할 수 있는 문제입니다.
디스크 고가용성을 위해 EC:4 설정으로 동시에 디스크 4개가 장애가 일어나지 않는다면 데이터 유실 없이 안정적으로 서비스할 수 있습니다.
또한, Kubernetes 클러스터가 제공하는 노드 장애 처리 절차를 통해 동시에 2개 노드가 장애가 아니면 무중단 서비스가 가능합니다.
'모니터링 및 알람'에서 디스크나 노드에 장애가 발생 시 알람을 발생시키게 했고, 인프라의 서버 모니터링 시스템이 상태를 관리하므로 빠른 대응이 가능합니다.
네트워크 및 디스크 I/O 문제
OS에서의 읽기/쓰기 작업은 하드웨어(네트워크 카드, 디스크 액세스 속도) 성능에 따라 달라집니다.
OS처럼 하드디스크를 스토리지로 사용하는 케이스에 대한 성능 테스트 및 그 결과는 MinIO의 성능 벤치마크 문서에 잘 정리되어 있습니다.
다만 동시 접속자가 일정 수준 이상일 때 어느 정도의 성능을 보이는지에 대한 충분한 테스트나 검증은 아직 이루어지지 않았으며,
이는 지속적으로 진행하여 네트워크 및 디스크 I/O 문제 발생을 사전에 방지하려 합니다.
S3 호환 API 제공
MinIO를 이용해 구축한 OS는 자체적으로 S3 호환 API를 제공하며,
AWS S3 클라이언트나 호환 클라이언트인 mc(MinIO Client)를 이용해 오브젝트를 업로드, 다운로드, 이동 등 모든 기능을 사용할 수 있습니다.
추가적으로 고려해야 할 부분은 OS를 Kubernetes 위에 구축한 점입니다.
외부에서 Kubernetes 내에 있는 OS에 접근할 수 있게 하려면 Ingress, Service 등을 사내 네트워크 구성에 맞춰 설정해야 합니다.
OS 구성도에서 볼 수 있는 것처럼, 클라이언트는 가상 IP(VIP)와 통신만 하면 S3 호환 API가 처리될 수 있게
인프라 및 보안 담당자들과 협조하여 네트워크를 구축했고, 사용자는 이를 쉽게 이용할 수 있게 했습니다.
사내 사용자를 위한 OS 서비스 포털 구축
사내 사용자들이 OS를 간단하게 이용할 수 있도록 서비스 포털을 만들었습니다.
사내 사용자들은 이 포털을 통해 본인 또는 조직이 사용하고자 하는 계정을 생성하고 관리할 수 있습니다.
각 사용자들은 기본적으로 각 계정에 해당하는 버킷만 이용할 수 있습니다.
이 포털 서비스를 통해 각 계정에 할당된 가용량을 늘리거나, 타 계정에 대한 읽기, 쓰기 권한 등을 설정하고, 인증 정보 등을 획득할 수 있습니다.
REST API 서비스
사내 사용자들이 OS에 접근할 수 있는 방법은 두 가지가 있습니다.
하나는 S3 API 호환 클라이언트 프로그램을 이용한 직접 접근(FUSE와 goofys, s3fs-fuse를 이용한 파일시스템 마운트 포함)이고,
다른 하나는 각 사용자 계정을 바탕으로 한 REST API 사용을 통한 접근입니다.
실제 OS 서비스에서는 데이터인프라팀만 직접 접근을 허용(개별 요청을 통한 예외적인 허용 가능)하고, 나머지 모든 사용자 및 조직에게는 REST API를 이용한 접근만 허용합니다.
OS는 애초에 데이터인프라팀에서 직접적으로 사용하는 것이 목적이었기 때문에 직접 접근을 허용하지만, 팀에서 관리하는 리소스의 한계가 존재합니다.
사내 다른 조직 사용자들이 사용하면서 발생하는 이슈를 처리하려면 인증, 인가 등의 제약을 둘 수밖에 없습니다.
이번 글에서는 대규모 데이터 저장과 관리의 필요성을 해결하기 위한 MinIO 기반 사내 스토리지 서비스 구축 과정을 다루었습니다.
기존 시스템의 한계를 보완하고, 효율적인 데이터 저장과 공유를 위해 Kubernetes 환경에서 MinIO를 활용한 오브젝트 스토리지를 구축하였습니다.
이를 통해 보안 강화, 비용 절감, 데이터 공유의 효율성을 동시에 달성할 수 있었습니다.
특히, S3 호환성 덕분에 기존 애플리케이션과의 통합이 용이하며, Kubernetes를 통해 확장성과 안정성을 갖춘 시스템을 구현할 수 있었습니다.
앞으로도 이러한 인프라 개선을 통해 데이터 관리 및 운영 효율성을 극대화할 수 있기를 기대합니다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.