TL;DR

  • s3 bucket 개념의 핵심 개념과 적용 범위를 정리
  • 등장 배경과 필요한 이유를 요약
  • 주요 특징과 실무 활용 포인트를 정리

1. 개념

s3 bucket 개념의 핵심 개념과 범위를 간단히 정의하고, 왜 이 문서가 필요한지 요점을 잡습니다.

2. 배경

이 주제가 등장하게 된 배경과 문제 상황, 기술적 맥락을 짚습니다.

3. 이유

왜 이 접근이 필요한지, 기존 대안의 한계나 목표를 설명합니다.

4. 특징

문서에서 다루는 주요 구성요소와 실전 적용 포인트를 정리합니다.

5. 상세 내용

S3 Bucket - 객체 스토리지의 논리적 컨테이너

작성일: 2026-03-04 카테고리: Cloud / AWS 포함 내용: S3 Bucket, Object Storage, Flat Namespace, Prefix, Delimiter, Bucket Policy, IAM Policy, ACL, Versioning, Region, DNS, Virtual-hosted-style, Path-style, Block Public Access, Lifecycle Policy, Replication, CRR, SRR, Object Lock, WORM, Encryption, SSE-S3, SSE-KMS


1. Bucket이란 정확히 무엇인가

정의

S3 Bucket은 객체(Object)를 담는 논리적 컨테이너(container)다. 전통적인 파일시스템의 디렉토리와 외형상 비슷해 보이지만, 내부 구조와 동작 방식은 근본적으로 다르다.

┌─────────────────────────────────────────────────────┐
│                    S3 Bucket                         │
│           (논리적 네임스페이스 단위)                 │
│                                                     │
│  ┌───────────────────────────────────────────────┐  │
│  │  Object = Key + Value + Metadata              │  │
│  │                                               │  │
│  │  Key:   "logs/2024/01/app.log"  ← 고유 식별자│  │
│  │  Value: [실제 데이터 바이트]                   │  │
│  │  Metadata: Content-Type, 사용자 정의 등       │  │
│  └───────────────────────────────────────────────┘  │
│                                                     │
│  ※ 폴더(directory)는 실제로 존재하지 않음          │
│  ※ "/"는 단지 키 문자열의 일부일 뿐                │
└─────────────────────────────────────────────────────┘

파일시스템 디렉토리와의 차이

비교 항목 파일시스템 디렉토리 S3 Bucket
계층 구조 물리적 트리 구조 존재 완전한 flat namespace (평면 구조)
중첩 디렉토리 안에 디렉토리 가능 Bucket 안에 Bucket 불가
위치 특정 OS, 디스크에 종속 특정 AWS Region에 종속
식별자 경로(path)로 식별 전 세계 유일한 이름 (globally unique)
용량 한도 디스크 용량에 제한 사실상 무제한 (단일 객체 최대 5TB)
접근 방식 OS syscall (open, read, write) HTTP REST API (GET, PUT, DELETE)

2. Flat Namespace - 폴더는 허상이다

실제 구조: 완전한 평면(Flat)

S3 내부에서는 Bucket 안의 모든 객체가 단순한 키-값 저장소(key-value store)로 존재한다. 폴더(directory)는 실제로 존재하지 않는다.

S3 내부 실제 저장 구조 (모든 것이 평면):

┌──────────────────────────────────────────┐
│ Key (문자열)              │ Value (데이터)│
│───────────────────────────│──────────────│
│ "logs/2024/01/app.log"   │ [바이트...]   │
│ "logs/2024/02/app.log"   │ [바이트...]   │
│ "images/profile.jpg"     │ [바이트...]   │
│ "readme.txt"             │ [바이트...]   │
└──────────────────────────────────────────┘

"logs/"라는 폴더는 존재하지 않는다.
"/"는 키 문자열의 일부일 뿐이다.

Prefix와 Delimiter로 폴더를 “흉내” 내는 방식

AWS Console이나 CLI에서 마치 폴더처럼 보이는 것은, List 요청 시 PrefixDelimiter 파라미터로 클라이언트 측에서 가상 계층을 시뮬레이션하기 때문이다.

