AWS (EBS, S3)

엄경문·2026년 1월 15일

AWS

목록 보기
3/10

들어가며

이번에는 스토리지에 대해 공부하고 실습을 진행할 것이다. EC2는 언제든 죽거나 교체될 수 있는 소모품이라 데이터를 서버안에만 두면 데이터가 같이 날아가거나 동기화의 여러움이 생긴다. 이러한 문제를 해결하기 위해 스토리지를 사용하는데 이번시간에는 스토리지 종류에 대해 공부하고 실습으로 확인할 것 이다.

스토리지

스토리지

스토리지의 종류는 크게 3가지로 구분된다.

1) Block Storage (블록 스토리지)

  • 데이터를 일정한 크기의 블록으로 쪼개 저장
  • 블록의 주소로 바로 접근 → 속도 빠름 랜덤 I/O에 강함
  • OS 입장에선 디스크처럼 보임(파티션/파일시스템을 OS가 직접 구성)
  • 특징: 서로 다른 OS에서도 디스크 방식으로 접근 가능(파일시스템 포맷은 OS 호환 필요)
    대표: EBS

2) File Storage (파일 스토리지)

  • 데이터를 파일/폴더(계층 구조) 로 저장
  • NAS처럼 SMB/NFS 프로토콜로 공유 폴더 접근
  • 파일/폴더가 많아질수록 탐색(디렉토리) 성능 저하 가능
  • 프로토콜/파일시스템에 따라 OS 제약이 생길 수 있음
    대표: EFS(리눅스 NFS), FSx(윈도우 SMB 등)

3) Object Storage (오브젝트 스토리지)

  • 데이터를 오브젝트(객체) 단위로 저장
  • 애플리케이션 레벨(API) 로 접근(파일시스템 마운트 개념 아님)
  • 확장 제약이 거의 없음 → 원하는 만큼 사실상 무한 확장
  • 각 오브젝트는 보통 Key(이름) + Value(데이터) + Metadata 형태
    대표: S3

EBS(Elastic Block Store)

EBS

EBS에 대해 자세히 알아보면

  • EC2 인스턴스에 연결해 사용할수있는 네트워크 기반 Block Storage 서비스
  • 데이터볼륨, 스냅샷에 대한 암호화 지원
  • 하나의 인스턴스에 연결하여 사용하며,EC2 인스턴스와별개로관리
  • 특정 가용영역에서만 생성되기 때문에 가용영역 간 EBS 볼륨 공유 불가
  • 디스크용량을 희망하는만큼 프로비저닝하여사용
  • gp2, gp3 SSD 를 많이 사용

EBS에 대해 알아보면 비슷한 개념인 Instance Storage 가 있게된다.

  • EBS: EC2에 붙여 쓰는 네트워크 디스크 (인스턴스와 분리)
  • Instance Storage: EC2 서버에 딸려있는 로컬 디스크 (인스턴스에 종속)

쉽게 말하면 데이터가 남아야한다 (영구) -> EBS
빠르지만 날아가도 된다 (임시:캐시) -> Instance Storage
로 이해하면쉽다.


EBS Snapshot

특정 시점의 EBS볼륨에 저장된 데이터를 복사해둔 데이터 (백업데이터)이다.
스냅샷을 저장하는 방식은 크게 2가지가 있다.

Full(전체) 방식

  • 매번 전체 데이터를 통째로 백업
  • 장점: 복구할 때 가장 단순 (마지막 Full 하나만 있으면 됨)
  • 단점: 백업할수록 시간/저장공간/비용이 많이 듦

증분(Incremental) 방식

  • 첫 1번만 전체(Full) 백업
  • 그 다음부터는 지난 백업 이후 변경된 데이터만 저장
  • 장점: 백업 시간이 짧고 저장공간이 효율적(비용 절감)
  • 단점: 복구 시 보통 체인이 필요

그럼 스냅샷은 백업데이터라 생각하면 AMI 랑 비슷한것을 볼 수 있다.
하지만 실질적으로 비교해보면

EBS Snapshot은 디스크(볼륨) 데이터의 특정 시점 백업이다.
AMI 는 인스턴스를 다시 만들 수 있는 서버 이미지이다.

