흰 스타렉스에서 내가 내리지

CF(2): CloudFront Origin (원본) 본문

AWS

CF(2): CloudFront Origin (원본)

주씨. 2024. 10. 25. 14:29
728x90

# 원본 (Origin)

  • 뷰어에게 보여줄 컨텐츠의 원본이 있는 거점.
  • 2가지 종류
    • Amazon S3
    • Custon Origin (S3 이외 모든 것.)
      • EC2, ELB
      • On-premise Resource
      • GCP, Azure, ...
      • HTTP 로 요청만 할 수 있다면 상관없이 모두를 Origin 으로 사용할 수 있다. ⭐️⭐️⭐️⭐️⭐️⭐️
  • 기본 최대 25/Distribution
    • 기본적으로 하나의 Distribution은 최대 25개의 origin 을 가질 수 있는데, 원한다면 늘릴 수 있다.

 

  • Viewer 가 CF 에 요청을 하면, CF 는 컨텐츠를 가져와야 한다.
  • CF가 컨텐츠를 가져올 수 있는 대상은 EC2, S3, ALB 등 AWS 리소스가 될 수도 있고, On-Premise 서버가 될 수 있다.
  • 이 중에서도, S3 를 Origin 으로 설정할 경우 이용할 수 있는 특별한 기능들이 있다. 

# S3 Origin

  • Amazon S3 을 Origin 으로 설정해 컨텐츠를 제공하는 경우
  • 도메인 형식 : {bucketname}.s3.{region}.amazonaws.com
    • 이렇게 설정하지 않을 경우 Custom Origin 취급
      • s3.amazonaws.com/{bucketname} (X)
      • http://{bucketname}.s3-website-{region}.amazonaws.com (가능, 단 S3 Static hosting)
  • S3 Origin 만의 추가 기능
    • S3의 접근 제한 기능 (OAC/OAI)
    • Post/Put 등으로 직접 S3 에 컨텐츠 업데이트 가능
  • 기타 활용 : S3 Object Lambda
    • S3에서 파일을 가져올 때, 동적으로 그 파일을 변환하거나 수정을 할 수 있다.

 


# Custom Origin

  • S3를 제외한 모든 Origin
    • MediaStore
    • S3 Static Hosting
    • Lambda Function URL
    • Application Load Balancer
    • EC2 or other HTTP Source(on-premise)
  • Origin Group
    • 여러 Origin 을 그룹으로 묶어 Failover 시나리오에 대응 가능
    • 예: Primary에서 HTTP status 500 을 반환할 경우, Secondary 에서 컨텐츠 가져오기
  • HTTP/HTTPS 로 접근할지 선택 가능
  • IP주소는 사용불가 → 도메인만 가능

 


# Origin Group

  • Failover를 대비하여 Primary, Secondary  두 Origin 을 그룹으로 묶어 관리 가능
  • Primary에서 실패한 경우 자동으로 Secondary 에 요청.
    • 실패를 나타내는 HTTP 코드가 반환될 경우
    • Primary에 통신을 할 수 없는 경우 (타임아웃 등)
      • 기본 10초 (3번 시도)
      • 시도 횟수와 시간 조절 가능
    • 요청의 응답이 늦어지는 경우
      • 기본 30초, 최대 60초까지 조절 가능
  • GET, HEAD, OPTION Method 에만 적용 가능
  • Primary, Secondary 모두 실패한 겨우 Custom 에러 페이지 생성 가능.

 

 


# Origin Custom Header

  • CF 에서 Origin 에 요청시 커스텀 추가 헤더 전달 가능

    • 사용 예
      • ALB 에서, Amazon CloudFront 에서만 오는 요청을 처리하고 싶을 때 
      • CloudFront 가 여러 개일 때, ALB에서 각각 어디서 요청을 받는지 로깅을 하고 싶을 때
    • 이미 요청에 포함되어 있으면 덮어씌움
    • 최대 10개 (증가 요청 가능)
    • 별도로 추가 불가능한 Header 존재

 

# 실습

1. EC2 인스턴스를 만들어서 Custom Origin 을 만든다. 

2. 인스턴스를 생성할 때, user data 에 다음 쉘 스크립트를 입력한다. 

#!/bin/bash
sudo -s
sudo yum install -y httpd
systemctl start httpd
chkconfig httpd on
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" "http://169.254.169.254/latest/meta-data/instance-id")
echo "$INSTANCE_ID" >> /var/www/html/index.html
# 쉘 스크립트 설명
1. sudo 명령을 통해 스크립트를 실행하는 사용자가 root 권한을 획득한다.
2. yum 패키지 관리자를 사용하여 Apache 웹 서버(httpd)를 설치한다. -y 플래그는 설치를 자동으로 승인한다.
3. Apache 웹 서버를 시작한다.
4. chkconfig httpd on : Apache 서버가 시스템 부팅 시 자동으로 시작되도록 설정한다.
5. TOKEN=~~ : EC2 인스턴스의 메타데이터 API 에 접근하기 위해 필요한 토큰을 발급받는다. 토큰은 21600초(6시간)동안 유효하다.
6. INSTANCE_ID=~~ : 발급받은 토큰을 사용하여 EC2 인스턴스의 ID를 가져온다. EC2 인스턴스 메타데이터 서비스의 instance-id 엔드포인트에서 인스턴스 ID 정보를 가져온다.
7. 가져온 인스턴스 ID 를 /var/www/html/index.html 파일에 추가하여, 웹 서버의 기본 페이지에 표시되도록 한다. 이로 인해, EC2 인스턴스의 IP주소로 웹 서버에 접속하면 해당 인스턴스의 ID가 웹페이지에 표시된다. 

 

