AWS VPC, Aurora RDS, EC2, EFS 및 ElastiCache를 구성하여 고가용성 웹 애플리케이션 구축

AWS VPC, Amazon Aurora RDS, Amazon EC2, Amazon EFS 및 Amazon ElastiCache를 구성하여 고가용성 웹 애플리케이션을 구축해보았습니다.
2021.08.03

안녕하세요 클래스메소드 김재욱(Kim Jaewook)이라고 합니다. 이번에는 AWS VPC, Amazon Aurora RDS, Amazon EC2, Amazon EFS 및 Amazon ElastiCache를 구성하여 고가용성 웹 애플리케이션을 구축해보았습니다.

VPC 생성

위 그림과 같이 CIDR 범위를 입력하고 VPC를 생성합니다.

프라이빗 및 퍼블릭 서브넷 생성

VPC를 생성한 다음, 두 개의 서로 다른 가용 영역에서 애플리케이션을 호스팅하는 데 사용할 서브넷을 생성합니다.

서브넷은 총 6개의 서브넷을 생성합니다.

인터넷 게이트웨이 생성 및 라우팅 설정

이어서 인터넷 게이트웨이를 통해 퍼블릭 서브넷과 인터넷의 연결을 해주고, NAT 게이트웨이를 통해 프라이빗 서브넷에서 인터넷으로의 연결을 허용합니다.

먼저 인터넷 게이트웨이를 생성합니다.

생성한 인터넷 게이트웨이를 클릭하고 작업 태그에서「VPC에 연결」을 클릭하여, 좀 전에 만들어둔「my-vpc」에 연결합니다.

그리고 라우팅 테이블을 하나 생성합니다.

라우팅 편집을 클릭해서, 이전에 만들어 둔 인터넷 게이트웨이를 통해 기본 경로를 추가합니다.

이어서, 서브넷 연결 탭에서 Public Subnet A와 Public Subnet B를 연결합니다.

퍼블릭 서브넷 전체에 NAT 게이트웨이 생성

계정의 VPC 대시보드로 이동하여 NAT 게이트웨이를 선택 하고 두 개의 퍼블릭 서브넷(즉, Public Subnet A 및 Public Subnet B) 각각에 하나의 게이트웨이를 생성합니다.

이제 두 개의 Application Subnet 각각에 대한 라우팅 테이블을 생성하고 이전에 생성한 NAT 게이트웨이를 기본 게이트웨이로 사용해야 합니다.

그리고 생성한 NAT 게이트웨이를 연결합니다.

이어서, 서브넷 연결 편집에서 Application Subnet A를 연결합니다. Application Subnet B 또 한, 마찬가지로 라우팅 테이블을 만들어서 위와 같이 구성합니다.

고가용성 데이터 계층 구축

이번에는 고가용성 데이터 계층을 구축 하도록 하겠습니다.

RDS 데이터베이스 설정

먼저 2개의 보안 그룹을 생성합니다. 첫 번째 보안 그룹의 이름은 WP Database Client SG 와 같이 지정해야 하고 두 번째 보안 그룹의 이름은 WP Database SG로 설정합니다.

이어서 WP Database SG에서 WP Database Client SG 보안 그룹을 허용하도록 설정합니다.

RDS 서브넷 그룹 생성

Amazon RDS를 사용하여 데이터베이스를 고가용성 방식으로 배포하면 2개의 서로 다른 가용 영역에 2개의 인스턴스가 생성됩니다. 이렇게 하려면 데이터베이스 배포를 생성할 때 데이터베이스 인스턴스를 배포할 수 있는 서브넷을 RDS에 알려주는 서브넷 그룹을 지정합니다.

RDS-서브넷 그룹으로 들어가서 서브넷 그룹 생성 버튼을 눌러 위 이미지와 동일하게 작성합니다. 가용 영역의 경우, VPC를 생성할 때 만들어 두었던 서브넷입니다.

서브넷의 경우, Data Subnet A와 Data Subnet B를 선택하고 생성 버튼을 눌러줍니다.

서브넷 그룹 생성이 끝났다면, 데이터베이스를 생성합니다. Amazon Aurora를 선택합니다.

마스터 사용자 이름과 마스터 암호를 설정합니다. 이후 나중에 WordPress의 DB 연결을 설정할 때 필요합니다.