요청: ListObjects(Bucket="my-bucket", Prefix="logs/", Delimiter="/")

응답:
├── Contents: []  (logs/ 바로 하위에 직접 있는 객체)
├── CommonPrefixes:
│   └── "logs/2024/"  ← 하위 경로를 하나로 묶어 반환

중요한 함의:

  • “폴더”를 삭제하면 실제로는 해당 prefix로 시작하는 모든 객체가 삭제된다
  • 빈 “폴더”를 만들면 myfolder/라는 0바이트 객체가 생성될 뿐
  • 폴더 자체에 권한을 설정하는 개념이 없다 (IAM/버킷 정책은 prefix 기반)

3. 이름 규칙 - 왜 이렇게 엄격한가

Bucket 이름은 단순한 식별자가 아니라 DNS 호스트명의 일부로 사용되기 때문에 엄격한 규칙이 적용된다.

필수 규칙

규칙 상세
길이 3자 이상, 63자 이하
허용 문자 소문자(a-z), 숫자(0-9), 하이픈(-), 마침표(.)
시작/끝 반드시 소문자 또는 숫자
금지 연속 마침표(..), IP 주소 형식, 대문자, 언더스코어

금지 접두사/접미사

유형 예시 이유
접두사 xn--, sthree-, amzn-s3-demo- 예약어
접미사 -s3alias, --ol-s3, .mrap Access Point, Multi-Region용

글로벌 유니크 (Global Uniqueness)

┌─────────────────────────────────────────────────────────┐
│  전 세계 모든 AWS 계정, 모든 Region을 통틀어             │
│  단 하나의 이름만 존재 가능                              │
│                                                         │
│  "my-bucket" 이름을 누군가 사용 중이면                  │
│  → 전 세계 어떤 AWS 사용자도 해당 이름 사용 불가        │
│                                                         │
│  이유: Bucket 이름이 DNS 서브도메인으로 사용됨           │
│  my-bucket.s3.amazonaws.com ← DNS 수준 유일성 필요      │
└─────────────────────────────────────────────────────────┘

Transfer Acceleration 제약

HTTPS + virtual-hosted-style 사용 시 이름에 마침표(.) 포함 금지. SSL 와일드카드 인증서(*.s3.amazonaws.com)가 다단계 서브도메인을 처리할 수 없기 때문.


4. Bucket과 Region의 관계

이름은 전역, 데이터는 로컬

┌─────────────────────────────────────────────────────┐
│                                                     │
│  이름(Name): 전 세계 전역 유일 (Global namespace)   │
│  데이터(Data): 지정한 Region에만 저장 (Regional)    │
│                                                     │
│  ※ 이 두 가지를 혼동하면 안 된다                    │
│                                                     │
│  us-east-1에 생성된 버킷의 데이터는                 │
│  명시적 복제 설정 없이는 절대                        │
│  ap-northeast-2로 이동하지 않는다.                   │
└─────────────────────────────────────────────────────┘
  • Bucket은 생성 시 특정 Region에 묶이며, 이후 변경 불가
  • 데이터는 해당 Region의 여러 AZ에 걸쳐 자동 복제 (내구성 99.999999999%)
  • Region 경계를 넘으려면 CRR(Cross-Region Replication) 명시 설정 필요

데이터 주권(Data Sovereignty)

GDPR, 금융 규제 등 데이터 거주 요구사항을 충족하려면 해당 Region에 Bucket을 생성하면 된다. 한국 데이터 → ap-northeast-2 (서울 리전).


5. URL 구조

Virtual-hosted-style (현재 권장)

https://{bucket-name}.s3.{region}.amazonaws.com/{key}

예시:
https://my-photos.s3.us-east-1.amazonaws.com/2024/vacation.jpg
       ─────────                              ──────────────
       Bucket 이름이 서브도메인에               Key

Path-style (레거시, 단계적 폐기)

https://s3.{region}.amazonaws.com/{bucket-name}/{key}

예시:
https://s3.us-east-1.amazonaws.com/my-photos/2024/vacation.jpg
                                   ─────────
                                   Bucket 이름이 경로에

