AWS 아키텍쳐 구성하기 (EC2, ELB, AutoScaling 등)

‍정진철·2023년 12월 25일
0

전체 흐름도

보안그룹 (Security Group) 설정

1. ALB (Application Load Balancer) SG(Security Group) 설정

목적: 부하 분산 장치 생성을 위한 로드 밸런서 설정

해당 그룹에서는 HTTP(80), HTTP(443) 트래픽을 허용한다.

2.Tomcat(WAS) Security Group 설정

해당 톰캣 포트는 8080이고 ELB에서 들어오는 트래픽만 받아줄거기에 앞서 설정한 ELB SG을 설정한다.
ALB에서 보낸 트래픽이 8080을 통해 흘러 들어온다.

3. Backend Service Security Group 설정

해당 백엔드는 Memcache, RabbitMQ, MySQL 총 3개의 서비스가 포함된다.

어플리케이션 보안그룹에 속한 Tomcat은 해당 포트를 통해 백엔드와 통신 가능

단, 백엔드 서버는 서로간에 통신이 가능해야 하므로 인바운드 그룹에 backend SG을 추가한다.

4. SSH 포트 설정

[ App Server]

해당 서버마다 운영자가 접근할 수 있도록 22번 포트를 각각 모두 열여준다.
또한 외부에서 퍼블릭ip + 8080포트로 접근할 수 있도록 8080포트에 내 ip를 허용한다.

p.s: 공용ip가 변경되면 해당 인바운드 규칙도 변경해줘야함.

[ Backend Server]

5. 아웃바운드 설정

각각의 서버에서 트래픽을 허용하는 인바운드 규칙을 해주는 것은 허용 측면에서 설정이고 해당 서버에 필요한 리소스를 얻기 위해서 인터넷에 접근하기 위해서는 아웃바운드를 설정해줘야한다. (EX: apt-get...)

[backend server]

[App server]


EC2 생성

데이터베이스 서버부터 생성해보자

DB 인스턴스 생성

네트워크 설정부분에서 보안그룹은 기존에 생성한 bakcend SG로 설정한다.

사용자 데이터 입력

EC2가 실행되고 해당 스크립트가 자동 실행된다.

#!/bin/bash
DATABASE_PASS='admin123'
sudo yum update -y
sudo yum install epel-release -y
sudo yum install git zip unzip -y
sudo yum install mariadb-server -y


# starting & enabling mariadb-server
sudo systemctl start mariadb
sudo systemctl enable mariadb
cd /tmp/
git clone -b main https://github.com/hkhcoder/vprofile-project.git
#restore the dump file for the application
sudo mysqladmin -u root password "$DATABASE_PASS"
sudo mysql -u root -p"$DATABASE_PASS" -e "UPDATE mysql.user SET Password=PASSWORD('$DATABASE_PASS') WHERE User='root'"
sudo mysql -u root -p"$DATABASE_PASS" -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1')"
sudo mysql -u root -p"$DATABASE_PASS" -e "DELETE FROM mysql.user WHERE User=''"
sudo mysql -u root -p"$DATABASE_PASS" -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%'"
sudo mysql -u root -p"$DATABASE_PASS" -e "FLUSH PRIVILEGES"
sudo mysql -u root -p"$DATABASE_PASS" -e "create database accounts"
sudo mysql -u root -p"$DATABASE_PASS" -e "grant all privileges on accounts.* TO 'admin'@'localhost' identified by 'admin123'"
sudo mysql -u root -p"$DATABASE_PASS" -e "grant all privileges on accounts.* TO 'admin'@'%' identified by 'admin123'"
sudo mysql -u root -p"$DATABASE_PASS" accounts < /tmp/vprofile-project/src/main/resources/db_backup.sql
sudo mysql -u root -p"$DATABASE_PASS" -e "FLUSH PRIVILEGES"

# Restart mariadb-server
sudo systemctl restart mariadb


#starting the firewall and allowing the mariadb to access from port no. 3306
sudo systemctl start firewalld
sudo systemctl enable firewalld
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=public --add-port=3306/tcp --permanent
sudo firewall-cmd --reload
sudo systemctl restart mariadb

Memcache 인스턴스 생성

그 외의 과정은 위에서 설정한 DB 인스턴스 생성 과정과 모두 일치.

사용자 데이터 입력

#!/bin/bash
sudo dnf install epel-release -y
sudo dnf install memcached -y
sudo systemctl start memcached
sudo systemctl enable memcached
sudo systemctl status memcached
sed -i 's/127.0.0.1/0.0.0.0/g' /etc/sysconfig/memcached
sudo systemctl restart memcached
firewall-cmd --add-port=11211/tcp
firewall-cmd --runtime-to-permanent
firewall-cmd --add-port=11111/udp
firewall-cmd --runtime-to-permanent
sudo memcached -p 11211 -U 11111 -u memcached -d

참고로 사용자 데이터 입력 시 #!/bin/bash가 첫 문단에 기입이 되도록 해야한다.


RabbitMQ 인스턴스 생성

이하 동일

App 인스턴스 생성