예를들어 DB 데이터/파일만 백업하고 싶다하면 Snapshot 웹서버를 동일 구성으로 여러 대 배포하고 싶다하면 AMI 를 사용한다.

실습

EC2→인스턴스→WEB SERVER 스토리지 → 볼륨 → 볼륨 수정 (20기가로 수정)

EC2 서버내부에서 볼륨이 늘어났나 확인하면

[root@ip-10-0-40-82 scripts]# df -h
Filesystem        Size  Used Avail Use% Mounted on
devtmpfs          4.0M     0  4.0M   0% /dev
tmpfs             459M     0  459M   0% /dev/shm
tmpfs             184M  404K  183M   1% /run
/dev/nvme0n1p1    8.0G  3.0G  5.0G  38% /
tmpfs             459M     0  459M   0% /tmp
/dev/nvme0n1p128   10M  1.3M  8.7M  13% /boot/efi
tmpfs              92M     0   92M   0% /run/user/1000
[root@ip-10-0-40-82 scripts]# lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1       259:0    0  20G  0 disk 
├─nvme0n1p1   259:1    0   8G  0 part /
├─nvme0n1p127 259:2    0   1M  0 part 
└─nvme0n1p128 259:3    0  10M  0 part /boot/efi
[root@ip-10-0-40-82 scripts]# sudo growpart /dev/nvme0n1 1 -> 파티션 할당
CHANGED: partition=1 start=24576 old: size=16752607 end=16777183 new: size=41918431 end=41943007
[root@ip-10-0-40-82 scripts]# df -h
Filesystem        Size  Used Avail Use% Mounted on
devtmpfs          4.0M     0  4.0M   0% /dev
tmpfs             459M     0  459M   0% /dev/shm
tmpfs             184M  404K  183M   1% /run
/dev/nvme0n1p1    8.0G  3.0G  5.0G  38% /
tmpfs             459M     0  459M   0% /tmp
/dev/nvme0n1p128   10M  1.3M  8.7M  13% /boot/efi
tmpfs              92M     0   92M   0% /run/user/1000
[root@ip-10-0-40-82 scripts]# sudo xfs_growfs -d / -> 할당된 파티션에 파일시스템 만들기
meta-data=/dev/nvme0n1p1         isize=512    agcount=2, agsize=1047040 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=0, rmapbt=0
         =                       reflink=0    bigtime=1 inobtcount=1 nrext64=0
         =                       exchange=0  
data     =                       bsize=4096   blocks=2094075, imaxpct=25
         =                       sunit=128    swidth=128 blks
naming   =version 2              bsize=16384  ascii-ci=0, ftype=1, parent=0
log      =internal log           bsize=4096   blocks=16384, version=2
         =                       sectsz=4096  sunit=4 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 2094075 to 5239803
[root@ip-10-0-40-82 scripts]# df -h -> 최종
Filesystem        Size  Used Avail Use% Mounted on
devtmpfs          4.0M     0  4.0M   0% /dev
tmpfs             459M     0  459M   0% /dev/shm
tmpfs             184M  404K  183M   1% /run
/dev/nvme0n1p1     20G  3.0G   17G  16% /
tmpfs             459M     0  459M   0% /tmp
/dev/nvme0n1p128   10M  1.3M  8.7M  13% /boot/efi
tmpfs              92M     0   92M   0% /run/user/1000
[root@ip-10-0-40-82 scripts]# 

위와 같이 추가되는것을 볼 수 있다. 하지만 리눅스의 경우 마운트와 파일시스템을 지정해야해서 AWS 에서 바로 추가해도 리눅스에서 df -h 에서는 확인이 안될 수 있다.

EBS 추가해서 기존 web 서버에 부착
EC2-> Elastic Block Store
볼륨 생성 후 연결

확인해보면

추가된것을 볼 수 있다.
다시 마운트해주면

[root@ip-10-0-40-82 dev]# sudo mkdir /data
[root@ip-10-0-40-82 dev]# sudo mkfs.xfs /dev/nvme1n1  -> 파일 시스템 생성
meta-data=/dev/nvme1n1           isize=512    agcount=16, agsize=163840 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1    bigtime=1 inobtcount=1 nrext64=0
         =                       exchange=0  