인스턴스가 생성되고, pub ip 로 접속해보면, 위와 같이 instance-id 가 보여져야 한다.

 

 

3. S3 버킷을 생성하고 아무 이미지 파일을 업로드 한다. 

 

 

4. CloudFront Distribution 을 생성한다.

방금 우리가 만든 s3 버킷을 Origin domain 으로 설정

 

원본 액세스, 기본 캐시 동작 등은 일단은 만지지 않고 디폴트값으로 들고 간다. 

나중에 따로 다뤄보도록 하자.

 

Legacy 를 선택하고 TTL 을 모두 0으로 해본다. 

 

WAF

WAF 도 지금은 Demo 이기 때문에 비활성화 한다. 

 

나머지는 그대로 두고 `배포 생성`을 해본다. 

 

CloudFront 는 전 세계에 있는 모든 edge location 에서 설정이 완료되어야지 배포가 완료되기 때문에, 상당히 오랜 시간이 걸린다. 

기다리는 동안, s3 origin 뿐만 아니라 custom origin 도 만들어보자. 

 

 

5. custom origin 을 사용한 새로운 CloudFront Distribution 을 생성한다.

 

아까 생성한 EC2 인스턴스의 public DNS 를 입력하고, 프로토콜은 HTTP 를 선택한다.

SSL 인증서를 받아 HTTPS 를 설정하지 않았기 때문이다.

 

 

Legacy 를 선택하고, 이번에는 TTL 을 기본 10, 최대 10으로 설정해본다. 

나머지는 그대로 두고, 배포 생성 버튼을 누른다.

 

custom origin 을 생성하는 동안, s3 origin 의 배포가 끝났을 것이다. 

 

배포 도메인이 생성이 되었고, 내가 업로드한 객체의 이름은 sunset.JPG 이었으므로, 

https://d84f7eiue0lid.cloudfront.net/sunset.JPG 로 접속을 해본다. 

 

당연히 Access Denied 가 될 것이다. 

왜냐하면, CloudFront 가 S3 버킷에 접속할 수 있어야 하는데, 버킷이 현재 public 이 아니기 때문이다

 

이를 해결하기 위한 방법은 2가지가 있다.

1. S3 버킷을 public 으로 만든다. (비추천)

2. OAC 사용.

 

 

6. s3 origin 을 사용할 수 있도록, s3 버킷에 접근할 수 있도록 해준다.

아직 OAC 를 배우지 않았기 때문에, S3 버킷의 퍼블릭 액세스 차단을 해제한다.

그리고 버킷 정책에 다음을 추가해준다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Statement1",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::[버킷명]/*"
    }
  ]
}

 

이제 url 로 접속이 가능해진다. 

 

 

7. Custom Origin 의 CF 배포 확인

ec2 인스턴스의 public DNS 를 넣고 생성한 CF 배포가 완료되면, 생성된 배포 도메인으로 접속해본다.

 

잘 접속이 되지요?

 

 

8. ec2 인스턴스에 연결하여 접속 로그를 확인해본다. 

sudo -s
cd /var/log/httpd
tail -f access_log

지금까지의 로그

 

ec2 인스턴스의 Public ip 로 접속했을 때, 아래 이미지의 드래그 한 로그가 찍힌다. 

 

이제 cloudfront 로 접속했을 때 로그를 살펴보자. 

CF 도메인으로 접속했을 때

그러나 바로 다시 접속을 해보면, 로그가 찍히지 않는다. 

왜냐하면 CF 배포를 설정할 때, TTL 을 10초로 두었기 때문에, 캐싱이 되어 인스턴스로 트래픽이 오지 않은 것이다. 

10초가 지나고, 즉 TTL 이 끝나고 다시 접속을 하면 로그가 다시 찍히게 된다. 

 


# origin group 사용하기

1. 새로운 ec2 인스턴스를 생성한다. user data 에 아래 쉘 스크립트를 입력한다.

#!/bin/bash
sudo -s
sudo yum install -y httpd
systemctl start httpd
chkconfig httpd on
echo "Oops!! This is secondary." >> /var/www/html/page.html

 

 

2. 위에서 만들었던 custom origin 의 cloudfront 배포로 가서, 원본을 생성한다.

 

새로 만든 ec2 인스턴스의 public DNS 를 등록하면, 아래 이미와 같이 원본이 2개 있을 것이다. 

 

 

3. 원본 그룹을 생성한다.

 

원본을 선택하고, 장애 조치 기준으로는 일단 404를 선택한다. 

원본에서 첫 번째가 primary 가 되고, 두 번째가 secondary 가 되는 것이다. 

 

 

4. 원본 그룹을 기반으로 동작을 편집한다.

원본 및 원본 그룹 드롭다운 선택

처음 들어가면 `원본 및 원본 그룹` 드롭다운이 초기 원본으로 선택되어 있을 것이다. 

이를 방금 생성한 원본 그룹으로 바꾸어 준다. 

수정 완료를 하면, 배포를 완료하는 데 역시 시간이 좀 걸린다. 

 

배포가 완료되면, /page.html 로 접속했을 때 페이지가 잘 뜰것이다. 

두 번째 인스턴스로 트래픽 이동

 

primary 로 설정한 origin 은 page.html 을 설정하지 않았다.

그래서 /page.html 로 접속하면 404를 던질 것이고, 그러면 secondary 로 트래픽이 가게 된다.

이것이 첫번째 ec2 인스턴스 트래픽

 

 

이러한 방식으로 유저 입장에서는 장애가 발생했는지 인식할 수 없게끔 고가용성을 확보할 수 있다.