본문 바로가기
Infra2026년 9월 14일9분 읽기

단일 노드 S3 호환 스토리지 고르기 — MinIO 이후의 선택지 정리

YS
김영삼
조회 142
단일 노드 S3 호환 스토리지 고르기 — MinIO 이후의 선택지 정리

S3 호환 스토리지는 아마존 S3의 API를 흉내 내는 서버다. 개발 환경에서 실제 S3 대신 쓰거나, 온프레미스에 오브젝트 스토리지를 두거나, 클라우드 비용을 줄이려 할 때 쓴다. 중요한 건 "S3 호환"이 하나의 규격이 아니라 스펙트럼이라는 사실이다.

기본 객체 CRUD는 어디서나 되지만, 멀티파트 업로드, 사전 서명 URL, 버전 관리, 객체 잠금, 조건부 요청, 서버 측 암호화, 수명 주기 정책으로 갈수록 구현 편차가 커진다. 선택 기준은 "얼마나 호환되나"가 아니라 "내가 쓰는 기능이 되나"다.

나는 개발 환경과 프로덕션에서 서로 다른 S3 구현을 쓰다가 호되게 당한 적이 있다. 로컬에서는 잘 되던 사전 서명 URL 업로드가 스테이징에서 서명 불일치로 실패했다. 원인은 서명 버전과 경로 스타일(path-style) 접근 방식 차이였다. 그 뒤로는 업로드·다운로드 경로만큼은 반드시 실제 대상에서 검증한다.

후보별 성격

선택지성격장점고려사항
Garage러스트로 작성된 경량 분산 오브젝트 스토어가볍고 운영이 단순, 지역 간 복제 설계기능 범위가 S3 전체는 아님
SeaweedFS대량 소형 파일에 강한 분산 파일 시스템 + S3 게이트웨이작은 객체 처리 성능, 유연한 구성구성 요소가 많아 학습 곡선
Ceph RGW대규모 분산 스토리지의 오브젝트 게이트웨이기능 완성도, 대규모 운영 검증단일 노드 용도로는 과함
LocalStack 등 개발용로컬 개발·테스트 대상설치가 간단, 여러 AWS 서비스 모사프로덕션 용도가 아님
파일시스템 + 정적 서버객체 저장만 필요한 최소 구성가장 단순S3 API가 아니므로 코드 결합
먼저 답할 질문 "왜 S3 호환이 필요한가?"에 명확히 답해야 한다. 개발 편의라면 가벼운 개발용 도구로 충분하다. 데이터 주권이나 비용이 이유라면 운영 부담을 감수할 각오가 필요하다. 단순히 파일을 저장하고 싶은 거라면 오브젝트 스토리지가 아니라 파일 시스템이 답일 수도 있다.

무엇을 검증하고 넘어가야 하나

도입 전에 실제로 돌려 봐야 할 목록이 있다. 아래 항목들은 구현마다 가장 자주 갈리는 지점이다.

호환성 체크리스트
멀티파트 업로드 — 대용량 파일과 이어받기가 필요한 경우 필수
사전 서명 URL(presigned URL) — 서명 버전(SigV4)과 만료 처리
경로 스타일 vs 가상 호스트 스타일 접근 — 클라이언트 설정과 맞물린다
CORS 설정 — 브라우저 직접 업로드를 쓴다면 반드시 확인
버전 관리와 객체 잠금 — 규제 대응이나 실수 복구에 필요하면
조건부 요청(If-Match, If-None-Match) — 낙관적 동시성 제어에 사용
수명 주기 정책 — 오래된 객체 자동 삭제가 필요한 경우
서버 측 암호화와 키 관리 방식
# 호환성 빠른 점검 (AWS CLI로 대상 엔드포인트 테스트)
export AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=...
EP=http://localhost:3900

aws --endpoint-url $EP s3 mb s3://test-bucket
aws --endpoint-url $EP s3 cp ./big.bin s3://test-bucket/   # 멀티파트 동작 확인
aws --endpoint-url $EP s3api list-objects-v2 --bucket test-bucket

