S3 에서 정적 웹사이트 호스팅하기

HYEONG HWAN, MUN/ 11월 23, 2019/ 미분류/ 0 comments

https://blog.lael.be/post/9648

안녕하세요 라엘입니다.
이 글은 AWS S3 에 정적 파일을 업로드를 한 후, 이것으로 웹사이트를 구동하는 방법에 대해 설명하고 있습니다.

혹시 S3 와 GIT 연동 방법도 궁금하다면 https://blog.lael.be/post/9678 를 참고해주세요.

 

1. S3 버킷 생성하기

S3Amazon WebService 에서 객체(Object)를 저장하는(자료를 저장하는) 서비스의 이름입니다.
Simple Storage Service 의 약자이며 S3 라고 부릅니다.

 

클라우드 컴퓨팅에서 저장 장치는 두가지 종류가 있습니다. 하나는 Block Storage(블록 스토리지) 이고, 다른 하나는 Object Storage(오브젝트 스토리지) 입니다.

Block Storage는 여러분이 사용하는 SSD, HDD 같은 것입니다. data를 block 단위로 저장하는 것이죠.
Disk 는 무수히 많은 block 으로 나누어져 있고, 여러분의 파일은 여러 block 에 걸쳐서 저장됩니다.
당연히 서버는 이런 Block Storage 를 사용해서 동작합니다. (무조건 Block Storage)

Object Storage는 필드가 2개인 아주 거대한 데이터베이스라고 생각하면 됩니다.
2개의 필드는 Key-Value 이며, Key(경로) 에 해당하는 Value(데이터) 를 저장하는 장치입니다.

/mypicture/2019/profile.png 라는 것이 있다고 가정해봅니다.

Block Storagemypicture 폴더가 있고, 그 하위에 2019 폴더가 있고, 그 하위에 profile.png 파일이 있고, 이 파일 데이터는 디스크의 여러 블록에 걸쳐서 저장됩니다.
반면 Object StorageKey는 /mypicture/2019/profile.png, Value 는 데이터값 이 저장됩니다.

Block Storage 는 디스크를 직접 사용하는 것이고(포맷, 파티션 등등), Object Storage 는 Object(객체)를 Key-Value 저장하는 것입니다.
Block Storage 는 파일 저장시 상위 폴더가 있어야 저장되지만, Object Storage 는 폴더는 개념상일 뿐 실제로는 없는 것이라서 아무 경로나 바로 저장할 수 있습니다.
Block Storage 는 파일 삭제하더라도 폴더 정보가 남지만, Object Storage 는 파일 삭제한 후 폴더가 비어버리면 폴더까지 삭제됩니다. (Object Storage 에서 폴더의 개념을 만들기 위해서 가상의 숨김 파일을 사용하기도 합니다. git 의 경우 .gitkeep 으로 사용합니다.)

Block Storage 는 Disk 이기 때문에 최대 크기가 정해져 있는데, Object Storage 는 저장 서비스 같은 것이라서 사실상 최대 크기가 무한입니다.

Block Storage 는 Disk 를 직접 다루기 때문에 OS의 다양한 캐시전략(Burst Read 등등)을 사용해서 IOPS가 빠릅니다.
반면 Object Storage 는 가상화된 저장장치이므로 IOPS가 Block Storage 에 비해 느립니다. (즉, 항상 EBS 에 file write 하는 것이 S3 에 PutObject 하는 것보다 빠릅니다.) (비슷한 이유로 Object Storage 는 find, move, copy 등의 작업이 어마어마하게 느립니다. 특히 폴더이동.)

서버에서 Object Storage 를 공유 폴더로 구현하여 사용하지 마세요. IO 성능이 잘 나오지 않습니다.

이론 설명은 여기까지…


추가) 그러면 서버의 공유 폴더는 어떻게 구현해야 하느냐?

전통적인 방식의 File Storage 방식을 사용해야 합니다. File Storage 방식은 하나의 Host PC 에 폴더 공유 소프트웨어(NFS daemon, SMB daemon)을 통해서, 폴더를 공유하는 방식입니다.
주로 같은 Private network/subnet 에 있는 PC 와 연결하고, 내부망은 GIGA 망으로 연결된 경우가 많기 때문에 속도가 빨라서, 공유 폴더로 사용할 수 있습니다. (클라우드 전에는 다들 이렇게 썼음)
단점은 부하가 Host PC 에 집중되는 경향이 있고, Host PC 가 다운되면 File Storage가 다 죽습니다. (장애극복 전략(Failover 전략)을 짜둘것.)

 