연결 확인

DB 연결확인

연결을 시도하려면 ssh 연결 시 아래처럼 ec2-user로 나오는데 centos로 AMI를 설정했기에 username을 'centos'로 변경 후 시도해야 한다!

그러면 다음과 같이 shell script로 설정한 mariadb가 실행된 걸 확인 가능하다.

추가적으로 인터넷에 접근하기 위해 아웃바운드 설정을 위해서 해주었으니 아래처럼 curl로 요청을 외부에 보냈을 떄 응답을 받을 수 있다 (200)

데이터베이스 접속

Memcahced 연결확인

서버 접속 후 상태 확인하기

상태 확인 또 다른 명령어 (ps -ef | grep)

네트워크 관점에서 해당 포트 상태 확인 ( ss -tnulp | grep {해당포트번호}

  • 0.0.0.0 은 외부 트래픽 모두를 허용한다는 것

App Sever (Tomcat) 연결 확인

tomcat service 실행 상태 확인

DNS 설정 -Route53 이용

도메인 이름과 유형을 선택한다

  • 유형 선택 시 프라이빗을 선택하는데, 인터넷 연결이 아닌 공통 리젼 내 해당 VPC 내에서 인스턴스 간 통신을 지원하기에 프라이빗으로 설정한다.

생성 완료

레코드 생성

  • 해당 레코드를 생성하는 이유는 요청 트래픽이 "내부적으로"(private) 적절한 곳 (DB, Memcached, RabbitMQ 서버로 안착하길 원해서이다.

  • 따라서 db01으로 향해야 하기에 해당 레코드 이름을 설정하고 db01의 프라이빗ip를 기재한다.

Memcached, RabbitMQ 서버에도 동일하게 레코드 생성


S3 버킷 접근 IAM 권한 부여하기

소스코드 파일을 S3에 보관하기 위해 해당 서비스를 이용하기 위한 권한을 부여해주자.

cli를 활용한 버킷 생성

aws s3 mb s3://{bucket name} 
참고로 버킷 네임은 유일한 이름이어한다.

WAR파일 버킷에 밀어넣기

위에서 생성한 버킷에 내 소스코드 파일을 넣어주자.

aws s3 cp vprofile-v2.war s3://jincheol-vprofile-bucket/

IAM 역할 생성

이제 위에서 생성한 app01 서버에 접속해 s3버킷에 넣는 소스코드를 다운로드 받아야 하는데 위에서 s3버킷 생성 및 소스코드를 집어넣어준 권한을 받아야한다.

유저 자체를 생성해주는 것보다 우리는 역할을 부여해 해당 행위를 할 수 있는 자격을 부여해보도록 하자.ㄴ

Ec2로 돌아가 생성한 역할을 부여해주도록 하자.

즉, 우리는 AccessKey로 접근하는 방식 대신 인스턴스에 '역할'을 부여해줌으로써 권한 설정을 준 것이다.

WAR 파일 가져오기 (within S3 bucekt)

1. aws-cli 설치

apt install awscli -y

2. aws s3 버킷 리스트 확인

3. vprofile-v2.war 파일 tmp폴더에 복사

 aws s3 cp s3://jincheol-vprofile-bucket/vprofile-v2.war /tmp/

유효성 검사

root@ip-10-0-9-180:~# systemctl stop tomcat9

rm -rf /var/lib/tomcat9/webapps/ROOT

cp /tmp/vprofile-v2.war /var/lib/tomcat9/webapps/ROOT.war

systemctl start tomcat9

ls /var/lib/tomcat9/webapps/

레코드 설정 ( in application.properties)

#JDBC Configutation for Database Connection
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://db01.vprofile.in:3306/accounts?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
jdbc.username=admin
jdbc.password=admin123

#Memcached Configuration For Active and StandBy Host
#For Active Host
memcached.active.host=mc01.vprofile.in
memcached.active.port=11211
#For StandBy Host
memcached.standBy.host=127.0.0.2
memcached.standBy.port=11211

#RabbitMq Configuration
rabbitmq.address=rmq01.vprofile.in
rabbitmq.port=5672
rabbitmq.username=test
rabbitmq.password=test

#Elasticesearch Configuration
elasticsearch.host =192.168.1.85
elasticsearch.port =9300
elasticsearch.cluster=vprofile
elasticsearch.node=vprofilenode

위에서 ROUTE53을 활용해 생성한 레코드 주소를 해당 property 파일에 동일하게 입력한다.

Load Balancer 설정

대상그룹 생성

대상그룹은 요청 트래픽을 경유하는 인스턴스 그룹이다.
로드밸런서가 해당 대상(목표)그룹으로 트래픽을 분산한다.

해당 로드밸런서는 톰캣 서버로 트래픽을 분산시켜 주고 톰캣 서버의 창구는 8080포트이기에 해당 포트번호를 8080으로 맞춰준다!


http의 기본 포트는 80번이며 우리는 80번 포트가 아닌 8080포트로의 트래픽을 허용하기에 (http프토콜을 사용하지만 문 번호가 다름) 해당 사용중인 문 번호로 override 한다.

로드밸런서 생성

위에서 생성한 타겟 그룹으로 트래픽을 실제로 분산시켜 줄 로드밸런서를 생성하자!

  • 참고로 ELB 보안그룹은 80,443 트래픽에 대한 보안 그룹이다.

443 로드밸런서는 인증서나 도메인을 구입하지 않았다면, 제거해야 한다.

접속 시도

  • 참고로 나같은 경우에 최초 시도에는 접속이 되지 않았는데 2가지 측면을 고려봐야 한다.
  1. 대상그룹 내 연결된 포트 정보
  2. 해당 인스턴스 내 보안그룹 규칙(인바운드)

나같은 경우엔 app 서버로 허용되는 인바운드 규칙 중 8080포트로 들어오는 트래픽에 대해서 내 ip만 허용해주었는데, 해당 ip를 허용해줄 때 집에서 설정해주고 실제 접속은 외부 카페에서 시도해서 한 번 실패를 해주었기에 카페 Ip로 다시 인바운드 규칙을 수정해주었다.

결과


AutoScailing 설정

준비물

1. AMI
2. 시작 템플릿
3. AutoScailing Group

AMI 생성하기

  • 스케일링, 스케일 아웃할 인스턴스 이미지를 생성한다.

시작 템플릿 생성하기

시작템플릿의 역할은 오토 스케일링 시, 시작할 인스턴스 이미지 및 보안그룹 등에 대한 일종의 시작점을 제공한다.

톰캣 인스턴스를 증감/증대 시키기에 보안그룹은 해당 보안그룹과 동일하게 맞춘다.

해당 인스턴스 생성 시, 기존 부모 인스턴스에게 부여된 역할을 동일하게 부여한다.

ASG(AutoScailing Group) 생성

ASG가 동작되면 생성된 인스턴스를 아래 대상그룹에 포함시켜 로드밸런싱 그룹에 포함되도록 한다.


오토 스케일링 그룹을 생성하였다면, 아래처럼 인스턴스가 새로 생성된 걸 확인할 수 있다.

또한 대상그룹에도 포함된 걸 확인 할 수 있다.

sticky session 설정

Sticky Session 이란 ?

Application Load Balancer (ALB)에서의 Sticky Session은 클라이언트가 특정 인스턴스에 대한 연결을 계속 유지하도록 하는 기능입니다. 일반적으로 로드 밸런서는 요청이 들어올 때마다 서버 또는 인스턴스 간에 부하를 분산하는 역할을 합니다. 그러나 Sticky Session이 활성화되면 로드 밸런서는 특정 클라이언트의 모든 요청을 동일한 서버 또는 인스턴스로 보냅니다.

이 기능은 세션 기반의 어플리케이션에서 유용하게 사용됩니다. 일반적으로 클라이언트와 서버 간의 세션 정보가 유지되어야 하는 경우, 예를 들어 사용자 로그인 정보나 장바구니 정보 등이 있는 경우가 그 예입니다. 이때 하나의 인스턴스에 대한 클라이언트의 모든 요청이 동일한 서버로 전송되면, 세션 정보가 그대로 유지되면서 일관된 경험을 제공할 수 있습니다.

Sticky Session은 다양한 방법으로 구현될 수 있습니다. 일반적으로는 클라이언트의 세션 쿠키에 의존하거나, 클라이언트의 IP 주소에 의존하여 특정 서버로 유지되도록 설정할 수 있습니다. Sticky Session을 사용하면 세션 정보를 서버 간에 공유하지 않고도 특정 클라이언트에 대한 지속적인 연결을 유지할 수 있습니다.

하지만 Sticky Session을 사용할 때 주의해야 할 점도 있습니다. 특히 로드 밸런서와 백엔드 서버 간의 부하 분산이 저하될 수 있으며, 특정 서버에 장애가 발생할 경우 해당 서버에 연결된 클라이언트는 영향을 받을 수 있습니다. 따라서 Sticky Session을 사용하는 경우 이러한 측면을 고려하여 설계해야 합니다.


정리

  1. 유저가 특정 Url로 접속

  2. ALB(Application Load Balancer)에 접촉

  3. ALB는 포트8080을 가진 톰캣 서버 인스턴스에 요청을 전달한다.
    -> 톰캣 서버는 다른 보안그룹에 존재 (Security Group)

  4. 톰캣 서버는 해당 요청을 백엔드 서버로 보낸다
    -> 이때 Route53으로 개인(private) DNS 서버를 설정해 백엔드와의 통신이 가능하게 한다. (db01,rmq01,mc01)
    -> 백엔드 서버는 같은 보안그룹을 유지한다.
    -> 각각의 포트번호를 열어주고 서로간에 통신이 필요하기에 해당 보안그룹 역시 등록한다.

  5. S3에 업로드한 소스파일을 변경 될 때 마다 톰캣 서버에 업로드 할 수 있다. (이때 CI/CD를 적용하는 것이 효율적)

profile
WILL is ALL

0개의 댓글

관련 채용 정보