학교 동아리(Devkor)로부터 AWS IAM 계정을 받았다.
해당 계정을 통해 현재 이용 가능한 것은 EC2, RDS, S3이다.
현재 내 계정으로 돌아가고 있는 EC2와 RDS를 옮기고 CI/CD를 구축하고자 한다.
1. 환경변수 수정
일단 application.yml의 환경변수를 수정해준다.
DB 정보 관련
인텔리제이에 RDS의 정보를 입력하여 연결해준다.
할당 받은 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키가 있는 곳으로 이동해준다.
공개키를 생성하기 위해 다음 명령어를 입력한다.
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로 설정하여 가상 메모리를 얻어준다.
아래 명령어를 순서대로 입력한다.
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/
다음 명령어를 순서대로 입력한다.
# 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
다음을 순서대로 입력한다.
# 시스템 패키지 업데이트
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 |