요약 :
Block Storage : OS(운영체제) ---- Block Disk
Object Storage : OS(운영체제) ---- Object Storage Service (Key-Value 방식의 분산저장되는 디스크 서비스) --- Block Disk (결국엔 물리적으로 저장되어야 함)
File Storage : OS(운영체제) ---- Host PC 의 공유소프트웨어 ---- Block Disk

IO 속도 : Block Storage > File Storage >>>> Object Storage

다만 Object Storage 는 대량의 복제된 스토리지 서비스이기 때문에, 예를 들어 100만명이 동시에 다운로드 해야하거나, 서로 다른 100만개의 파일을 업로드해야하거나 할 때는 Object Storage 를 사용해야만 한다. 개별 I/O 처리는 느린 편이지만, 동시다발적인 I/O를 잘 다룰 수 있는 저장장치 인 것이다.


아무튼 S3 버킷을 생성해 봅시다.

Key-Value 방식에서 Key는 여러 사용자가 겹칠 수 있기 때문에, 추가적으로 Bucket 이라는 구분자를 사용합니다. 이것은 Object Storage 에서 도메인의 역할을 합니다.

< 그림 : bucket >

S3 콘솔에 이동 후 버킷을 생성합니다. (저는 한글 번역이 헷갈려서, 영문 UI 를 쓰고 있습니다. 적절한 버튼을 눌러주세요.)

Bucket name사용할 도메인 이름으로 정하고 나머지는 Next 누르고 끝마치세요.

저의 경우 fakepath.link 라는 도메인을 입력했습니다.

 

2. 사용할 정적 HTML 코드 준비하기

제가 임의로 하나 지정하겠습니다.

https://github.com/Mobirise/Free-Bootstrap-Template

다운 받은 다음에 압축 풀고, S3 에 업로드하세요.

파일을 S3 에 업로드하는 방법은 이 글에서는 다루지 않습니다.

 

3. Bucket 에 Public 접근권한 허용하기

Bucket -> Permission -> Block public access -> 모두 체크 해제 후 Save.

잘못된 Public 설정을 하는 경우가 있어서, 기본적으로 Public 설정을 할 수 없게 막고 있습니다. 이 막는 것을 해제합니다.

 

그 후 Bucket Policy(버킷 정책)에 아래와 같은 Policy 를 입력하세요.
Resource 항목의 Bucket name 만 수정해서 적용해주세요.
모두에게(*) 특정 리소스 경로 읽기(GetObject) 허용(Allow).