# 사전 서명 URL 생성 후 실제 업로드가 되는지
URL=$(aws --endpoint-url $EP s3 presign s3://test-bucket/up.txt --expires-in 300)
curl -X PUT --upload-file ./up.txt "$URL" -v

# 버전 관리 지원 여부
aws --endpoint-url $EP s3api put-bucket-versioning \
  --bucket test-bucket --versioning-configuration Status=Enabled

개발 환경용 구성

개발 환경의 목표는 "프로덕션과 같은 코드 경로를 쓰되, 설정만 바꿔서 로컬을 가리키게 하는 것"이다. 코드에 분기를 넣기 시작하면 그 분기가 버그의 온상이 된다.

# docker-compose.yml (예시 — 엔드포인트만 바꿔 끼운다)
services:
  s3:
    image: <s3-compatible-image>
    ports: ["3900:3900"]
    environment:
      - RPC_SECRET=devsecret
    volumes:
      - s3data:/data

  app:
    build: .
    environment:
      - S3_ENDPOINT=http://s3:3900
      - S3_FORCE_PATH_STYLE=true     # 로컬은 대개 경로 스타일
      - S3_REGION=us-east-1
volumes:
  s3data:

환경 변수로 엔드포인트와 경로 스타일만 제어하면, 같은 코드가 로컬·스테이징·프로덕션에서 동작한다. SDK 대부분이 이 두 설정을 지원한다.

프로덕션 자체 운영을 고민한다면

비용 계산에서 자주 빠뜨리는 항목들이 있다. 스토리지 단가만 비교하면 셀프 호스팅이 항상 싸 보이지만, 실제 비용은 다른 곳에서 나온다.

셀프 호스팅의 이점
  • 전송·요청 요금 없음
  • 데이터 위치 통제
  • 대용량에서 단가 우위
  • 네트워크 내부 지연 감소
실제로 드는 비용
  • 디스크 이중화와 교체 운영
  • 백업과 복구 리허설
  • 모니터링·알림 체계 구축
  • 업그레이드·장애 대응 인력 시간
  • 재해 시 복구 책임이 전부 내부

경험상 손익분기는 용량보다 운영 인력에서 결정된다. 스토리지를 돌볼 사람이 없으면, 싼 단가는 장애 한 번으로 사라진다. 반대로 이미 온프레미스 인프라와 운영 인력이 있다면 셀프 호스팅의 경제성은 분명하다.

데이터 안전 설계

1
복제 수준 결정
단일 노드는 디스크 장애 = 데이터 손실이다. 최소한 RAID나 다중 노드 복제를 전제로 한다.
2
외부 백업 경로 확보
같은 시스템 안의 복제는 백업이 아니다. 다른 매체·다른 위치로 나가는 경로가 있어야 한다.
3
복구 리허설
스냅샷에서 실제로 객체를 되살려 애플리케이션이 읽을 수 있는지까지 확인한다.
4
접근 제어 점검
버킷 정책과 키 스코프를 분리한다. 애플리케이션 키가 삭제 권한을 가질 필요가 있는지 다시 본다.
5
용량 감시
오브젝트 스토리지는 조용히 꽉 찬다. 사용률 알림을 임계값 여러 단계로 걸어 둔다.

마이그레이션 시 주의

구현을 옮길 때 가장 많이 깨지는 건 메타데이터다. 콘텐츠 타입, 사용자 정의 메타데이터, ACL, 버전 이력은 단순 복사로 옮겨지지 않는 경우가 있다. rclone 같은 도구를 쓰면 대부분 처리되지만, 반드시 샘플로 검증한 뒤 전체를 옮겨야 한다.

# rclone 으로 구현 간 이전 (메타데이터 보존 옵션 확인 필수)
rclone copy old:bucket new:bucket \
  --transfers 16 --checkers 32 \
  --s3-upload-concurrency 8 \
  --metadata --progress

# 이전 후 검증: 개수와 체크섬 비교
rclone check old:bucket new:bucket --one-way --combined /tmp/diff.txt

자주 묻는 질문

S3 호환이라고 하면 모든 기능이 같은가요?

아닙니다. 기본 객체 조작은 대부분 동일하지만 멀티파트 업로드, 사전 서명 URL, 버전 관리, 객체 잠금, 조건부 요청, 수명 주기 정책 등은 구현마다 지원 범위가 다릅니다. 사용하는 기능 목록을 기준으로 직접 검증해야 합니다.

개발 환경용과 프로덕션용을 같은 것으로 써야 하나요?

반드시 같을 필요는 없지만, 사용하는 기능의 동작이 같은지 검증해야 합니다. 특히 사전 서명 URL과 경로 스타일 접근은 구현 간 차이로 자주 문제가 생기므로, 업로드 경로만은 스테이징에서 실제 대상으로 확인하세요.

단일 노드로 운영해도 괜찮나요?

개발·테스트나 손실을 감수할 수 있는 데이터라면 가능합니다. 프로덕션 데이터라면 디스크 장애가 곧 손실이므로 최소한 이중화와 외부 백업 경로가 필요합니다. 복제와 백업은 다른 개념이라는 점을 분리해서 설계하세요.

셀프 호스팅이 클라우드보다 싼가요?

스토리지 단가만 보면 그럴 수 있지만, 디스크 교체·백업·모니터링·장애 대응 인력 시간을 포함하면 달라집니다. 이미 온프레미스 운영 역량이 있는 조직에서는 경제성이 뚜렷하고, 그렇지 않으면 총비용이 더 클 수 있습니다.

브라우저에서 직접 업로드하려면 무엇이 필요한가요?

사전 서명 URL 지원과 CORS 설정이 필수입니다. 서명 버전 호환과 만료 시간 처리도 확인해야 하며, 업로드 후 서버 측에서 객체 검증(크기·타입·바이러스 검사 등)을 거치는 흐름을 설계하는 것이 안전합니다.

다른 구현으로 옮길 때 주의할 점은요?

객체 본문보다 메타데이터가 문제가 됩니다. 콘텐츠 타입, 사용자 정의 메타데이터, 접근 제어, 버전 이력이 그대로 옮겨지지 않을 수 있으니 샘플 이전 후 검증하고, 전체 이전 뒤에는 개수와 체크섬을 비교하세요.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록