Storage Service
AWS Storage Profile
Storage와 관련된 다양한 AWS의 서비스
- Storage : 데이터를 어떤 유형으로 저장하는가에 따라 구분가능
- Object단위로 저장(key와 val의 쌍) : S3
- Block단위로 저장( 블록고유주소로 접근 ) : EBS
- File단위로 저장( 물리적으로 연속되지 않고 떨어져있는 스토리지를 연결하여 사용, 계층구조 ) : EFS, FSx & NFS
- Protection
- Transfer
EBS( Elastic Block Storage )
: EC2 인스턴스에 네트워크 기반으로 연결된 Block Storage
- 암호화 지원 ( 데이터 볼륨, 스냅샷 )
- 하나의 EBS 볼륨은 하나의 EC2 인스턴스에 연결하여 사용( 1:1 ), EBS는 분리후 다른 인스턴스에 연결가능 ( 단일서버에서 사용되는 DB, 저장소로 활용 )
↔ 하나의 EC2 인스턴스에 여러 EBS 볼륨 연결가능( 1:N ), 동일한 가용영역의 여러 EBS와 연결가능
프로비저닝된 IOPS를 지원하는 EBS 볼륨타입( io1, io2 )은 EBS Multi-Attach를 지원( 동일한 AZ내 여러 EC2 인스턴스에 동시에 연결가능 ) → 머신러닝에서 사용하는 볼륨 - 가용영역(AZ)에 종속됨 → 같은 가용영역의 EC2에만 연결가능, 가용영역간 EBS 볼륨 공유 불가( 가용영역(az)이 다른 ec2 인스턴스에 ebs를 붙일 수 없음 )
SnapShot( 디스크 백업 )을 이용하여 다른 가용영역에 복제본을 만들어 사용가능
- 기본적으로 EC2용 데이터센터, EBS용 데이터센터가 물리적으로 분리됨 → 네트워크 전용선으로 연결
- NFS가 아니지만 네트워크 기반으로 연결되어있음 → 실제로 물리적인 연결처럼 이루어지기에 EC2에 일대일 연결만 가능
[ AWS Volume type ]
- 크게 SSD와 HDD로 구분 → SSD가 많이 사용됨 ( general SSD ), HDD는 거의 사용하지 않음( 비용상 차이가 거의 없음 )
- gp3는 gp2에 비해 처리량이 4배좋음
- IOPS SSD : 고성능, 고비용
[ AWS instance storage ]
호스트 컴퓨터의 디스크를 직접연결 = 인스턴스가 실행되는(위치하는) 물리적 서버의 로컬 디스크를 사용
- 네트워크를 사용하지 않음 → 가장 빠른 속도의 디스크 타입
- 비영구적인 저장소( 휘발성 ) : 인스턴스 중지/종료시 호스트의 위치가 바뀌면서(하드웨어 변경) 데이터 손실 ( 인스턴스가 해당 호스트 위에서(동일한 위치에서) 재시작된다는 보장이 없음, 다른 호스트로 이동시 새로운 물리저장소를 사용 )
- 연결해제 불가능, 분리 불가능
이와달리 EBS는 영구적으로 데이터 보관가능, 그러나 네트워크로 연결되어 비교적 느린 속도, 연결해제후(detach) 다른 EC2와 연결가능
[ AWS snapshot ]
: 특정시점의 EBS 볼륨에 저장된 데이터를 복사해둔 백업 데이터
- 증분 방식 저장( incremental backup ) : 첫 스냅샷은 전체 데이터를 백업하고 이후 스냅샷은 추가된 데이터 블록만 백업 → 중복내용을 백업X, 변경사항만 백업하여 효율적임 ( 삭제시 이전 스냅샷과 병합되어 관리 )
↔ 시간단위 백업( full backup ) : 데이터가 중복되어도 현상태를 반복적으로 백업 - S3 버킷에 보관
- 스냅샷의 활용 : AMI( 운영체제 및 타입 설정 )와 별개로 데이터만 백업, 생성된 EBS볼륨을 암호화 볼륨으로 교체(변경불가), 가용영역으로 볼륨복제 등
[ AMI & snapshot의 차이점 ] ( 중요 )
- AMI
- 목적 및 개념 : EC2 instance를 생성하기 위한 template( IMAGE )
- 저장위치 : S3
- 구성요소, 데이터 : EC2에 부착된 모든 EBS 볼륨 데이터 + 메타데이터( OS 및 application 설정정보 )
- Snapshot
- 목적 및 개념 : 특정시점의 EBS 볼륨 데이터를 백업, 복구용 이미지
- 저장위치 : S3( shapshot ID )
- 구성요소, 데이터 : 특정 EBS 볼륨의 데이터만 포함
EBS 서비스 구성 실습 과정
(1) EBS 루트 볼륨 확장 실습 ( EBS Volume Size Up )
일반적으로 EC2 인스턴스를 생성할 때 기본적으로 루트 볼륨으로 사용할 EBS(Elastic Block Store) 볼륨이 함께 생성 → EC2 인스턴스가 부팅하고 운영체제를 실행하기 위해 필요한 스토리지를 제공
vscode접속 → web-server접속 → lsblk : 리눅스 시스템에서 블록 디바이스(block devices)를 확인
20GB가 사용중( root dir에서 8GB사용중 )
볼륨 파티션 확장 growpart : 지정된 파티션의 크기를 확장, 남은 크기를 모두 할당
첫번째 파티션을 확장( 8G → 20G )
파일시스템 확장
df -h : 파일 시스템의 디스크 공간 사용량을 보기
xfs_growfs : XFS 파일 시스템 크기를 동적으로 조정(확장), XFS 파일 시스템을 디스크의 새로 할당된 여유 공간만큼 확장
(2) EBS 루트 볼륨 생성 실습 ( Create EBS Volume )
볼륨유형은 범용 SSD( gp3 ), 크기 10GiB
볼륨 연결 → lab-edu-ec2-web에 /dev/sdf라는 이름으로 연결
내부에서 파일시스템 포맷 및 마운트
- mkfs.xfs : 지정한 디스크(/dev/nvme1n1) 또는 파티션에 XFS 형식의 파일 시스템을 초기화
- /data 폴더에 마운트 이때 /etc/fstab에 설정되어있지 않으면, 재시작할 때(reboot) 디스크를 마운트하지 않음 파일 시스템 테이블(/etc/fstab) : 디스크 파티션, 파일 시스템, 마운트 지점, 마운트 옵션 등을 정의하는 설정 파일 → 부팅시 이를 읽어 자동으로 마운트하게됨
/etc/fstab에 nvme1n1의 uuid를 확인해서 한줄 추가해주면 서버가 재시작되어도 다시 마운트
blkid : 장치들의 uuid 확인 명령어
mount -a: fstab에 정의된 파일 시스템을 시스템에 자동으로 연결하는 명령
(3) 스냅샷 생성실습 ( EBS Snapshot )
스냅샷 생성 lab-edu-ec2-web의 EBS볼륨 /dev/xvda을 스냅샷으로 백업
스냅샷의 태그 : Name = lab-edu-snapshot-web
(4) 스냅샷으로 볼륨 복제 생성
- 가용 영역: ap-northeast-2c ↔ 기존 서버와 볼륨의 가용영역은 ap-northeast-2a
- 암호화
VScode 인스턴스에 연결 ( 가용영역 ap-northeast-2c에 존재 )
확장된 형태 그대로 반영
(+) EBS Snapshot 해외 리전으로 복제
ap-northeast-2에서 us-east-1로 복사됨
미국 버지니아 리전에 접속하면 스냅샷이 복사되어 저장됨
(+) 스냅샷 주기 정책설정 : 일정 기간동안 주기적으로 스냅샷 생성
EC2 메인 콘솔 화면 → 수명 주기 관리자 리소스 탭 → 사용자 지정 정책 선택 → EBS Snapshot 정책 선택 → 다음 단계 클릭
- EBS 스냅샷 정책 : 스토리지 볼륨 백업
- EBS 지원 AMI 정책 : AMI 이미지로 백업
- 교차 계정 복사 이벤트 정책 : 백업 AMI 이미지를 다른 AWS 계정과 공유
볼륨 리소스를 Name키로 지정 → 스냅샷을 생성
인스턴스 리소스를 선택하는 경우 AMI가 생성됨
일정 lab-edu-ebslc-web 생성 : 매일 9:00에 5개의 스냅샷이 생성됨
Simple Storage Service - S3
[ AWS S3 ]
웹 서비스( 인터넷 )를 이용해 어디서나 접근이 가능한 오브젝트 스토리지 ( 객체형식으로 데이터 저장 )
- 용량제한 없이 무제한(거의) 확장 가능한 스토리지
EBS는 사용할 gb를명시하지만 S3는 용량을 정하지 않고 넣을수록 확장 - 용량을 사전에 프로비저닝하지 않고 사용한 만큼 과금 ( 저장용량만큼 비용청구, 전소량에 따른 비용청구 )
- 단순 데이터 저장소( 프로그램 설치 작업 제한, 마운트는 가능 ) ↔ EBS는 서버에 마운트, 소스코드 등을 저장하여 프로그램 실행 및 설치
- 가용성과 내구성이 강함 ( 99.999999999% )
+) Route 53 dns 서버는 가용성 100%를 보장하는 유일한 서비스 - S3를 사용하여 정적 웹 사이트를 호스팅가능 ( HTML, CSS, 이미지, JavaScript 파일 등 )
[ S3 Bucket ]
folder_1의 object(dogs.jpg) 파일 ⇒ 버킷명/folder_1/dogs.jpg로 접근
- 전역( global )에서 고유한 이름으로 생성 & 위치( region )을 지정
- 저장되는 객체( object )는 키(key)와 값(val)으로 구성
- 객체 식별 및 접근방식
- S3 URI : AWS 내부 작업용 식별자, AWS CLI에서 사용 s3://[BucketName]/[ObjectKey]
- Object URL : HTTP기반 외부 접속용 식별자, 브라우저에서 사용
https://[BucketName].[Region].amazonaws.com/[ObjectKey]
[ S3 보안관리 ]
인터넷을 통해 접근가능하게 보안설정이 매우 중요함
- Bucket Policy : JSON 형식으로 작성된 정책문서( IAM의 Policy와 유사 ) → 버킷에 내부(in-line방식)에서 작성하여 권한관리 ⇒ 세밀한 조건(condition) 기반정책
- ACL( access control list ) : 버킷의 객체수준에서 개별 접근 권한 관리( 세밀한 관리부족( 완전히 열거나 닫음 ) → 보안상 권장하지 않음 )
- IAM : 보안주체에 권한 할당( 버킷에 접근가능, 제한 ) 버킷정책이 없어도 IAM에 권한이 있으면 버킷 데이터 접근가능 ⇒ 보안주체별 세부적인 리소스 접근권한 관리, 교차계정 접근시
- Pre-Signed URL : 제한시간동안에만 접근 가능한 링크 → 객체단위의 데이터의 일시적 공유
정책, ACL로 접근을 막아도 이를 통해 제한시간동안 접근허용가능
[ S3 ACL ]
세밀한 조정이 불가 → 완전히 열거나 완전히 닫음
- 콘솔화면에서 편집
- AWS CLI : 파일을 S3에 업로드 할때 --acl 옵션
aws s3 cp example.txt s3://my-bucket/example.txt --acl public--read
public-read를 설정하여 Everyone(public access) 접근 허용
- AWS SDK
# example 파일 업로드 및 public access 허용
import boto3
s3 = boto3.client('s3’)
data = open('example.txt', 'rb')
s3.put_object(
Bucket='my_bucket',
Key='example.txt',
Body=data,
ACL='public-read'
)
s3를 import하여 s3변수에 담음 데이터를 읽어서 data변수에 담음 → ACL=”public-read” 적용
[ S3 Bucket Policy ]
- Effect : Action의 작업권한을 Allow 혹은 Deny
- Principle : 보안주체 ( IAM의 identity와 유사 ) → User, Role… 권한을 부여할 주체
- "AWS" : "arn:aws:iam::123456789012:user/user01” ⇒ amazon resource name, 리소스 고유하게 식별, IAM도 resource
- Action: 서비스명(dynamodb, s3… ) + 행위(DeleteItem, GetObject…)
- Resource : 정책 적용대상(접근대상)의 ARN정보 → *로 전제 접근, 특정 파일에만 접근가능하도록 설정가능 버킷이라고 하더라도 폴더별, 오브젝트별로 지정가능
- Condition : 해당 정책이 적용될 조건 ( 조건이 충족된 경우에만 정책이 허용 )
[ S3 pre-signed URL ]
- AWS CLI : presign을 이용 & 옵션 --expires-in 만료시간
- AWS SDK : generate_presigned_url
[ Public access block ]
모든 설정중에 가장 우선됨 ( 다른 방식에서 오픈해놓아도 Public Access Block에서 모든 공개 접근 차단을 하면 무효화 )
- Public 접근 권한을 무시하거나 차단하기 위해 사용됨 ( 기본적으로 버킷은 Private )
S3 객체 업로드 & 접근제어 실습
[ 콘솔에서 Amazon S3 생성 및 ACL 접근제어 설정 ]
(1) AWS Console에서 버킷 생성 및 데이터 업로드
버킷내 객체 URL복사하여 접속 → AccessDenied
현재 Role로 등록은 가능하지만 접근은 불가한 상황
(2) ACL 이용 Public access 설정 : 버킷에 접근 public으로 접근 허락 + 객체 자체도 public으로 오픈
버킷은 기본적으로 public access 차단상태 → 비활성화
객체소유권 편집 → ACL 활성화
객체 탭에서 ACL을 이용하여 퍼블릭으로 설정
다시 객체 URL로 접근시 정상확인가능
(3) 업로드와 동시에 public 접근 허용
새로운 이미지 업로드 → 업로드 시에 권한에서 퍼블릭 읽기 엑세스 권한을 부여 → 업로드와 동시에 URL로 접근가능
(4) 삭제 : 내부 객체를 모두 삭제후 버킷 삭제가능
[ AWS CLI 이용 Amazon S3 생성 ]
(1) VScode에 할당할 Role 생성
- AmazonEC2FullAccess : EC2 인스턴스 및 관련 리소스에 대한 모든 관리 권한을 부여
- AmazonS3FullAccess : 모든 S3 버킷에 대해 접근 권한을 부여 ( 내가생성 + 남이 생성 )
Vscode 인스턴스의 IAM 역할수정 →
(2) VScode로 접속
aws sts get-caller-identity : AWS의 **STS(Security Token Service)**에서 호출자의 정보를 반환 → 인스턴스에 부여된 IAM 역할정보
- UserId: 인스턴스에 부여된 role session ID.
- Account: 인스턴스를 소유한 AWS 계정 ID.
- Arn: 인스턴스에 부여된 role ARN.
AWS CLI 명령어로 버킷 생성
# 고유한 버킷 이름 지정
ACCOUNT_ID=$(aws sts get-caller-identity | jq -r .Account)
BUCKET_NAME="lab-edu-bucket-image-$ACCOUNT_ID"
# 버킷 생성
aws s3 mb "s3://$BUCKET_NAME"
버킷생성후 데이터 업로드 ( cp명령으로 이미지를 복사하여 업로드 )
AWS CLI 명령어로 Pre-Signed URL 생성
(1) object URL 생성
하지만 object URL은 권한이 없기에 오류발생
(2) Pre-Signed URL로 생성
aws s3 presign s3://$BUCKET_NAME/$OBJECT_KEY --expires-in 30
--expires-in 30 : 30초간 허용 → 30초 이후에 해당 URL로 재접속시 다시 접근 불가능
[ S3 Bucket Policy 설정 (IAM Role 접근 허용 정책) ]
현재 web-server에서는 S3접근불가, VScode만이 가능
VSCode의 Role에 IAMFullAccess를 부여 : 해당 인스턴스에서 IAM 권한을 다룰 수 있음( 추출, 부여 등.. )
Vscode에서 정책문서를 작성하여 webserver가 가진 역할에 접근권한을 부여하게 하자!
AWS 스크립트로 적절한 버킷 정책 문서(JSON)을 생성
s3_bucket_policy_ec2_web_role.sh : 주어진 S3 버킷 정책 파일(INPUT_FILE)을 복사하고, 해당 파일 내에 특정 플레이스홀더를 실제 값으로 바꾸는 작업을 수행( sed명령 ) → 수정된 정책파일(OUTPUT_FILE) 도출
s3_bucket_policy_ec2_web_role.json : 기본 버킷 정책 템플릿 ( 해당 S3에 모든 권한을 부여함 )
최종 결과물
lab-edu-role-ec2라는 역할에 S3 접근권한을 부여한다 → 이 역할을 가지고 있는 web-server도 자연스럽게 접근이 가능해진다!!
S3 콘솔 메인화면에서 버킷 접속 → 권한에서 버킷정책필드를 편집하여 JSON 등록
퍼블릭 액세스 차단이 이루어진 상태에서 버킷정책이 등록됨
이후 web-server에서 다시 S3에 접속한 결과 접속이 가능해짐
[ S3 Bucket Policy 설정 (Source IP 기반 접근 허용 정책) ]
기존의 버킷정책 삭제
AWS 스크립트로 적절한 버킷 정책 문서(JSON)을 생성
s3_bucket_policy_ec2_web_role_ip.sh : VPC_ID와 그에 속한 NAT_GATWAY_IP가 추가됨 S3는 VPC 외부에 있는 서비스로 EC2가 접근하기 위해서는 인터넷 접근이 필요함( VPC외부 = 0.0.0.0 ) 따라서 NAT gateway를 반드시 거치게 될 것이고 패킷의 source IP는 NAT gateway IP가 될 것임 ⇒ 인스턴스에 부여된 role로 식별하지 않고 인스턴스의 IP로 식별함
s3_bucket_policy_ec2_web_role+ip.json : 기본 버킷 정책 템플릿 ( 해당 S3에 모든 권한을 부여함 )
- 대상을 특정 role을 소유한 것으로 필터링하지 않고 대상은 모든 것으로 넓힘 (*)
- condition조건으로 source IP를 지정함
결과 정책문서
S3 콘솔 메인화면에서 버킷 접속 → 권한에서 버킷정책필드를 편집하여 JSON 등록
nat gateway의 IP를 확인해서 값을 잘 가져왔는지 확인