VPC

vpc cidr : 10.0.0.0/16

서브넷

Subnet 간단 개념
  • 개념 : VPC의 IP 주소 범위를 나누는 단위.

  • 역할분리 - 외부에 공개하느 리소스 여부를 구별

  • 기기 분리 - AWS 안에서의 물리적인 이중화(다중화)를 수행

subnet cidr :

  1. 10.0.0.0/20(public1)

  2. 10.0.16.0/20(public2)

  3. 10.0.64.0/20(private1)

  4. 10.0.80.0/20(private2)

Internet Gateway

internet gateway 생성 후 vpc에 연결

NAT Gateway

NAT Gateway : private subnet 2개에 각각 대응해줄 2개의 NAT Gateway 생성 후 “퍼블릭 서브넷”에 1개씩 연결 ( + eip 할당 )

라우팅 테이블

라우팅 테이블 생성

  • 퍼블릭 1개 생성

    • 라우팅 : 0.0.0.0/0 에 대해 인터넷 게이트웨이 연결

    • 서브넷 연결 : 퍼블릭서브넷 2개 모두 연결

  • 프라이빗 2개 생성

    • 라우팅 : 각각 모두 0.0.0.0/0 에 대해 NAT 게이트웨이 연결

    • 서브넷연결 : 각각 프라이빗서브넷 1개씩 분담

**라우팅테이블 부연 설명**
  • 서브넷과 서브넷, 또는 서브넷과 각 게이트웨이가 통신할 수 있는 경로가 필요할 때, 서브넷 사이의 통신 경로를 설정하여 어떤 서브넷 안의 리소스가 해당 서브넷 밖의 리소스에 접근할 수 있도록하는 기능

  • 여러 서브넷이 같은 라우팅 테이블을 공유할 수 있다. 즉, 라우팅테이블:서브넷 = 1:n

  • 책에서는 퍼블릭 라우팅 테이블을 1개만 생성, 퍼블릭 서브넷 1, 2에 연결 프라이빗 라우팅 테이블 2개를 생성, 프라이빗 서브넷 1, 2에 각각 연결

  • 라우팅테이블 > 라우팅 정보에 입력된 대상의 순서는 상관없다. “설정 정보의 순서는 중요하지 않습니다. AWS 라우팅 테이블에서는 목적지 CIDR 블록과 일치하는 가장 구체적인 경로를 찾는 기능을 제공합니다”

💡
라우터 일반적인 네트워크 설계에서는 라우팅 테이블에 수행하는 설정을 라우터(router)라는 기기에 수행한다. 그러나 AWS 관리 콘솔에서는 라우터를 명시적으로 생성할 필요가 없다. 라우팅 테이블을 생성하면 라우터에 해당하는 것도 자동 생성된다.

보안그룹

2개의 보안그룹 생성

  • 점프서버(bastion host)용

    • 인바운드만 설정 > SSH(22포트)에 대해서 Anywhere-IPv4(0.0.0.0/0)
  • 로드밸런서 용

    • 인바운드만 설정 > HTTP(80포트), HTTPS(443)에 대해서 Anywhere-IPv4(0.0.0.0/0)
NACL ↔ 보안그룹 차이
💡
  • 보안그룹 : 리소스(EC2, 로드밸런서, RDS 등)에 대해 설정 가능
  • 네트워크 ACL : 네트워크에 대한 설정. 즉, 해당 서브넷에 포함되는 리소스 모두에 적용 (책 필자의 경우 설정 누락은 인프라스트럭처 설계서 또는 CloudFormation을 이용한 IaC 시스템을 활용해서 방지하고, 네트워크 ACL은 잘 이용하지 않는다고한다.)
💡

점프서버(Bastion Host)

외부에서 리소스로의 접속은 제한된 관리자만 수행할 수 있도록 해야하는데, 이러한 설정을 모든 리소스에 수행하기란 매우 어려우며 설정이 누락될 가능성도 높다. 따라서, 모든 리소스에 접속할 수 있는 입구인 점프서버를 준비하고, 해당 서버를 경유해야만 각 리소스에 접속할 수 있는 방식을 많이 사용한다. 목적한 리소스로의 통호 이외의 용도는 없다. 따라서 성능이 낮아도 되며 OS도 특별히 가리지 않는다.

