본문 바로가기
Devkor

AWS IAM 계정으로 배포하기 (1)

by 진진리 2024. 6. 27.
728x90

학교 동아리(Devkor)로부터 AWS IAM 계정을 받았다.

해당 계정을 통해 현재 이용 가능한 것은 EC2, RDS, S3이다.

현재 내 계정으로 돌아가고 있는 EC2와 RDS를 옮기고 CI/CD를 구축하고자 한다.

 

1. 환경변수 수정

일단 application.yml의 환경변수를 수정해준다.

 

DB 정보 관련

인텔리제이에 RDS의 정보를 입력하여 연결해준다.

Database를 입력하면 connect 실패가 뜬다.

 

할당 받은 RDS에 database가 없어서 만들어준다.

연결한 RDS의 콘솔창을 연 후 다음과 같이 입력하여 실행한다.

create database kodaero;

 

위 인텔리제이 창에 있는 URL에 /kodaero를 추가해서 application.yml의 DB_URL에 저장해준다.

username과 password도 수정한다.

 

그 외 기존 나의 ec2 ip주소를 할당받은 ec2의 ip주소로 변경해준다.

S3 정보는 이후에 추가해줄 예정이다.

 

2. EC2 ssh 연결

할당받은 ec2의 경우 연결된 키 페어가 없어 ssh 클라이언트 연결이 불가능했다.


EC2 콘솔 왼쪽에 있는 '네트워크 및 보안 > 키 페어'로 이동

'키 페어 생성' 클릭 후 이름을 입력하고 RSA, .pem 선택 후 생성해준다.

저장된 pem 키는 잘 보관해준다.

 

cmd 창을 열어 해당 pem키가 있는 곳으로 이동해준다.