가용성 및 내구성은「다른 AZ에 Aurora 복제본/리더 노드 생성(확장된 가용성에 권장)」을 선택합니다.

VPC는 my-vpc를 선택하고, 서브넷 그룹은 좀전에 만들어두었던 서브넷 그룹을 선택합니다. 보안 그룹 또 한, 이전에 만들어두었던 WP Database SG를 선택합니다. 마지막으로 추가 구성에서 초기 데이터베이스 이름을 wordpress로 입력하고 데이터베이스 생성 버튼을 클릭합니다.

ElastiCache Memcached 설정

Memcached는 일반적인 데이터베이스 쿼리를 캐싱하여 데이터베이스 로드를 줄이는 서버 측 캐싱 메커니즘으로 WordPress 웹사이트의 로딩 속도를 높입니다.

먼저 2개의 보안 그룹을 생성합니다. 첫 번째 보안 그룹의 이름은 WP Cache Client SG, 두 번째 보안 그룹의 이름은 WP Cache SG입니다.

보안 그룹 생성이 끝났다면, WP Cache SG에서 WP Cache Client SG를 허용하는 인바운드 규칙을 생성합니다.

ElastiCache Memcached 인스턴스 생성

ElastiCache로 들어가서 생성 버튼을 눌러줍니다. 클러스터 엔진은 Memcached로 선택하고, 위치는 Amazon 클라우드를 선택합니다.

Memcached 설정에서는 이름만 적어주고, 나머지는 디폴트 값으로 설정합니다.

고급 Memcached 설정에서는 이름을 적고, 서브넷을 선택합니다.

파일 시스템 보안 그룹 생성

웹 애플리케이션 서버에 공유 파일 시스템을 제공할 EFS 클러스터를 생성합니다. 먼저, 2개의 보안 그룹을 생성합니다. 첫 번째 보안 그룹의 이름은 WP FS Client SG로 지정하고, 두 번째 보안 그룹의 이름은 WP FS SG로 지정합니다.

그리고 WP FS SG에서 WP FS Client SG 트래픽을 허용하는 인바운드 규칙을 설정합니다.

EFS 클러스터 생성

VPC에서 my-vpc를 선택하고 사용자 지정을 클릭 합니다. 파일 시스템 설정의 기본값을 수락하고 다음 을 클릭 합니다.

네트워크 액세스에서는 서브넷을 application subnet A와 B를 선택하고, 보안그룹은 WP FS SG를 선택합니다.

애플리케이션 계층 구축

응용 프로그램 응답 시간을 개선하기 위해 공유 파일 시스템, 중앙 HA 데이터베이스 및 캐싱 계층을 만들었습니다. 이제 애플리케이션 자체를 고가용성 방식으로 배포해 봅시다.

로드 밸런서 및 애플리케이션 보안 그룹 생성

로드 밸런서에 대한 보안 그룹을 생성합니다. 보안 그룹의 이름은 WP Load Balancer SG로 지정합니다.

인바운드 규칙은 다음과 같이 설정합니다.

로드 밸런서 생성

EC2 서비스로 들어가서, 로드 밸런서 탭에서 로드 밸런서 생성 버튼을 클릭합니다. 그리고 HTTP/HTTPS를 선택하고, 가용 영역에서는 my-vpc를 선택한 다음, 서브넷은 Public Subnet A, Public Subnet B를 선택합니다.

이후, 보안 그룹은 좀 전에 선택했던 보안그룹을 선택해주고, 대상 그룹 지정은 이름만 설정한 다음 디폴트값으로 로드 밸런서를 생성합니다.

시작 구성 만들기

네트워크를 생성하고 HA 활성/수동 MySQL 데이터베이스, 관리형 Memcached 인스턴스 및 공유 스토리지용 분산 NFS 클러스터를 배포했습니다. 이제 PHP를 실행하는 HA 응용 프로그램 서버를 배포하여 이러한 리소스를 확장 가능한 WordPress 설치의 일부로 사용합니다.

WordPress 서버용 보안 그룹 생성

WordPress 서버에 대한 보안 그룹을 만듭니다. 보안 그룹의 이름은 WP WordPress SG와 같이 지정합니다.