data     =                       bsize=4096   blocks=2621440, imaxpct=25
         =                       sunit=1      swidth=1 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1, parent=0
log      =internal log           bsize=4096   blocks=16384, version=2
         =                       sectsz=512   sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@ip-10-0-40-82 dev]# sudo mount /dev/nvme1n1 /data -> 마운트
[root@ip-10-0-40-82 dev]# df -h
Filesystem        Size  Used Avail Use% Mounted on
devtmpfs          4.0M     0  4.0M   0% /dev
tmpfs             459M     0  459M   0% /dev/shm
tmpfs             184M  412K  183M   1% /run
/dev/nvme0n1p1     20G  3.0G   17G  16% /
tmpfs             459M     0  459M   0% /tmp
/dev/nvme0n1p128   10M  1.3M  8.7M  13% /boot/efi
tmpfs              92M     0   92M   0% /run/user/1000
/dev/nvme1n1       10G  104M  9.9G   2% /data

하지만 리눅스에서는 이렇게 마운트하면 ec2가 재부팅 될때 초기화된다.
영구적으로하기위해

[root@ip-10-0-40-82 dev]# sudo blkid
/dev/nvme0n1p1: LABEL="/" UUID="497419d5-2417-43e6-927d-6777766bb648" BLOCK_SIZE="4096" TYPE="xfs" PARTLABEL="Linux" PARTUUID="303326ff-63a6-4fc3-aedc-62dab0bfb196"
/dev/nvme0n1p128: SEC_TYPE="msdos" UUID="A1F2-F73A" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="2221ec8e-a2a0-4419-b79c-a572a7ff1b42"
/dev/nvme0n1p127: PARTLABEL="BIOS Boot Partition" PARTUUID="48969b33-1a9d-45f1-8304-408abc80eee3"
/dev/nvme1n1: UUID="9e611402-f641-45d9-b6a2-8d699cdae0c6" BLOCK_SIZE="512" TYPE="xfs"
[root@ip-10-0-40-82 dev]# vi /etc/fstab -> 접속

영구적으로 mount 해줄수 있다.


스냅샷 생성
EC2 web 기본 볼륨으로(작업) → 스냅샷 생성

스냅샷에서 새로운 볼륨생성

스냅샷으로 만든 볼륨 연결

Bastion 서버에 생성

root@ip-10-0-1-211:~# df -h
Filesystem       Size  Used Avail Use% Mounted on
/dev/root         96G  9.2G   87G  10% /
tmpfs            7.7G  8.0K  7.7G   1% /dev/shm
tmpfs            3.1G  1.2M  3.1G   1% /run
tmpfs            5.0M     0  5.0M   0% /run/lock
efivarfs         128K  3.6K  120K   3% /sys/firmware/efi/efivars
/dev/nvme0n1p16  881M   89M  730M  11% /boot
/dev/nvme0n1p15  105M  6.2M   99M   6% /boot/efi
tmpfs            1.6G   16K  1.6G   1% /run/user/0
/dev/nvme1n1p1    20G  3.0G   17G  16% /web_directory

스냅샷 주기정책

내일 아침 9시가 지나면 자동으로 스냅샷 하나가 추가된다.
그러다가 6일차에 자동으로 삭제돼서 5개를 유지 -> 스냅샷 비용이 비싸진않지만 엄청 많은 과거값이 필요한게 아니면 스냅샷 갯수를 많이 해두지않아도 된다.

Simple Storage Service

S3

Amazon S3(Simple Storage Service) 인터넷(웹) 방식으로 어디서나 접근하는 오브젝트 스토리지이다.

중요한 특징으로는

1. 거의 무제한 확장

  • 디스크 용량을 미리 프로비저닝하지 않고
  • 데이터를 넣으면 넣는 만큼 저장됨(확장 제약이 매우 적음)

2. 사용한 만큼 과금

  • 저장한 용량(GB)만큼 비용
  • 그리고 요청(업/다운로드 요청 수), 전송량(트래픽) 에도 비용이 붙을 수 있음