왜 Virtual-hosted-style로 전환?

  • DNS 기반 라우팅으로 수십억 개의 버킷 처리 가능
  • 각 버킷이 독립된 DNS 엔드포인트 → 장애 격리(fault isolation) 향상
  • CDN, SSL 인증서 관리에 더 적합
  • 중앙화된 path-style의 단일 장애점(SPOF) 위험 제거

6. 접근 제어 - Bucket Policy vs IAM Policy vs ACL

┌─────────────────────────────────────────────────────────┐
│              S3 접근 제어 3계층                          │
│                                                         │
│  ┌─────────────────┐                                   │
│  │ S3 Block Public │ ← 최상위 레이어 (모든 것 덮어씀) │
│  │ Access          │                                   │
│  └────────┬────────┘                                   │
│           │                                             │
│  ┌────────┴────────┐  ┌──────────────┐  ┌──────────┐  │
│  │ Bucket Policy   │  │ IAM Policy   │  │ ACL      │  │
│  │ (리소스 기반)   │  │ (자격증명    │  │ (레거시) │  │
│  │                 │  │  기반)       │  │          │  │
│  │ "누가 이 버킷에 │  │ "이 사용자가 │  │ 미리정의 │  │
│  │  접근 가능?"   │  │  뭘 할 수    │  │ 된 권한  │  │
│  │                 │  │  있나?"     │  │ 세트만   │  │
│  │ Cross-account  │  │             │  │          │  │
│  │ 직접 가능      │  │ S3 포함     │  │ 비권장   │  │
│  │                 │  │ 모든 서비스 │  │          │  │
│  └─────────────────┘  └──────────────┘  └──────────┘  │
│                                                         │
│  평가: 기본 DENY → Allow 합집합 → 명시적 DENY 우선     │
└─────────────────────────────────────────────────────────┘
항목 Bucket Policy IAM Policy ACL
부착 대상 Bucket User/Role Bucket 또는 Object
크기 제한 20KB 5KB -
Cross-account 직접 가능 양쪽 모두 설정 필요 가능 (제한적)
조건 설정 풍부한 Condition 풍부한 Condition 불가
권장 여부 권장 권장 비권장 (레거시)

7. Bucket Versioning

개념

동일한 키(이름)를 가진 객체의 여러 버전을 같은 버킷 안에 보존하는 기능.