WP WordPress SG에서 WP Load Balancer SG의 포트 80의 HTTP 트래픽만 허용 하도록 인바운드 규칙을 설정합니다.

Auto Scaling 그룹(ASG)에 대한 시작 구성 생성

시작 구성은 Auto Scaling Group이 EC2 인스턴스를 시작하는 데 사용하는 인스턴스 구성 템플릿입니다. 시작 구성을 생성할 때 Amazon 머신 이미지(AMI)의 ID, 인스턴스 유형, 키 페어, 하나 이상의 보안 그룹 및 블록 디바이스 매핑을 포함하여 인스턴스에 대한 구성 정보를 지정해야 합니다.

오토 스케일링 시작구성에 들어가서 시작 구성 생성 버튼을 클릭합니다. 시작 구성 이름은 WordPress로 설정합니다. AMI와 인스턴스 유형은 위와 같이 구성합니다. 리전 별로 Amazon Linux AMI ID가 다를 수 있습니다.

이 후, 고급 세부 정보에서 다음 코드를 입력합니다.

#!/bin/bash -xe

EFS_MOUNT="<YOUR-EFS-HOSTNAME>"

DB_NAME="wordpress"
DB_HOSTNAME="<YOUR-DB-HOSTNAME>"
DB_USERNAME="<YOUR-DB-USERNAME>"
DB_PASSWORD="<YOUR-DB-PASSWORD>"

WP_ADMIN="wpadmin"
WP_PASSWORD="WpPassword$"

LB_HOSTNAME="<YOUR-ALB-HOSTNAME>"

yum update -y
yum install -y awslogs httpd24 mysql56 php55 php55-devel php55-pear php55-mysqlnd gcc-c++ php55-opcache

mkdir -p /var/www/wordpress
mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 $EFS_MOUNT:/ /var/www/wordpress

## create site config
cat <<EOF >/etc/httpd/conf.d/wordpress.conf
ServerName 127.0.0.1:80
DocumentRoot /var/www/wordpress/wordpress
<Directory /var/www/wordpress/wordpress>
  Options Indexes FollowSymLinks
  AllowOverride All
  Require all granted
</Directory>
EOF

## install cache client
pecl install igbinary-2.0.8
wget -P /tmp/ https://s3.amazonaws.com/aws-refarch/wordpress/latest/bits/AmazonElastiCacheClusterClient-1.0.1-PHP55-64bit.tgz
tar -xf '/tmp/AmazonElastiCacheClusterClient-1.0.1-PHP55-64bit.tgz'
cp 'AmazonElastiCacheClusterClient-1.0.0/amazon-elasticache-cluster-client.so' /usr/lib64/php/5.5/modules/
if [ ! -f /etc/php-5.5.d/50-memcached.ini ]; then
    touch /etc/php-5.5.d/50-memcached.ini
fi
echo 'extension=igbinary.so;' >> /etc/php-5.5.d/50-memcached.ini
echo 'extension=/usr/lib64/php/5.5/modules/amazon-elasticache-cluster-client.so;' >> /etc/php-5.5.d/50-memcached.ini

## install wordpress
if [ ! -f /bin/wp/wp-cli.phar ]; then
   curl -o /bin/wp https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
   chmod +x /bin/wp