키페어 생성 (pem키)

점프 서버 생성(Bastion Host)

사용 AMI : Amazon Linux 2 AMI(HVM) - Kernel 5.10, SSD VolumeType

키페어 설정 : 위에서 생성한 키페어 선택

네트워크 설정 :

  • 퍼블릭 서브넷 01 연결 (이 설정을 통해 퍼블릭 서브넷 01 구역 안에 이 EC2가 생성된다)

  • 퍼블릭 IP 자동할당 활성화

  • 기존 보안그룹 2개 연결

    • default

    • 위에서 생성한 sg-bastion

점프 서버(Bastion Host) 접속 확인

# 생성 및 다운로드된 pem키 위치에서
ssh -i {pem키 이름} ec2-user@{Bastion Bublic IP}

# 근데 pem키의 권한이 너무 열려있다고 에러를 뱉는다.(보호된 키 X) -> 
# 다른사람이 액세스할 수 없도록 수정이 필요하다고 한다
chmod 400 {pem키 이름}

# 다시
ssh -i {pem키 이름} ec2-user@{Bastion Bublic IP}

# 접속 성공
# 로그아웃 방법은 logout 혹은 exit 혹은 Ctrl+ D
📌
  1. 키페어를 깃허브와 같은 저장소에 업로드되는 것을 방지하는 git-secrets라는 도구가 제공된다는 점 참고()
  2. 나중에 마이크로 서비스 구축에 흥미가 있다면 AWS가 제공하는 ‘서버리스 컴퓨팅’이라는 유스케이스(https://aws.amazon.com/ko/serverless/) 읽어보기

웹 서버 생성

사용 AMI : Amazon Linux 2 AMI(HVM) - Kernel 5.10, SSD VolumeType

키페어 설정 : 위에서 생성한 키페어 선택

네트워크 설정 :

  • 프라이빗 서브넷 01 설정

  • 퍼블릭 IP 자동할당 비활성화

  • 기존 보안그룹 1개 연결 : default

※ 위와 동일하게 1개 더 생성 → 서브넷만 프라이빗 서브넷 02로 설정

📌
점프서버 보안그룹 : 기본 + SSH 웹서버 보안그룹 : 기본

로드밸런서 생성

인터넷 게이트웨이로의 경로가 있는 서브넷을 지정해야한다는 점 주의(여기서는 퍼블릭 서브넷) 서브넷을 잘못지정하면 외부로부터 웹 서버에 도달할 수 없다.

로그밸런서 개념정리

주요역할 3가지

  1. 요청 분산

  2. SSL(Secure Socket Layer) 처리 HTTPS > 외부로부터의 요청패킷을 복호화하여 웹서버에 전달하고 외부로의 응답 패킷은 암호화하여 정보를 보호하는 기능 웹서버에서 암복호화를 모두 수행하면 부하에 따른 비효율

  3. 부정요청 대응

📌
요청라우팅(Request Routing) : 외부에 공개된 프로토콜과 포트번호의 조합으로 이루어진 요청에서 → 내부의 웹서버가 받는 프로토콜과 포트 번호로 변환하는 기능

하나의 로드밸런서에는 여러 대상 그룹을 지정 가능

ALB 설정 항목 2가지

  • 로드밸런서: 어떤 프로토콜(HTTP, HTTPS)을 이용할 것인지와 같은 설정. 주로 인터넷에서 로드 밸런서로 접근할 때와 관련한 설정을 수행. 클라이언트로부터 처리를 받는 “리스너” 기능

    • Network mapping : 퍼블릭 서브넷 2개 연결

    • 보안그룹 2개 연결 : default, (위에서 생성한) sj-sg-elb

    • Linstener and routing : HTTP, 80 port 설정 후 “Create target group” 클릭

  • 대상 그룹

    • Choose a target type : Instances

    • Protocol : HTTP, Port : 3000(”외부에서 인터넷으로 접근할때는 위에서 설정한 HTTP프로토콜과 포트(80)으로 수신을 수행하지만 로드밸런서에서 복호화해 웹서버에 접근할 때는 HTTP프로토콜, 3000번 포트를 이용한다”)

    • Register targets : 웹서버 2개 선택 후 “include as pending below”

  • 로드밸런서(대상그룹 생성 이 후 이어서 진행)

    • Linstener and routing > Default action에 위에서 생성한 대상그룹 추가

HTTP 작동 확인하기

ssh web01, ssh web02 접속 후 각 서버에서 다음 과정 실행

  1. index.html파일 생성
<html><body>hello world</body><html>
  1. Amazon Linux에 기본설치되어있는 파이썬으로 HTTP 서버 기동
python -m SimpleHTTPServer 3000

index.html파일이 존재하는디렉터리에서 파이썬을 이용해 HTTPS 서버를 기동. 올바르게 기동되면 로드밸런서로부터 헬스체크를 수행할 때마다 정기적인 연결에 대한 액세스 로그가 계속해서 표시된다.

여기까지 진행했더라도 로드밸런서는 곧바로 요청을 라우팅하지 않음. 수 차례 서버에 헬스체크 수행 후, 요청들이 모두 성공한 뒤에야 비로소 요청을 라우팅하기 시작한다.

EC2 대시보드 > Targets groups > Detail page > [Targets] Tab > Health status에서 healthy 상태 확인

이것으로 로드밸런서에 접근할 수 있는 준비 완료.

브라우저를 이용해 작동 확인하기 : 생성한 로드밸런서를 클릭하여 DNS 이름 확인 → 해당 도메인 이름으로 브라우저에서 접근하여 확인 → 정상 확인 완료

로그밸런서의 작동을 확인했으니 이제 서버에서 실행중인 파이썬 프로그램을 Ctrl+D를 눌러 종료 더는 필요없는 index.html도 삭제

데이터베이스 생성

  1. 파라미터 그룹 생성 데이터베이스의 성능 개선, 사용 현황 파악, 기능 추가 등을 수행. 주로 데이터베이스 엔진 고유의 설정을 수행. 사용하는 언어나 데이터베이스 튜닝을 설정할 수 있다.

  2. 옵션 그룹 생성 AWS를 이용한 데이터베이스 모니터링에 관한 설정 등 주로 RDS고유의 설정을 수행

  3. 서브넷 그룹 생성 데이터베이스 서버를 여러 개의 가용 영역에 분산 배치할 때 이용되는 설정. 데이터베이스 서버도 여러 대의 서버를 제공함으로써 신뢰성이나 성능을 높일 수 있다.

  4. 가용영역 : VPC에서 사용되는 가용영역 선택

  5. 서브넷 : 각 가용영역에 해당되는 private 서브넷 선택

※ 데이터베이스는 기본적으로는 보안을 위해 퍼블릭 서브넷을 서브넷 그룹에 추가하지 않는다.

  1. 데이터베이스 생성
데이터베이스 생성방식표준생성
엔진옵션MySQL
템플릿프리티어
마스터 사용자 이름admin
마스터 암호Masterpw (특수문자 들어가게끔 설정했더니 최종적으로 Access denied for user. 연결 실패. 문자열로만 설정 필요)
최초 데이터베이스 이름(공란)

데이터베이스 작동 확인하기

웹 서버에서 접속을 진행한다. 웹 서버에 연결했다면 MtSQL 명령어를 이용해 데이터베이스에 연결한다. MySQL 명령어는 Amazon Linux 2에 기본으로 포함되지 않으므로 별도 설치해야한다.

  1. 먼저 웹 서버에 SSH를 이용해 연결. (ssh web01)

  2. sudo yum -y install mysql

  3. RDS 대시보드에서 데이터베이스 클릭 → 생성한 인스턴스 → 아래쪽의 ‘연결 & 보안’ 탭 → 엔드포인트 및 포트 확인

  4. 웹 서버에서 아래 명령어 입력 후 패스워드까지 입력했을때 “mysqld is alive”가 출력되면 MySQL 데이터베이스에 연결확인 완료 mysqladmin ping -u admin -p -h {데이터베이스의 엔드포인트}

스토리지 생성

EC2 인스턴스는 SSD나 하드 디스크에 해당하는 스토리지를 제공한다.

EBS(Amazon Elastic Block Store)라는 이름으로 제공되는 서비스다. 다만 EBS를 스토리지로 이용하면 다음과 같은 문제가 발생한다.

  • EC2 인스턴스의 OS 자체도 관리해야한다(보안 대응 등)

  • 예측하지 못한 장애 발생 시 대응이 필요한 경우에 대한 준비를 해야한다.

  • EC2 인스턴스를 사용하지 못할 가능성이 있다(SLA(서비스품질보증)에 의하면 1년에 약 5분 정도 서비스가 정지될 가능성이 있다)

이런 문제를 해결하고자 AWS에서 제공되는 서비스가 S3

S3는 내결함성과 비용 측면에서 EBS보다 압도적으로 우수

단점으로는 S3는 어디까지나 외부 스토리지 서비스라는 한계가 있기때문에 EBS와 달리 C드라이브나 D드라이브 등으로 활용할 수 없으며 리눅스나 맥에서의 파일시스템처럼 마운트할 수도 없다.

S3와 VPC의 관계

지금까지 다뤄본 서비스는 모두 VPC 안에 생성. 그러나 S3는 VPC 밖에 생성. 따라서 S3에 접근하는 방법으로는 다음과 같은 두가지를 고려할 수 있다.

  • 인터넷으로부터 직접 접근

  • VPC로부터 접근 이 경우 S3 버킷에 대한 접근 권한이 필요하다. 이 권한은 일반적으로 IAM의 역할(role)이라는 개념을 이용해서 적용한다. 즉, S3 버킷에 접근할 수 있는 “정책을 가진 역할”을 생성하고 그 역할을 EC2에 적용한다.

💡
기술적으로는 S3에 접근할 수 있는 “정책을 가진 사용자”를 만든 뒤 해당 사용자의 권한과 액세스 키를 조합해 S3 버킷에 접근하는 것도 가능하다. 단, “역할”을 이용하는 방법을 보통 더 많이 이용한다.

버킷 생성시 이 버킷의 퍼블릭 액세스 차단 설정에서** **‘모든 퍼블릭 액세스 차단’(기본값)을 설정한다. 따라서 의도하지 않은 열람이나 변경을 방지. 이렇게 버킷을 우선 생성하고, 이후 용도에 맞춰 필요한 접근 권한만 부여하는 게 좋다.

”EC2가 S3에 접근할 수 있는 권한”을 가진 역할 생성하기

AmazonS3FullAccess 정책을 사용해서 만드는 방법이 있지만 ‘특정 S3 버킷에만 연결할 수 있는 정책 설정’을 사용해본다

기본적으로 AamazonS3FullAccess 정책은 다음과 같다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*",
                "s3-object-lambda:*"
            ],
            "Resource": "*"
        }
    ]
}

이것을 활용하여 원하는 버킷을 특정할 수 있다 ▼

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*",
                "s3-object-lambda:*"
            ],
            "Resource": [
                "arn:aws:s3:::(bucketname)",
                "arn:aws:s3:::(bucketname)/*"
            ]
        }
    ]
}

위의 코드를 통해 ‘특정 S3 버킷에만 연결할 수 있는 정책’을 생성한 다음, 이 정책을 통해 역할을 생성한다

  • 신뢰할 수 있는 엔터티 유형 : AWS 서비스 / EC2

  • 권한 추가 > 권한 정책 : 위에서 생성한 정책 선택

EC2에 역할 적용하기

EC2 콘솔 > 웹서버 인스턴스 클릭 > 작업 > 보안 > IAM 역할 수정 > 위에서 생성한 역할 부여

작동 확인하기

Amazon Linux 2는 S3와 같은 AWS 리소스를 조작하는 명령어를 제공하므로, 이를 이용해 S3 버킷에 파일을 업로드 해본다.

  1. 웹서버 접속 → 홈디렉토리에 test.txt 파일 생성

  2. aws s3 cp test.txt s3://{버킷이름}

  3. S3에 업로드 완료