(참고: https://velog.io/@zero-black/AWS-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4%EC%97%90-%EC%B6%94%EA%B0%80%EB%A1%9C-%ED%82%A4-%EC%83%9D%EC%84%B1%ED%95%98%EB%8A%94-%EB%B2%95)

공개키를 생성하기 위해 다음 명령어를 입력한다.

ssh-keygen -f 발급받은_키페어_이름

 

생성된 공개키를 열어 문자열을 그대로 복사해준다.

 

다시 EC2로 돌아와서 EC2 인스턴스 연결로 접속해준다.

sudo vi .ssh/authorized_keys

 

위와 같이 입력 한 후 공개키를 붙여 넣는다.

 

EC2의 '연결 > SSH 클라이언트'로 이동 했을 때의 아래에 있는 명령어를 복사한 후

 

다음과 같이 수정해준 후 로컬 cmd 창에서 pem키가 있는 곳으로 이동 후 입력하면 ec2로 ssh 원격 접속이 가능하다.

ssh -i 발급받은_pem_키 ubuntu@ec2-13-209-186-62.ap-northeast-2.compute.amazonaws.com

 

 

3. EC2 기본 세팅

Swap area 설정

EC2의 디스크 공간의 일부를 swap area로 설정하여 가상 메모리를 얻어준다.

(참고: https://velog.io/@seyoung755/AWS-EC2%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%B4-%EB%B0%B0%ED%8F%AC%ED%95%B4%EB%B3%B4%EC%9E%90-6-Swap-area-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0)

 

AWS EC2를 이용해 배포해보자 (6) - Swap area 설정하기

우리의 프로젝트를 성공적으로 배포했지만, 프리티어의 메모리 1기가로는 벅찬 느낌이 있습니다. 부족한 메모리를 커버해보기 위해 가상 메모리 기법을 떠올려봅니다. 우리의 하드 디스크 일부

velog.io

 

아래 명령어를 순서대로 입력한다.

sudo dd if=/dev/zero of=/swapfile bs=128M count=16

sudo chmod 600 /swapfile

sudo mkswap /swapfile

sudo swapon /swapfile

sudo swapon -s

sudo vi /etc/fstab
# 파일의 끝에 /swapfile swap swap defaults 0 0 을 추가하고 저장합니다.

 

서버 시간 설정

sudo timedatectl set-timezone Asia/Seoul

date # 변경 확인

 

Docker 설치

참고: https://docs.docker.com/engine/install/ubuntu/

 

Install Docker Engine on Ubuntu

Jumpstart your client-side server applications with Docker Engine on Ubuntu. This guide details prerequisites and multiple methods to install Docker Engine on Ubuntu.

docs.docker.com

 

다음 명령어를 순서대로 입력한다.

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# docker.sock 권한 부여 및 로그인
sudo chmod 666 /var/run/docker.sock

sudo docker login

# docker version 확인
sudo docker -v

 

 

Docker compose 설치

참고: https://wiki.crowncloud.net/?How_to_Install_and_use_Docker_Compose_on_Ubuntu_24_04

 

How To Install And Use Docker Compose On Ubuntu 24 04=

 

wiki.crowncloud.net

 

다음을 순서대로 입력한다.

# 시스템 패키지 업데이트
sudo apt update -y
sudo apt upgrade -y

# Docker 설치(생략)

# Docker Compose 설치
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose

# 버전 확인
docker-compose -v

 

 

Nginx 설치

관련 명령어

sudo apt install nginx # 설치

sudo service nginx start # 시작

sudo service nginx status # 상태 확인

sudo service nginx restart # 재가동

 

 

4. Docker를 이용한 배포

CI/CD 구축 전 Dockerhub에 올려져 있는 docker image를 이용해 블루-그린 배포를 우선 시도해본다.

 

우선, 프로젝트에서 Redis를 사용하기 때문에 Redis 컨테이너를 띄운다.

docker run -v /path/on/host:/data -d --name my-redis -p 6379:6379 redis redis-server --appendonly yes --requirepass [password]

 

Redis 컨테이너에 접속하고자 하는 경우

sudo docker exec -it my-redis redis-cli # my-redis는 앞에서 입력한 이름
# 비밀번호 입력 요청
auth [password]

 

docker-compose.yml을 생성한다.

version: '3'
services:
  green:
    container_name: green
    image: leeyejin113035/kodaero # docker hub의 image 이름
    ports:
      - "8080:8080"  # green은 8080 포트를 열어줍니다.
    environment:
      - 환경변수_key값=환경변수_value값

  blue:
    container_name: blue
    image: leeyejin113035/kodaero # docker hub의 image 이름
    ports:
      - "8081:8080"  #blue는 8081 포트를 열어줍니다.
    environment:
      - 환경변수_key값=환경변수_value값

 

배포 시 실행할 deploy.sh를 생성한다.

IS_GREEN=$(docker ps | grep green) # 현재 실행중인 App이 blue인지 확 인합니다.
DEFAULT_CONF=" /etc/nginx/nginx.conf"

if [ -z $IS_GREEN  ];then # blue라면

  echo "### BLUE => GREEN ###"

  echo "1. get green image"
  docker compose pull green # green으로 이미지를 내려받습니다.

  echo "2. green container up"
  docker compose up -d green # green 컨테이너 실행

  while [ 1 = 1 ]; do
  echo "3. green health check..."
  sleep 3

  REQUEST=$(curl http://localhost:8080/api/search/buildings) # green으로 request
    if [ -n "$REQUEST" ]; then # 서비스 가능하면 health check 중지
            echo "health check success"
            break ;
    fi
  done;

  echo "4. reload nginx"
  sudo cp /etc/nginx/nginx.green.conf /etc/nginx/nginx.conf
  sudo nginx -s reload

  echo "5. blue container down"
  docker compose stop blue
else
  echo "### GREEN => BLUE ###"

  echo "1. get blue image"
  docker compose pull blue

  echo "2. blue container up"
  docker compose up -d blue

  while [ 1 = 1 ]; do
    echo "3. blue health check..."
    sleep 3
    REQUEST=$(curl http://localhost:8081/api/search/buildings) # blue 로 request

    if [ -n "$REQUEST" ]; then # 서비스 가능하면 health check 중지
      echo "health check success"
      break ;
    fi
  done;

  echo "4. reload nginx"
  sudo cp /etc/nginx/nginx.blue.conf /etc/nginx/nginx.conf
  sudo nginx -s reload

  echo "5. green container down"
  docker compose stop green
fi

 

green 컨테이너가 실행 중이라면 blue를, 아니면 green을 실행하는데, docker-compose.yml에 따라 이미지를 pull 받는다.

해당 컨테이너를 실행한 후에 잘 작동하는지 health check를 하는데 이때 jwt 토큰이 필요하지 않은 api/search/buildings를 호출하도록 설정하였다.

health check가 이루어진 후에는 nginx.conf 파일을 새로 실행하는 컨테이너에 맞는 conf 파일로 뒤집어쓴 후 기존 실행중이던 컨테이너를 down시킨다.

 

ec2에 처음 접속하면 기본 위치는 /home/ubuntu이고 nginx.conf 파일을 만들기 위해 /etc/nginx로 이동해준다.

nginx.green.conf와 nginx.blue.conf를 생성한다.

# nginx.green.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

    events {
        worker_connections  1024;
        }

        http {

        include       mime.types;

        server {

        server_name 13.209.186.62; # 도메인 이름

        location / {

        # GREEN - 8080 포트로 연결합니다.
        # BLUE 설정파일은 이부분의 포트만 8081로 변경해주면 됩니다.
        proxy_pass http://localhost:8080;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real_IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        }
        
        }

        # 80 포트로 접근시 443 포트로 리다이렉트 시켜주는 설정
        server {

        return 301 https://$host$request_uri;

        listen 80;
        server_name 13.209.186.62; # 도메인 이름
        return 404; # managed by Certbot
        }

}

 

green은 80포트로 접근 시 8080포트로, blue는 8081 포트로 리다이렉트 시켜준다.

 

이후 https 인증서를 발급 받은 후에는 443포트로 접근 시 8080, 8081 포트로 리다이렉트 시켜준다.

그리고 다음과 같이 conf 파일을 수정해준다.

# nginx.green.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

    events {
        worker_connections  1024;
        }

        http {

        include       mime.types;

        # 443 포트로 접근시 ssl을 적용한 뒤 3000포트로 요청을 전달해 주도록 하는 설 정.
        server {

        server_name {ip_주소}; # 도메인 이름

        location / {

        # GREEN - 8080 포트로 연결합니다.
        # BLUE 설정파일은 이부분의 포트만 8081로 변경해주면 됩니다.
        proxy_pass http://localhost:8080;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real_IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        }

        listen 443 ssl; # managed by Certbot

        ssl_certificate /etc/letsencrypt/live/{ip_주소}/fullchain.pem; # managed by Cert>
        ssl_certificate_key /etc/letsencrypt/live/{ip_주소}/privkey.pem; # managed by Ce>
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
        }

        # 80 포트로 접근시 443 포트로 리다이렉트 시켜주는 설정
        server {

        return 301 https://$host$request_uri;

        listen 80;
        server_name {ip_주소}; # 또는 도메인 이름
        return 404; # managed by Certbot
        }

}

 

 

마지막으로 deploy.sh을 실행해준다.

health check에는 시간이 조금 걸린다.

만약 무한대로 실행된다면 ctrl+c로 중단 후 docker logs 컨테이너ID로 로그를 확인하여 문제를 확인한다.

 

ip주소로 접속해보면 다음과 같이 배포된 것을 확인할 수 있다.

'Devkor' 카테고리의 다른 글

[고대로] static 변수와 영속성 컨텍스트  (0) 2024.08.17
[고대로] 운영 시간 관리  (0) 2024.08.17