AWS - Load Balancing (3): CloudFront
이 포스트는 CDN 과 AWS 에서 제공하는 CDN 서비스인 CloudFront 에 대해 알아본다.
- 1. CDN (Contents Delivery Network)
- 2. CloudFront
- 3. CloudFront 를 통한 CDN 서비스 테스트
아래는 이번 포스트에서 다뤄볼 범위 도식화이다.
1. CDN (Contents Delivery Network)
콘텐츠 제공자와 사용자 간 지리적으로 떨어져있는 환경에서 콘텐츠를 빠르게 제공하기 위한 기술이다.
CDN 이 없는 환경에서 오리진 서버는 모든 사용자 요청에 대해 일일이 처리하는 과부하 환경이며, 지리적으로 떨어져있는 경우 지연 시간이 길어진다.
CDN 은 오리진 서버로부터 지역적으로 분산되어 있는 캐시 서버로 콘텐츠를 분배하고, 각 지역의 사용자는 인접한 캐시 서버로부터 콘텐츠를 전달받아 원활한 서비스를 제공받을 수 있다.
오리진 서버에 저장된 콘텐츠를 캐시 서버로 저장하는 것을 캐싱이라고 한다.
캐시 서버에서 콘텐츠를 갖고 있으면 Cache Hit
, 갖고 있지 않으면 Cache Miss
라고 하는데 Cache Miss
인 경우 오리진에 원본 콘텐츠를 요청하여 저장한다.
- Static Caching (정적 캐싱)
- 이미지 파일, 자바스크립트, CSS 등 정적인 콘텐츠 캐싱
- Dynamic Caching (동적 캐싱)
- 사용자 요청에 의해 생성되는 동적 콘텐츠
- 캐싱하더라도 Cache Hit 가 높지 않아 캐싱의 이점을 얻기 어렵지만 CDN 을 통해 배포하게 되면 오리진 서버를 보호하고, 보다 빠른 콘텐츠를 제공받을 수 있음
- Dynamic Caching 은 실제 콘텐츠를 캐싱하지 않기 때문에 TTL 은 0으로 설정됨
2. CloudFront
CloudFront 는 AWS 에서 제공하는 CDN 기능으로, 오리진 대상의 콘텐츠를 캐싱하여 짧은 지연시간과 빠른 전송 속도로 전 세계 사용자에게 콘텐츠를 전송하는 CDN 서비스다.
CloudFront 의 주요 기능은 아래와 같다.
- 오리진 Selection
- 여러 오리진을 구성하여 콘텐츠 처리 가능
- 오리진 그룹을 통한 Failover
- 오리진 그룹 내의 기본 오리진과 보조 오리진을 구성하여 기본 오리진이 응답 불가한 상태이면 자동으로 보조 오리진으로 변환
- SSL 지원
- 콘텐츠에 대해 SSL/TLS 를 통해 전송 가능
- 고급 SSL 기능 (Full/Half 브릿지 HTTPS 연결, 필드 레벨 암호화 등) 을 자동으로 활성화 가능
- 액세스 제어
- Signed URL 과 Signed Cookie 를 사용하면 토큰 인증을 지원하며, 인증된 최종 사용자만 액세스하도록 제한 가능
- 보안
- DDoS 공격을 비롯한 여러 유형의 공격에 대해 계층형 보안 방어 가능
- 비용
- 사용한 만큼 지불하는 일반 요금과 약정 트래픽 개별 요금 제공
- AWS 클라우드 서비스와 오리진에서 CloudFront 간 무료 데이터 전송
- S3, EC2, ELB 같은 AWS 서비스가 오리진일 경우 오리진에서 CloudFront Edge Location 으로 전송되는 데이터는 요금이 청구되지 않음
① 오리진
- AWS 서비스 중 EC2, ELB, S3 가 오리진 대상이 될 수 있으며, 고객 데이터 센터의 별도 서버도 가능
② Distribution
- 오리진과 Edge Location 중간에서 콘텐츠를 배포하는 역할을 수행하는 CloudFront 의 독립적인 단위
- HTTP(S) 전용의 Web Distribution 과 동영상 콘텐츠 전용의 RTMP Distribution 으로 분류됨
③ Edge Location
- 오리진에서 Distribution 을 통해 배포되는 콘텐츠를 캐싱하는 장치
- 리전별 Edge Cache 가 존재하고, 하위에 Edge Location 이 구성되어 콘텐츠 캐싱
④ 보안 장치
- OSI 3/4 계층 DDoS 를 완화하는 AWS Shield 및 OSI 7계층을 보호하는 AWS WAF 와 통합하여 보안을 강화
⑤ 도메인 구성
- Distribution 생성 시 xxx.cloudfront.net 형태의 도메인이 생성되는데 해당 도메인으로 접근해도 되고, Route 53 과 연결하여 사용자가 원하는 도메인으로 Alias 부여 가능
⑥ 사용자
- 위의 도메인으로 접근하여 콘텐츠 제공받음
3. CloudFront 를 통한 CDN 서비스 테스트
상파울루 리전에 EC2 Instance 구성 후 로컬(대한민국)에서 직접 연결하는 것과 AWS CloudFront 를 통한 CDN 서비스 연결하는 것의 차이를 알아본다.
- 기본 환경 구성
- CloudFormation 적용
- CloudFormation 을 통해 생성된 자원 확인
- Route 53 설정 (EC2 Instance A Record 연결)
- 기본 통신 환경 검증
- CloudFront 설정과 Route 53 연결
- CloudFront Distribution 생성
- Route 53 설정 (CloudFront A Record 연결)
- CloudFront 검증
- Resource 삭제
3.1. 기본 환경 구성
- CloudFormation 적용
- CloudFormation 을 통해 생성된 자원 확인
- Route 53 설정 (EC2 Instance A Record 연결)
- 기본 통신 환경 검증
3.1.1. CloudFormation 적용
서울 리전이 아닌 상파울루 리전(sa-east-1) 에 AWS Resource 를 생성한다.
[CloudFormation] - [Stacks]
CloudFormation Template Download CloudFormation Template (펼쳐보기)
Parameters:
LatestAmiId:
Description: (DO NOT CHANGE)
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
AllowedValues:
- /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
Resources:
SaVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.10.0.0/16
EnableDnsHostnames: true
Tags:
- Key: Name
Value: jhSA-VPC
SaIGW:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: jhSA-IGW
SaIGWAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref SaIGW
VpcId: !Ref SaVPC
SaPublicRT:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref SaVPC
Tags:
- Key: Name
Value: jhSA-Public-RT
SaDefaultPublicRoute:
Type: AWS::EC2::Route
DependsOn: SaIGWAttachment
Properties:
RouteTableId: !Ref SaPublicRT
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref SaIGW
SaPublicSN1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref SaVPC
AvailabilityZone: !Select [0, !GetAZs '']
CidrBlock: 10.10.0.0/24
Tags:
- Key: Name
Value: jhSA-Public-SN-1
SaPublicSNRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref SaPublicRT
SubnetId: !Ref SaPublicSN1
WEBSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable HTTP access via port 80 and SSH access via port 22
VpcId: !Ref SaVPC
Tags:
- Key: Name
Value: jhWEBSG
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '80'
ToPort: '80'
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
SaEC2:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: !Ref LatestAmiId
Tags:
- Key: Name
Value: jhSA-EC2
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref SaPublicSN1
GroupSet:
- !Ref WEBSG
AssociatePublicIpAddress: true
UserData:
Fn::Base64: !Sub |
#!/bin/bash
(
echo "CN@12c"
echo "CN@12c"
) | passwd --stdin root
sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/g" /etc/ssh/sshd_config
sed -i "s/^#PermitRootLogin yes/PermitRootLogin yes/g" /etc/ssh/sshd_config
service sshd restart
wget https://cloudneta.github.io/test.jpg
wget -P /usr/share/nginx/html/ https://cloudneta.github.io/test.jpg
amazon-linux-extras install -y nginx1.12
echo "<head><link rel='icon' href='data:;base64,iVBORw0KGgo='></head><h1>CloudNet@ CloudFront Test!!</h1><img src='test.jpg'>" > /usr/share/nginx/html/index.html
systemctl start nginx
systemctl enable nginx
3.1.2. CloudFormation 을 통해 생성된 자원 확인
- VPC
- jhSA-VPC
- IP CIDR: 10.10.0.0/16
- jhSA-VPC
- Public Subnet
- jhSA-Public-SN-1
- IP CIDR: 10.10.0.0/24
- AZ: sa-east-1a
- jhSA-Public-SN-1
- Public Routing Table
- jhSA-Public-RT
- 연결: jhSA-Public-SN-1
- jhSA-Public-RT
- IGW
- jhSA-IGW
- 연결: jhSA-VPC
- jhSA-IGW
- Public EC2 Instance
- jhSA-EC2
- 연결: jhSA-Public-SN-1
- 데몬: HTTP 구성
- root 계정 로그인: 암호 CN@12c
- jhSA-EC2
- Security Group
- jhWEB-SG
- 프로토콜(inbound): SSH, HTTP
- 대상(Source): 0.0.0.0/0
- jhWEB-SG
3.1.3. Route 53 설정 (EC2 Instance A Record 연결)
Route 53 A Record 를 생성하여 jhSA-EC2 Instance 의 Public IP 와 연결한다.
[Route 53] - [Hosted zones] - [선택] - [Create record] - [Simple routing] - [Define simple record]
중도에 jhjhtest.com 에서 jhtesttest.com 으로 도메인 재취득했음
3.1.4. 기본 통신 환경 검증
이제 상파울루 리전의 jhSA-EC2 로 웹접근을 해본다.
해당 웹페이지에는 대용량 이미지가 구성되어 있어 지연시간이 꽤 길게 나올 것이다. 개발자 도구를 통해 지연시간을 확인해보자.
캐시 삭제 후 재접속시에도 비슷하게 15s 정도 소요되는 것을 알 수 있다.
3.2. CloudFront 설정과 Route 53 연결
- CloudFront Distribution 생성
- Route 53 설정 (CloudFront A Record 연결)
- CloudFront 검증
3.2.1. CloudFront Distribution 생성
CloudFront 에서 오리진을 EC2 Instance 로 지정할 때는 Public DNS 주소(=EC2 Instance 의 Public DNS 주소)가 필요하다.
CloudFront Web Distribution 을 생성하여 오리진 웹 서버에 대한 콘텐츠를 전 세계의 Edge Location 으로 배포한다.
[CloudFront] - [Distributions] - [Create distribution]
Origin Setting 은 Origin 대상에 대한 설정을 하는 영역이다.
Origin domain
: Origin 에 대한 도메인 이름 지정Origin path
: CloudFront 가 바라보는 Origin 의 기준 경로custom header
: Origin 으로 보내는 요청에 사용자 지정 헤더 추가
Default cache behavior 는 캐시에 대한 정책을 설정하는 영역이다.
프로토콜, HTTP method, 캐시 정책 등을 설정한다.
Path pattern
: Origin 에서 가져올 콘텐츠에 대한 패턴 지정 (*
은 모든 콘텐츠)Viewer protocol policy
: 사용자가 콘텐츠를 액세스하는데 사용할 프로토콜Allowed HTTP methods
: 허용하는 HTTP methodCache policy
: 최소/최대 TTL 설정 및 Cache 키 설정 (헤더, 쿠키, 쿼리)Origin request policy
: Origin 요청에 대한 정책 설정 (헤더, 쿠키, 쿼리)
Distribution settings 은 CloudFront Distribution 에 대해 설정을 하는 영역이다.
Distribution Edge Location 영역 지정, CNAME (Canonical Name), SSL, 로깅 등을 설정한다.
Distribution 설정에서 Alternate Domain Name 을 부여하여 Route 53 과 연결할 예정인데, 이 때 연결 대상 도메인에 대해 SSL 인증서가 등록되어 있어야 한다. AWS Certificate Manager(ACM) 에 들어가 인증서를 먼저 등록한다. (N.Virginia)
[AWS Certificate Manager] - [Request certificate]
ACM 등록 후 Status 를 보면 Pending validation
인 것 을 확인할 수 있는데, 검증을 위해선 Route 53 에 CNAME Record 를 추가해야 한다.
아래에서 Create records in Route 53 을 누르면 CNAME Record 가 생성된다.
레코드 생성 후 잠시 기다리면 Status 가 Pending validation
에서 Issued
로 변경되며 등록이 완료된다.
ACM 발급의 자세한 내용은 AWS Certificate Manager 인증서 관리 을 참고하세요.
Price class
: 배포할 Edge Location 범위Alternate domain name (CNAME)
: CloudFront Distribution 의 도메인 이름에 대한 alias 지정 (Route 53 도 설정)Default root object
: 최상위 주소로 접근 시 보여줄 Root 대상 지정
약 10~15분 후 Status 가 Deploying
에서 Enabled
로 변경되는 것을 확인할 수 있다.
3.2.2. Route 53 설정 (CloudFront A Record 연결)
Route 53 A Record 를 생성하여 CloudFront Distribution 과 Alias 연결을 한다.
[Route 53] - [Hosted zones] - [선택] - [Create record] - [Simple routing] - [Define simple record]
3.2.3. CloudFront 검증
이제 로컬에서 CloudFront Distribution 으로 웹 접근을 해본다.
위의 3.1.4. 기본 통신 환경 검증 에서는 약 15s 가 소요된 부분을 기억하자.
최초 접근 시 약 4s 가 소요되었다.
최초로 CloudFront Distribution 에 접근 시 오리진(EC2) 로부터 콘텐츠를 받고, CloudFront Distribution 은 설정된 모든 Edge Location 으로 콘텐츠를 배포한다.
개발자 도구에서 이미지 파일 클릭 수 헤더 정보를 보면 X-Cache
필드값이 Miss from cloudfront
인 것을 확인할 수 있는데, 이것은 콘텐츠 응답을 Edge Location 이 아닌 Origin 을 통해 응답을 주었다는 것을 의미한다.
① 사용자는 CloudFront Distribution 도메인(cdn.jhtesttest.com) 으로 웹 접근
② Distribution 은 최초 연결이므로 Origin 서버인 jhSA-EC2 로 콘텐츠 요청 후 응답을 받음
③ 사용자에게 웹 접근에 요청에 대한 응답을 줌
④ Distribution 은 설정된 모든 Edge Location 으로 배포하여 동기화함
이제 캐시를 지운 후 다시 CloudFront Distribution 으로 웹 접근을 해보자.
약 1s 로 훨씬 짧은 지연시간과 이미지 파일의 헤더 정보 중 X-Cache 의 값이 Hit from cloudfront
인 것을 확인할 수 있다.
이것은 콘텐츠 응답을 Edge Location 이 응답 주었다는 의미로, 사용자와 가장 인접한 Edge Location 이 응답해준 것을 의미한다.
① 사용자는 CloudFront Distribution 도메인(cdn.jhtesttest.com) 으로 웹 접근
② 최초 접근 시 Edge Location 으로 콘텐츠가 배포된 상태이므로 사용자가 가장 인접한 Edge Location 이 응답해줌
3.3. Resource 삭제
아래의 순서대로 Resource 를 삭제한다.
- Distribution 삭제 ([CloudFront] - [Distributions] - [선택] - [Disable] - [대기] - [Delete])
- ACM 삭제 (N.Virginia) ([Certificate Manager])
- 호스팅 영역 Record 삭제 ([Route 53] - [Hosted zones] - [Records])
- CloudFormation Stack 삭제 ([CloudFormation] - [Stacks] - [Delete])
- 상파울루 EC2 는 Public Subnet 에 위치하고, SSH 로그인 방식이 key 방식이 아닌 암호 입력 방식으로 SSH 무차별 대입 공격이 발생할 수 있으니 반드시 삭제를 확인할 것
CloudFormation Stack 이 삭제되면 위의 3.1.2. CloudFormation 을 통해 생성된 자원 확인 의 자원이 모두 삭제되었는지 확인한다.
참고 사이트 & 함께 보면 좋은 사이트
본 포스트는 김원일, 서종호 저자의 따라하며 배우는 AWS 네트워크 입문를 기반으로 스터디하며 정리한 내용들입니다.
- 따라하며 배우는 AWS 네트워크 입문
- 따라하며 배우는 AWS 네트워크 입문 - 책가이드
- 따라하며 배우는 AWS 네트워크 입문 - 팀블로그
- Amazon CloudFront 주요 기능
- AWS Certificate Manager 인증서 관리