fi
# make site directory
if [ ! -d /var/www/wordpress/wordpress ]; then
   mkdir -p /var/www/wordpress/wordpress
   cd /var/www/wordpress/wordpress
   # install wordpress if not installed
   # use public alb host name if wp domain name was empty
   if ! $(wp core is-installed --allow-root); then
       wp core download --version='4.9' --locale='en_GB' --allow-root
       wp core config --dbname="$DB_NAME" --dbuser="$DB_USERNAME" --dbpass="$DB_PASSWORD" --dbhost="$DB_HOSTNAME" --dbprefix=wp_ --allow-root
       wp core install --url="http://$LB_HOSTNAME" --title='Wordpress on AWS' --admin_user="$WP_ADMIN" --admin_password="$WP_PASSWORD" --admin_email='admin@example.com' --allow-root
       wp plugin install w3-total-cache --allow-root
       # sed -i \"/$table_prefix = 'wp_';/ a \\define('WP_HOME', 'http://' . \\$_SERVER['HTTP_HOST']); \" /var/www/wordpress/wordpress/wp-config.php
       # sed -i \"/$table_prefix = 'wp_';/ a \\define('WP_SITEURL', 'http://' . \\$_SERVER['HTTP_HOST']); \" /var/www/wordpress/wordpress/wp-config.php
       # enable HTTPS in wp-config.php if ACM Public SSL Certificate parameter was not empty
       # sed -i \"/$table_prefix = 'wp_';/ a \\# No ACM Public SSL Certificate \" /var/www/wordpress/wordpress/wp-config.php
       # set permissions of wordpress site directories
       chown -R apache:apache /var/www/wordpress/wordpress
       chmod u+wrx /var/www/wordpress/wordpress/wp-content/*
       if [ ! -f /var/www/wordpress/wordpress/opcache-instanceid.php ]; then
         wget -P /var/www/wordpress/wordpress/ https://s3.amazonaws.com/aws-refarch/wordpress/latest/bits/opcache-instanceid.php
       fi
   fi
   RESULT=$?
   if [ $RESULT -eq 0 ]; then
       touch /var/www/wordpress/wordpress/wordpress.initialized
   else
       touch /var/www/wordpress/wordpress/wordpress.failed
   fi
fi

## install opcache
if [ ! -d /var/www/.opcache ]; then
    mkdir -p /var/www/.opcache
fi
# enable opcache in /etc/php-5.5.d/opcache.ini
sed -i 's/;opcache.file_cache=.*/opcache.file_cache=\/var\/www\/.opcache/' /etc/php-5.5.d/opcache.ini
sed -i 's/opcache.memory_consumption=.*/opcache.memory_consumption=512/' /etc/php-5.5.d/opcache.ini
# download opcache-instance.php to verify opcache status
if [ ! -f /var/www/wordpress/wordpress/opcache-instanceid.php ]; then
    wget -P /var/www/wordpress/wordpress/ https://s3.amazonaws.com/aws-refarch/wordpress/latest/bits/opcache-instanceid.php
fi

chkconfig httpd on
service httpd start
  • EFS_MOUNTElastic Filesystem의 DNS 호스트 이름으로 설정해야 합니다. ex)fs-5a59585f.efs.us-west-2.amazonaws.com.
  • DB_NAME데이터베이스의 이름입니다. 기본값을 입력한 경우 이 값은 이어야 합니다 wordpress
  • DB_HOSTNAME데이터베이스 인스턴스의 호스트 이름입니다. RDS 데이터베이스에 대한 세부 정보 페이지에서 확인 합니다. ex)wordpress-db.cluster-cytbfylghhjz.us-west-2.rds.amazonaws.com.
  • DB_USERNAME데이터베이스 마스터 사용자 이름입니다.
  • DB_PASSWORD데이터베이스 마스터 사용자의 비밀번호입니다.
  • LB_HOSTNAME애플리케이션 로드 밸런서의 호스트 이름입니다. ex)wordpress-lb-678399122.us-west-2.elb.amazonaws.com.

보안 그룹은 위 그림과 같이 구성 하고 생성합니다.

백엔드 웹 서버용 ASG 생성

로드 밸런서를 사용하고 이전 2개 실습의 구성을 시작하여 WordPress 애플리케이션 서버의 Auto Scaling 집합을 생성합니다.

시작 구성이 생성되면, 작업에서 Auto Scaling 그룹 생성을 클릭합니다.

이름을 입력하고 네트워크 탭으로 넘어간 다음, VPC와 서브넷을 설정합니다.

기존에 만들었던 로드 밸런서를 선택합니다.

그룹 크기를 설정하고 생성을 합니다.

이제 Auto scaling 그룹은 생성한 시작 구성을 기반으로 원하는 수의 EC2 인스턴스 생성을 시작합니다. 시스템이 On 상태가 되면 대상 그룹이 EC2 인스턴스에 대한 인스턴스 세부 정보로 업데이트 되고 로드 밸런서가 인스턴스 간에 트래픽을 분산하기 시작합니다. 인스턴스가 추가되거나 제거되면 Auto scaling 그룹과 로드 밸런서는 정상 인스턴스만 트래픽을 수신하도록 서로 협력하여 작동합니다.