photo.jpg (Upload #1) → Version ID: 111abc
photo.jpg (Upload #2) → Version ID: 222def  ← 이전 버전도 보존!
photo.jpg (Delete)    → Delete Marker 삽입   ← 실제 삭제 아님!

상태값

상태 설명
Unversioned (기본) Versioning 비활성화
Enabled 모든 객체에 버전 ID 부여
Suspended 신규는 버전 관리 안 함, 기존 버전은 보존

주의: EnabledUnversioned 복귀 불가. Suspended로만 전환 가능.

왜 쓰는가

  • 실수로 덮어쓴 파일 복구: 이전 버전 자동 보존
  • 실수로 삭제된 파일 복구: Delete Marker만 삽입됨, 마커 삭제 시 복구
  • 감사 추적(Audit Trail): 파일 변경 이력 보존
  • CRR 전제 조건: Cross-Region Replication은 Versioning 필수

비용 주의

각 버전은 완전한 별도 객체로 과금된다 (diff가 아님). 1MB 파일 × 100번 수정 = 최대 100MB 과금. Lifecycle Policy로 오래된 버전 자동 삭제/이전 필수.


8. Bucket 레벨 설정들

설정 설명
암호화 기본 SSE-S3(AES-256) 자동 적용. SSE-KMS(감사 추적), SSE-C(고객 키), DSSE-KMS(이중 암호화) 선택 가능
서버 접근 로깅 모든 요청을 다른 S3 버킷에 로그 기록 (IP, 시간, 상태코드)
수명 주기 정책 날짜/경과일 기반 자동 작업. Transition(클래스 변경), Expiration(자동 삭제)
복제 CRR(Cross-Region), SRR(Same-Region). Versioning 활성화 필수
CORS 브라우저 다른 도메인 접근 허용. 정적 웹사이트 호스팅 시 필수
이벤트 알림 생성/삭제/복원 이벤트 → SNS, SQS, Lambda 전달
Object Lock WORM 모델. Compliance Mode(누구도 삭제 불가), Governance Mode(특정 권한만 삭제)
정적 웹사이트 Bucket을 정적 웹사이트로 서빙. CloudFront와 결합 시 HTTPS+CDN
Transfer Acceleration CloudFront 엣지 경유 업로드 속도 향상
Requester Pays 다운로드하는 사람이 전송 비용 부담
태깅 최대 10개 key-value. 비용 배분, 접근 제어 조건에 활용

9. 계정당 Bucket 제한

구분 한도
기본 한도 10,000개 (2024년 11월 상향, 기존 100개)
최대 요청 가능 1,000,000개
무료 생성 최초 2,000개 무료
유료 구간 2,000개 초과 시 소액 월정 요금

10. 왜 “Bucket”이라는 이름인가

AWS가 공식적으로 명시한 문서는 없으나 다음 배경에서 추론 가능:

  1. 일상 언어: “bucket” = 무언가를 담는 용기 → “객체를 담는 통” 메타포
  2. 컴퓨터 과학: 해시 테이블에서 충돌 처리 단위를 bucket이라 부름. S3의 flat key-value 구조와 개념적 유사
  3. 파일시스템 용어 회피: 새로운 패러다임(객체 스토리지)을 위해 directory, folder 대신 중립적 용어 선택
  4. 업계 표준화: GCS도 “bucket”, Azure는 “container” 채택. S3가 사실상 표준

11. 흔한 실수와 보안 사고

1. 퍼블릭 노출 사고 (가장 심각)

S3 역사상 최악의 사고 유형. FedEx, Verizon, Dow Jones 등 대형 기업들이 잘못된 설정으로 민감 데이터 공개 노출.

반드시 활성화해야 하는 4가지 Block Public Access 설정:

BlockPublicAcls:         true  ← 퍼블릭 ACL 적용 차단
IgnorePublicAcls:        true  ← 기존 퍼블릭 ACL 무시
BlockPublicPolicy:       true  ← 퍼블릭 버킷 정책 차단
RestrictPublicBuckets:   true  ← 퍼블릭 버킷 접근 제한

2. "Principal": "*" 실수

"Principal": "*"  //  세계 익명 사용자 포함 - 매우 위험!

인증된 AWS 사용자뿐 아니라 인터넷의 모든 익명 사용자를 포함한다.

3. 이름 선점(Squatting)

  • 삭제된 버킷 이름이 다른 사람에게 즉시 선점 가능
  • 이름에 회사/서비스명 포함 시 URL로 비즈니스 로직 추론 가능

4. 버킷 삭제 불가

  • 내부 모든 객체 + 모든 버전 + Delete Marker 먼저 삭제해야 함
  • Versioning 활성화 시 특히 주의

5. 덮어쓰기 복구 불가

  • Versioning 비활성화 상태에서 같은 키로 PUT → 이전 객체 영구 삭제
  • 복구 불가능. 미리 Versioning 활성화 필수

6. Region 선택 실수

  • 생성 후 Region 변경 불가
  • 잘못된 Region → Cross-Region 전송 비용 + 데이터 주권 위반 가능

7. IaC 한 줄의 파급력

acl = "public-read"  // 이 한 줄이 수백 개 버킷을 동시에 공개로 만들 수 있음

SCPs(Service Control Policies)와 코드 리뷰 조합 필수.


관련 키워드

S3 Bucket, Object Storage, Flat Namespace, Prefix, Delimiter, Bucket Policy, IAM Policy, ACL, Versioning, Delete Marker, Region, DNS, Virtual-hosted-style, Path-style, Block Public Access, Lifecycle Policy, Replication, CRR, SRR, Object Lock, WORM, Encryption, SSE-S3, SSE-KMS, Transfer Acceleration, Requester Pays, CORS, 정적 웹사이트, Global Uniqueness, Firecracker