{
    "Version": "2012-10-17",
    "Id": "Policy1574498168597",
    "Statement": [
        {
            "Sid": "Stmt1574498167630",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::fakepath.link/*"
        }
    ]
}

 

설정이 끝나면 S3 리소스(arn:aws:s3:::fakepath.link/)에 대해서 Read 권한(GetObject)이 Public Open(*) 됩니다.

웹콘솔에서 적당한 리소스(파일)를 클릭한 다음 Object URL 을 눌러봅시다.

현재 이 상태로도 CNAME 만 설정하면 웹페이지 운영은 가능합니다.
다만 웹사이트 운영에 필요한 index 라는 기능이 없기 때문에, 웹사이트로 사용하려면 몇가지 더 작업을 해야 합니다.

예를 들어 많은 사람들은 웹사이트 방문시 도메인만 입력합니다.
브라우저에 바로 fakepath.link 를 입력할 뿐이지 https://fakepath.link/index.html 이라고 입력하지 않는다는 것이죠.

따라서 우리는 index 기능을 사용하게 해주는 website 기능을 사용설정 할 것입니다.

 

 

웹서버에서 Bucket 을 선택 후 Properties -> Static website hosting 을 클릭합니다.

원하는 index document 관련 메뉴가 있습니다. 위 그림과 같이 index.htmlerror.html 을 입력해주세요. (이 값은 이미 placeholder 로 표시되어 있을 것입니다.)

Redirection rules 를 응용하면 멋진 기능을 만들 수도 있습니다. (저 같은 경우 복잡하게 응용해서, 이미지 캐시 서버, 이미지 리사이즈 서버로 운영했었습니다.)

그러면 새로운 웹주소(Endpoint)를 얻게 됩니다. http://fakepath.link.s3-website.ap-northeast-2.amazonaws.com/

 

이제 1) Public 접근 설정도 하였고 2) Index document 설정도 하였으니 3) Custom Domain 설정을 해보도록 합시다.

해당 도메인의 DNS 설정을 변경해봅니다.
S3 웹사이트 서버 주소는 고정(1대라는 뜻은 아님)이기 때문에 아래와 같이 작업하면 됩니다. s3-website.ap-northeast-2.amazonaws.com 를 입력하면 됩니다. 원하는 도메인이 root domain 이 아니라면 CNAME 으로 입력하세요.

- Route53 DNS (https://aws.amazon.com/ko/route53/)

 

- Cloudflare (https://www.cloudflare.com/)

 

- DNSEVER (https://kr.dnsever.com/)


S3 또는 S3 Website 서버를 Custom hostname 으로 접근시 S3는 그 Custom hostname 와 일치하는 Bucket 을 찾고 연결해서 서비스한다.

이제 연결한 도메인을 접속해 보자 : http://fakepath.link/ (예제의 경우)

 

남은 한가지의 문제 ) 요즘엔 개인정보를 취급하지 않더라도 HTTPS 사이트를 구축하는 추세이다.
따라서 https 로 서비스되도록 설정해보자.
불행하게도 S3 는 커스텀 도메인 인증서 기능을 지원하지 않는다. 따라서 S3, S3 Website 는 Custom domain 을 사용한 HTTPS 운영을 지원하지 않는다.

이 문제를 해결하기 위해서 HTTPS 를 먼저 처리해주는 Proxy 서버를 구축해야 한다.

하지만 Proxy 서버를 직접 구축하는 것은, 요즘의 유행하는 Serverless 추세에 맞지 않으므로, 서버를 구축하지 않고 할 수 있는 2가지 방법을 소개해 보겠다.

 

1] Cloudflare

DNS 설정에서 Proxied 를 처리하면 정확히 원하는대로 동작한다. (회색 아이콘에서 주황색 아이콘으로 변경해야함.)

User(사용자) -> HTTPS Server(Cloudflare Proxy) -> HTTP Server(Amazon S3)

단점은 도메인의 Cloudflare 서비스를 이용하기 위해서, 네임서버를 반드시 Cloudflare 로 바꾸어야 한다는 것이다.

 

2] Amazon CloudFront

자세하게 설명하기에 너무 길어서 그냥 말로만 설명한다.

US East (N. Virginia) 리전의 AWS Certificate Manager 에서, 원하는 도메인의 SSL 인증서를 발급받는다.
CloudFront 에서 Create Distribution 버튼을 클릭한 다음, S3 버킷을 선택한다.
Alternate Domain Names(CNAMEs) 항목에 원하는 도메인을 입력한 다음, 인증서를 연결해주면 된다.

< 핵심 설정 부분 >

장점은 AWS 만 사용해서 구현되고, S3 의 특정 도메인을 Web root 로 지정할 수 있게 된다. 요청 기록이나, 접근 제어(방화벽)를 할 수 있다.
단점은 설정이 번거롭고, S3 Website 와 상관없이 동작하는 거라서, Index page 와 Error page 지정을 할 수 없다.

User(사용자) -> HTTPS Server(CloudFront Server) <= (파일 복사 요청)Amazon S3)

AWS 를 잘 다루는 사람 입장에서는, 이 방식이 지극히 Amazon way 이기 때문에 이 방식을 선호한다.

CloudFront 로 구현할 경우, S3 Website 기능을 꺼도 된다. 그리고 Bucket name 을 도메인 주소(domain name)으로 하지 않아도 된다.

 

 

 

이렇게 S3 에서 당신이 원하는 도메인 주소로 웹사이트를 운영할 수 있게 되었습니다!

 

예제 구현 링크

링크 종료

 

Leave a Comment

작성하신 댓글은 관리자의 수동 승인 후 게시됩니다.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
*
*