스스로 구축하는 AWS 클라우드 인프라

Seung jun Cha·2023년 11월 2일
0

1. 서버리스 정적 웹사이트 호스팅 및 성능 가속화

  • 서버가 없어도 구성이 가능한 정적 웹 사이트를 호스팅하고, 콘텐츠 전송 네트워크(CDN) 서비스를 이용하여 웹 사이트의 성능을 향상시킵니다
    • Amazon S3 (Simple Storage Service)
      Amazon CloudFront
      CloudFront는 aws에서 제공하는 CDN 서비스이다.

① (us-east-1) S3 Bucket 생성
② Object(File) 업로드
③ 정적 웹 사이트 호스팅 기능 활성화


속성부분에서 호스팅 설정을 한다. 인덱스 문서는 S3버킷으로 웹사이트 호스팅이 되었을 때 보여주는 기본 페이지이다.

④ Bucket과 Object에 대한 액세스 정책 설정 (먼저 활성화되어있는 모든 퍼블릭 엑세스 차단을 비활성화 해야한다.)

S3버킷에 대한 엑세스 차단을 수정한다. 그리고 버킷 정책에서 정책 생성기를 눌러서 정책을 설정한다.
(권한 -> 버킷정책 편집 -> 정책 생성기)


  • 타입은 S3 Bucket Policy로 설정.
    Effect : Allow,
    Principal : * ,
    Actions : GetObject(조회만 가능하다)
    ARNarn:aws:s3:::버킷이름/* 으로 설정해준다.
    주의해야 할 점은 ARN에 버킷 ARN을 복붙한다음 /*을 추가해야 한다는 것이다.
arn:aws:s3:::lab-s3-web-hosting-inflean/*
arn:aws:s3:::studyprojects3/*



생성된 정책을 복붙하고 저장한다.
⑤ 웹 브라우저에서 웹 사이트 작동 확인

1-1 CloudFront를 통한 웹사이트 성능 가속화

  • 배포된 S3를 바탕으로 CloudFront를 생성하면 해당 S3에 있는 데이터들이 캐싱이 된다.
  • 이전요청에서 사용되었던 캐시키와 현재 사용자의 요청으로 만들어진 캐시 키가 동일한 경우를 캐시 히트라고 하는데, 캐시키가 같다면 클라우드 프론트에서 캐시된 객체가 전달된다.

    배포된 CloudFront를 사용하면 캐시데이터를 불러올 수 있다. 캐시데이터를 가지고 온 것이 맞다면 개발자도구에서 아래처럼 Hit이 나온다
https://d1g40qtzup6h2g.cloudfront.net/

X-Cache: Hit from cloudfront

2. LAMP 웹 서버 및 Application Load Balancer 구성

  • 클라우드 네트워크 환경에 Linux 기반의 가상 서버에 Apache 웹 서버, MySQL 데이터베이스, PHP 어플리케이션을 구성하고 Application Load Balancer를 이용하여 이중화 된 네트워크를 구성합니다.

2-1 기본 네트워크 환경 구성

  • vpc : 우리끼리 사용하는 독립된 아이피 주소로 vpc별로 네트워크를 구성할 수 있다.

  • CIDR(Class Inter Domain Routing) : CIDR 블록은 VPC 내의 인스턴스 및 리소스에 할당되는 IP 주소를 결정합니다. CIDR 블록을 AWS 인프라에 따라 서브넷으로 나누어서 사용하게 됩니다. CIDR 블록에서 '/16'의 의미는 IP의 길이를 나타내는 프리픽스로 CIDR의 범위는 /16에서 /28까지 가능합니다.

  • 서브넷 : vpc를 쪼갠다. 서브넷을 나누는 이유는 더 많은 네트워크망을 만들기 위해서이다. 인터넷과 연결이 되어 있느냐 아니냐에 따라서 public, private 서블릿으로 나뉜다.

  • 라우트 및 라우트테이블 : 네트워크 요청이 발생하면, 데이터는 라우트테이블에서 정한 라우트로 향한다. 즉, 라우트는 데이터의 목적지이다.

    • 서브넷A의 라우팅테이블은 172.31.0.0/16 즉 VPC안의 네트워크 범위를 갖는 네트워크 요청은 로컬에서 찾도록 되어있습니다. 하지만 그 이외 외부로 통하는 트래픽을 처리할 수 없습니다.
    • 서브넷B의 라우팅테이블을 잘보면 0.0.0.0/0으로 정의되어있습니다. 이뜻은 모든 트래픽에 대하여 IGA(인터넷 게이트웨이) A로 향하라는뜻입니다. 라우팅테이블은 가장 먼저 목적지의 주소가 172.31.0.0/16에 매칭되는지를 확인한 후 매칭되지 않는다면 IGA A로 보냅니다.
  • 인터넷 게이트웨이 : VPC와 인터넷을 연결해주는 하나의 관문이다.

  • EC2 : AWS에서 원격으로 제어할 수 있는 가상의 컴퓨터를 한 대 빌리는 것

  • NAT 게이트웨이 : 프라이빗서브넷이 인터넷과 통신하기위한 아웃바운드 인스턴스입니다. 프라이빗 네트워크가 외부에서 요청되는 인바운드는 필요없더라도 인스턴스의 펌웨어나 혹은 주기적인 업데이트가 필요하여 아웃바운드 트래픽만 허용되야할 경우가 있습니다.
    (private 서브넷 -> NAT 게이트웨이 -> 인터넷 게이트웨이 -> 인터넷)

  1. vpc 생성
  2. vpc가 나누어 놓은 하위 네트워크인 6개의 서브넷 구성
  3. 외부인터넷과 통신이 가능하도록 인터넷게이트웨이와 라우트테이블 생성 그리고 라우트 설정
  4. 아마존 머신 이미지(AMI)를 사용해서 동일한 ec2를 추가 생성
  • vpc가 나누어 놓은 하위 네트워크인 6개의 서브넷 구성
    트래픽이 이동하여 외부인터넷과 통신이 가능하도록 인터넷게이트웨이와 라우트테이블 생성 그리고 라우트 설정
    (생성된 인터넷 게이트 웨이는 어떤 // 라우트 테이블 : 데이트 패킷
    아마존 머신 이미지(AMI)를 사용해서 동일한 ec2를 추가 생성

  • 외부 인터넷과 인터넷 게이트워이를 통해 직접 통신이 가능한 퍼블릭 서브넷
    EC2 인스턴스에 필요한 소프트웨어를 설치하면 웹서버로 활용가능
    efs는 각 서브넷에 마운트타겟을 통해 ec2인스턴스와 연결되고 파일을 공유
    브라이븟 ec2에 접근하기위해 퍼블릭에 위치한 ec2를 이용한다. 이러한 ec2를 Bastion이라고 한다
    트래픽 증가 등 문제에 대비하기 위해 프라이빗에 복수의 웹서버를 구성하고 이 인스턴스들을 로드밸런스에 연결

vpc에서 사용하는 ec2들이 호스트 네임을 사용할지 말지 결정하는 설정이다.
서브넷의 CIDR은 VPC의 CIDR보다 작아야한다.

  1. vpc 생성, 설정

    DNS 호스트 이름 활성화를 체크한다. vpc에서 사용하는 ec2들이 호스트 네임을 사용할지 말지 결정하는 설정이다
  2. 서브넷 생성

    지금은 public 2개, private 4개로 총 6개의 서브넷을 생성한다.
public-subnet-a1
10.1.1.0/24
  1. 트래픽이 이동하여 외부인터넷과 통신이 가능하도록 인터넷게이트웨이와 라우트테이블 생성 그리고 라우트 설정

    생성된 인터넷게이트웨이는 어떤 vpc의 게이트웨이 역할을 하는지 알아야 하기 때문에 VPC에 연결

  2. 라우팅 테이블 생성 : 라우트 테이블은 VPC 에 존재하는 서브넷들이 특정한 범위의 IP 목적지를 향할 때, Target 을 정해주는 역할을 한다.

    생성한 라우트테이블과 서브넷을 연결한다. 지금은 public 서브넷은 IGA와 연결하고 private 서브넷은 NAT과 연결했다.
    public 서브넷의 요청은 IGA로 가게되고, private 서브넷의 요청은 NAT로 간다.

  3. public 라우트 테이블과 인터넷게이트웨이를 연결한다. 이것으로 트래픽이 설정된 인터넷게이트웨이를 통해 외부로 나가게 된다. private 라우트 테이블은 외부와 직접 연결하지 않는다.

  4. 서브넷별로 반복한다.

2-2 EC2 생성


EC2 생성시 이전에 만들었던 vpc와 서브넷을 적용한다.

웹서버로 사용하기 때문에 보안그룹은 HTTP, HTTPS를 추가한다. 여기서 소스 유형은 어디에서 오는 트래픽을 받을 것인지 결정하는 것이다.

사용자 데이터는 아래와 같다

#!/bin/bash
yum update -y
amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2
yum install -y httpd mariadb-server
systemctl start httpd
systemctl enable httpd
usermod -a -G apache ec2-user
chown -R ec2-user:apache /var/www
chmod 2775 /var/www
find /var/www -type d -exec chmod 2775 {} \;
find /var/www -type f -exec chmod 0664 {} \;

그리고 인스턴스 생성시 발급받은 key pair를 putty를 사용해서 ppk확장자로 변환한다. 만들어진 ppk파일로 서버에 접속할 수 있다.

2-2 Custom AMI를 통한 Public EC2 인스턴스 생성

  • EC2를 시작하기 위한 기본 세팅의 모음으로 동일한 구성의 인스턴스가 여러개 필요할 때 한 AMI에서 여러 인스턴스 시작이 가능하다.

    존재하는 인스턴스를 기반으로 AMI를 생성한다.

    새로운 인스턴스를 생성할 때 AMI를 기반으로 생성한다. 그러면 해당하는 인스턴스 정보를 기반으로 새로운 인스턴스가 만들어진다.

2-3 EFS를 통한 네트워크 파일 시스템 구성

  • EFS는 리눅스 인스턴스를 위한 확장성, 공유성 높은 파일 스토리지로, EC2 Linux 인스턴스에 마운트된 Network File System(NFS)을 통해 VPC에서 필요한 파일에 접근하거나 AWS Direct Connect로 연결된 온프레미스 서버의 파일에 접근할 수 있다. 수천대의 EC2 인스턴스간 파일 시스템 공유 가능하며, 병렬 접근이 가능하도록 설계되어 있어, 두 개 이상의 EC2로부터 하나의 공유된 스토리지 공간이 필요할 때 EFS를 채택하면 된다.

    1. VPC에서 EFS전용 보안그룹을 생성한다. 이것은 EFS 및 EC2 인스턴스에 대한 액세스를 제어하는 역할을 한다. 아웃바운드 규칙은 그대로둔다.

시큐리티 그룹을 통해 나오는 nfs트래픽을 efs의 마운트 타겟(EC2)에 마운트 한다.

2. 마운트할 EC2 인스턴스가 위치하는 VPC, 가용 영역, 서브넷을 선택한다. 서브넷 아이디는 a1, c1을 선택하고 보안그룹은 efs를 위해 만든 시큐리티 그룹을 적용한다

  1. EFS 마운트 하기 (EC2 연결하기)
    putty를 사용해서 마운트 할 EC2에 접속한다. 몇 가지 방법이 있지만 지금은 efs 마운트 헬퍼를 사용한다.
yum install amazon-efs-utils -y

cd /var/www/html
mkdir efs

그 다음 마운트를 위해 마운트 포인트를 생성한다. 어디에 생성하든 위치는 상관없다. 지금 포인트는 efs 폴더로 적용했다.

efs서비스의 연결에 들어가서

지금은 마운트 헬퍼를 사용하기 때문에 해당하는 부분을 복사해서 putty에서 적용한다.

sudo mount -t efs -o tls fs-0e64e6805b8494d11:/ efs
df -h

이 명령어를 사용해서 확인해보면

/var/www/html/efs 가 마운트 포인트로 적용된 것을 확인할 수 있다.

S3에 들어가서 저장된 파일을 가져와보자. 원하는 파일의 객체 url을 복사해서 putty에 아래처럼 적용한다. 이 과정을 진행하는 폴더는 마운트 포인트가 적용된 폴더여야한다.(지금은 efs폴더이다)

wget https://lab-s3-web-hosting-inflean.s3.amazonaws.com/car.jpg

그리고 마운트 된 EC2의 ip를 가져와서 적용해보자(지금은 a1이다)

http://43.202.31.40/efs/mycar.html

다음에 c1에 적용할 때는 s3에서 파일을 가져오는 과정이 필요없다. efs는 인스턴스들이 공유하고 있고 a1에서 이미 파일을 가져와서 s3에 존재하기 때문이다.

2-5 Application Load Balancer를 통한 이중화 네트워크 구성(ELB)

  • 로드밸런서는 트래픽을 하나의 경로로 받고, 받은 트래픽을 여러 대상에 자동으로 분산시켜 안정적인 AWS서버 환경을 운용하는데에 도움을 주는 서비스이다.
  • 서로 다른 EC2 인스턴스에 대한 하나의 엔드포인트를 제공한다. 그래서 사용자는 실제 요청이 처리되는 백엔드 인스턴스에 대한 고려 없이, 동일한 엔드포인트로 요청을 전송할 수 있다.
  • ELB는 Virtual Private Network(VPC)Visit Website에 탑재되며, 외부의 요청을 받아들이는 리스너(Listener)와 요청을 분산/전달할 리소스의 집합인 대상 그룹(Target Group)으로 구성된다

    먼저 로드밸런서가 로드밸런싱을 할 대상인 타겟그룹을 생성한다.

  • 타겟그룹을 생성하고 이제 로드밸런서를 생성한다.

    로드밸런서가 어느 서브넷으로 트래픽을 보낼지 정하는 부분이다.

    로드밸런서용 보안그룹을 만들고 적용한다.

    클라이언트 또는 외부환경과 로드밸런서 사이의 통신규칙을 정하는 것이다. HTTP 80 포트로 요청이 오면 타겟그룹의 인스턴스로 트래픽을 보내겠다는 것이다.

2-6 Bastion host와 NAT Gateway를 통한 Private EC2 인스턴스의 외부 통신 구성

  • private 서브넷은 외부 인터넷을 차단하고 내부에서만 사용하기 위해 만든 Subnet이다. 그런데 만일 private 서브넷에 들어가 있는 서비스를 외부 인터넷을 통해 업데이트를 해야 할 일이 생긴다면 어떻게 해야할까?"
    바로 이러한 경우에 사용하는 것이 NAT Gateway와 Bastion Host 기술이다.
    이 둘은 사설망의 구조를 유지시켜주면서 외부와 조건적으로 데이터 통신이 가능하게 해준다.
  • 다만 NAT Gateway는 서브넷에서 외부로 나갈수는 있어도, 거꾸로 외부에서 private 서브넷으로 접속은 못한다. 만일 ssh로 외부에서 인스턴스에 접속해 조정할 일이 있다면, private 서브넷은 어떻게 접속해서 해야할까? 바로 이러한 역할을 해주는게 Bastion Host이다.
  • Bastion Host란 private 서브넷과 연결되어 private 서브넷에 접속할수있는 public 서브넷을 그냥 Bastion Host라고 일컫는 것이다.
    관리자가 Bastion Host으로 SSH 연결을 한 후 Bastion Host에서 Private Subnet의 Host에 SSH 연결을 하는 형태로 Private Subnet에 접근할 수 있게 된다.
    정리하자면, NAT가 Private Subnet에서 외부와 통신하는 수단이라면, Bastion Host는 외부에서 Private Subnet과 통신하는 수단이라고 보면 된다.
  1. 인스턴스 메뉴에서 AMI를 사용해서 private-ec2-a1 서브넷을 생성한다. public을 생성할 때와 거의 같다.

  2. public-ec2-a1(Bastion Host)을 통해 private-ec2-a1에 접속 가능하도록 설정한다.
    먼저 public-ec2-a1에 접속한다. 여기서 private-ec2-a1를 생성할 때 만들었던 키페어(.pem)파일을 편집해야한다.

vi ec2-private-seoul.pem

private-ec2-a1의 키페어 파일을 메모장으로 열고 내용을 모두 복사한 후 새로 생성하는 ec2-private-seoul.pem파일에 붙여넣기한다.

3. ec2-private-seoul.pem파일에 대한 접근권한을 설정한다.

chmod 400 ec2-private-seoul.pem
  1. private-ec2-a1에 접속
ssh -i ec2-private-seoul.pem ec2-user@private-ec2-a1의 private ip
  1. NAT Gateway 생성 : public 서브넷과 연결

    NAT 게이트웨이는 Private Subnet과 외부와의 통신 매개체 이기 때문에, 외부에 접근할 수 있어야 하기 위해선 서브넷을 꼭 Public Subnet으로 할당하여야 한다.
  2. private 서브넷의 라우트 테이블에 NAT Gateway를 추가해서 ec2인스턴스가 외부와 통신할 수 있게 한다.

    private-subnet-a1-rt를 선택해서 라우팅 편집을 한다. private subnet의 라우팅 테이블의 라우트 설정을 변경하여 0.0.0.0/0 즉 모든 패킷을 nat로 설정을 추가하면 된다.

    프라이빗 서브넷에서 트래픽이 외부로 나갈때 퍼블릭 서브넷에 있는 NAT Gateway로 트래픽이 전달된다. 그리고 Elastic IP(공인 IP)로 주소를 변환한 후 Internet Gateway를 통해 공인 인터넷으로 나아가게 된다.

2-7 Application Load Balancer를 통한 이중화 네트워크 구성 (2)

  • 웹서버를 private 영역에 둔다


    로드밸런서에 적용하는 보안그룹도 새로 생성한다.
  • 과정
    사용자의 요청 - 로드밸런서 - private 서브넷의 ec2 인스턴스 - 요청의 응답 - 로드밸런서 - 인터넷 - 브라우저에 출력

3. Amazon RDS를 통한 MySQL 데이터베이스 이중화(Multi-AZ) 구성

3-1 Amazon RDS를 통한 MySQL 데이터베이스 이중화(Multi-AZ) 구성

  • RDS에 적용한 보안그룹은 rds생성단계에서 만들 수도 있지만 ip문제로 인해 vpc에서 미리 생성하는 것을 추천한다.

    인바운드 규칙의 소스는 vpc의 CIDR로 지정한다

    private subnet에서만 RDS에 접근할 수 있게 RDS의 서브넷 그룹에서 private 서브넷을 추가한다.
    다음으로 RDS에 들어가서 데이터베이스를 생성한다. 설명은 생략

3-2 웹 서버와 데이터베이스 인스턴스 연결

  1. putty를 사용해서 public을 통해 private-ec2-a1에 접속한다. index.php가 있는 경로에 dbinfo.inc파일을 생성한다.
  2. Db정보를 구성한다. 엔드포인트, 비밀번호, rds이름 등

  3. private-ec2-c1도 똑같이 반복한다.
  4. 로드벨런서에서 private 로드벨런서의 DNS 이름을 복사하고 인터넷으로 들어가본다.
  5. private-ec2-a1에 다시 들어가서 DB에 접속한다.
mysql -h RDS Endpoint -P 3306 -u admin -p
  1. 테이블을 만드는 등 DB에서 하는 작업들을 수행한다. prvate 서브넷들은 하나의 DB를 공유한다.

3-3 데이터베이스의 Read replica 생성 및 웹 서버 연결


Read replica를 생성 후 원본 DB와 직접 연결되어 있는 인스턴스를 Read replica에 연결하는 것으로 수정한다.
원본 DB의 엔드포인트를 rrDB의 엔드포인트롤 수정하면된다.
원본 DB의 데이터를 수정하고 rrDB로 확인했을 때 수정되었는지 확인해본다.

3-4 Failover를 통한 데이터베이스 이중화 테스트

  • master DB, rrDB, standBy DB 이렇게 3개가 만들어졌다.
 dig lab-vpc-rds.chjqyckes5pk.ap-northeast-2.rds.amazonaws.comdig lab-vpc-rds.chjqyckes5pk.ap-northeast-2.rds.amazonaws.com

위의 명령어는 마스터 DB의 엔드포인트를 입력한 것이다. ip를 확인해본다.

그리고 장애 조치로 재부팅을 누르고 재부팅을 한 후 저 명령어를 입력하면 ip주소가 바뀐 것을 확인할 수 있다. 이유는 마스터 DB가 장애로 재부팅되면서 standBy DB가 실행됐기때문이다. 변경된 ip주소는 standBy DB의 ip주소이다.

4. Auto Scaling을 통한 확장성 및 탄력성 구현

4-1 Launch Template 및 Application Load Balancer 구성

  • private ec2에 대한 ami 이미지를 생성한다.

  • EC2 -> 시작 템플릿 -> 시작 템플릿 생성에서 템플릿을 생성한다.


  • target group 생성

    인스턴스를 추가하지 않고 그냥 타겟그룹을 생성한다. 오토스케일링 그룹에 연결되는 로드밸런서의 타겟그룹이기 때문에 오토스케일링을 통해 생성되는 인스턴스들이 이 타겟그룹에 자동으로 등록이 된다.

  • 로드 밸런서 생성

오토스케일링 그룹에 연결된 로드밸런서가 사용할 security group를 생성한다

4-2 Auto Scaling Group 및 Scaling Policy 구성

  • 템플릿을 사용해서 Auto Scaling Group 생성
  • 오토스케일링 그룹을 통해 생성되는 인스턴스가 어느 서브넷에 생성되게 할 것인지 정한다
  • Auto Scaling Group에 로드밸런서를 설정
  • Auto Scaling Group 및 크기 조정 구성
  1. 원하는 크기 : 평상시에 유지하고 있을 인스턴스 수
  2. 원하는 최소용량, 최대용량 : 말 그대로 최소, 최대로 유지할 인스턴스의 수
  • 인스턴스 확인 : 정해진 인스턴스 용량을 충족하기 위해 2개의 인스턴스가 새로 생성되었다. 2a과 2c 서브넷에 각각 생성되었다. Auto Scaling으로 생성된 인스턴스들이 target group에 등록된 것도 볼 수 있다.

4-3 Auto Scaling Scale-Out 테스트

  • putty를 통해 public-ec2-a1에 접속한다. 그리고 로드밸런서에 부하를 준다.
ab -n 20000 -c 1000 http://lab-vpc-alb-asg-711088071.ap-northeast-2.elb.amazonaws.com/
  • CloudWatch에서 CPU 부하를 점검해보자
  • EC2에서 인스턴스의 개수가 증가했는지 그리고 Auto Scaling활동내역도 확인해보자. 새로운 인스턴스 2개가 생성되었고 오토스케일링이 작동한 것을 확인할 수 있다.

4-4 Auto Scaling Scale-In 테스트

ab -n 20000 -c 1000 http://lab-vpc-alb-asg-711088071.ap-northeast-2.elb.amazonaws.com/

이 요청이 다 끝나고 시간이 지나서 CPU 사용량이 감소하면 자동으로 Scale-In되어서 생성된 인스턴스가 삭제된다.
Auto Scaling 활동내역에 들어가서 확인해보자.

  • Auto Scaling 전략

-참고
aws 참고 블로그

0개의 댓글