3. 접근 방식: 파일시스템이 아니라 API

  • 윈도우 폴더/리눅스 디렉토리처럼 OS가 마운트해서 쓰는 디스크가 아니라 REST API(HTTP) 로 업로드/다운로드/조회함
  • 콘솔(GUI)도 있지만 내부적으로는 API 호출이라고 보면 됨
  • 그래서 프로그램 설치해서 실행하는 장소 같은 개념이 아니라 단순 저장소에 가까움

4. 높은 내구성/가용성

  • S3는 매우 높은 수준의 내구성과 가용성을 목표로 설계된 서비스로 알려져 있고 운영 관점에서 데이터를 오래 안전하게 두는 저장소로 많이 씀

S3의 보안과 권한으로는 크게 4가지가 있다.

1) Bucket Policy (버킷 정책)

  • 무엇: JSON 정책 문서를 버킷에 인라인으로 붙임
  • 적용 범위: 버킷 + 객체(리소스 단위)
  • 제어 수준: 조건(Condition)까지 포함한 세밀한 제어 가능
  • 주 사용처
    • 특정 IP에서만 접근 허용, 특정 VPC Endpoint만 허용 등 조건 기반 제어
    • 교차 계정(Cross-account) 접근 허용을 버킷에 명확히 걸어줄 때 자주 씀

2) ACL (Access Control List)

  • 무엇: 객체/버킷에 붙는 간단한 권한 목록
  • 적용 범위: 주로 객체 단위(Object)
  • 제어 수준: 읽기/쓰기 같은 기본 권한 위주 조건 기반 제어 약함
  • 주 사용처
    • 아주 단순한 공개/공유 케이스(과거 레거시)

3) IAM Policy

  • 무엇: 사용자/그룹/역할(Role) 같은 보안 주체에 직접 붙이는 권한
  • 적용 범위: 보안주체(Principal)
  • 제어 수준: 리소스 ARN 기준으로 매우 세밀하게 가능
  • 주 사용처
    • 이 사용자/역할은 이 버킷의 이 prefix만 읽기 가능 같은 주체 중심 권한 관리

4) Pre-Signed URL

  • 무엇: 일정 시간 동안만 유효한 S3 접근 링크(서명 포함)
  • 적용 범위: 객체 단위
  • 제어 수준: 기간 + 요청 방식(GET/PUT 등) 정도로 제한적
  • 주 사용처
    • 외부 사용자에게 파일을 잠깐 공유
    • 로그인/권한 부여 없이도 임시 다운로드/업로드 제공 (예: 업로드 링크 10분)

S3 실습

S3 → 버킷만들기
lab-edu-bucket-sample-593927188341
기본스팩으로 만들기(아래에서 수정 할 예정)

이미지 파일 업로드

객체로 들어가면 안들어가진다 -> 기본스팩으로해서
권한 차단때문에 그렇다. 퍼블릭 엑세스 차단, 객체 소유권 편집

퍼블릭 엑세스

객체 url 접근

사진에 접근되는것을 알 수 있다.


이미지를 올릴때부터 읽기권한을 허용하면

바로 보이게된다.


객체 삭제 및 버킷 삭제를 진행하고 CLI 로 버킷생성
IAM - ROLE(EC2 적용)

AmazonS3FullAccess, AmazonEC2FullAccess

vscode 서버에서 버킷만들기

이미지 올리고 golden_retriever.jpg 객체 Object URL 생성

DNS로 확인해보면

IAM FULL ACCESS 권한 추가

ssh로 Web server에 접속하고 Web server에서 S3를 호출하면 AWS는 Web Server에 붙어있는 IAM ROLE을 호출 주제로 봐서 원래는 AccessDenied 가 된다. 하지만 S3 버킷의 Bucket policy에 이 role은 이 버킷을 읽어도 된다는 규칙을 추가해서 web server가 S3를 호출하면 Role 조건을 통과해서 S3 접근이 성공하게 된다.

마무리

EBS와 S3를 직접 사용해보면서 AWS 에서 위 서비스들을 쓰는 방법들에 대해 알 수 있었고 나중에 프로젝트의 성질마다 다양한 스토리지를 적절히 쓰는것이 중요한거같다는 것을 깨달았다. 추후에는 배운내용을 토대로 프로젝트를 직접 개발하며 공부하고싶다.

0개의 댓글