๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Infra

AWS CodeDeploy, Docker ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ

by joaa 2024. 2. 28.

๐ŸŽˆ ๋ฐฐํฌ ๊ตฌ์กฐ

๊ธฐ๋Šฅ๊ณผ ๊ด€๋ จ๋œ ๋ถ€๊ฐ€์ ์ธ ์™ธ๋ถ€ API ๋“ฑ์€ ์ œ์™ธํ•˜๊ณ  ๋Œ€๋žต์ ์ธ ๊ตฌ์กฐ๋Š” ๋‹ค์Œ ๊ทธ๋ฆผ๊ณผ ๊ฐ™๊ฒŒ ๋œ๋‹ค. 

๋ฐฐํฌ๋Š” Github Actions, Codedeploy๋ฅผ ํ†ตํ•ด์„œ ํ•˜๊ณ , 

์š”์ฒญ์ด ์™”์„ ๋•Œ๋Š” AWS ALB์—์„œ SSL ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ณ , NginX์—์„œ๋Š” blue, green ์ค‘ ์ž‘๋™ ์ค‘์ธ ํฌํŠธ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ๊ฐ€ ๊ตฌํ˜„๋œ๋‹ค. 

๋ฐฐํฌํ•  ๋•Œ + ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๋•Œ

๋ฐฐํฌ ํ๋ฆ„

1. ๊นƒํ—ˆ๋ธŒ ๋””ํดํŠธ ๋ธŒ๋žœ์น˜์— ๋ณ€๊ฒฝ ๋‚ด์šฉ ์ปค๋ฐ‹
2. Github workflow๊ฐ€ java ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œ
3. Codedeploy, S3 ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ  IAM ํ‚ค๋ฅผ ์•Œ๊ณ  ์žˆ๋Š” Github workflow๊ฐ€ S3์— ๋นŒ๋“œ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜๊ณ , Codedeploy๋กœ ๋ฐฐํฌ ์š”์ฒญ
4. Codedeploy๊ฐ€ appspec.yml์— ๋”ฐ๋ผ ์ง€์ •ํ•œ hook ์‹œ์ ์— scripts/deploy.sh ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰
5. deploy.sh๋Š” ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ blue ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์žˆ๋‹ค๋ฉด green ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ณ , ์—†๋‹ค๋ฉด blue ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ -> ๋ฐฐํฌ ์ค‘์—๋„ ์„œ๋น„์Šค๊ฐ€ ์ค‘๋‹จ๋˜์ง€ ์•Š๋„๋ก ํ•จ

 

 

 

 

 

ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๋•Œ


 HTTPS ์š”์ฒญ ์ฒ˜๋ฆฌ ํ๋ฆ„
1. ๋„๋ฉ”์ธ์œผ๋กœ ๋“ค์–ด์˜จ ์š”์ฒญ์€ EC2์˜ ๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ๋กœ ๋ผ์šฐํŒ… ๋จ
2. AWS ALB๋Š” ์š”์ฒญ์ด HTTP๋ผ๋ฉด HTTPS๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜๊ณ , HTTPS๋ผ๋ฉด ๋“ฑ๋ก๋œ ์ธ์ฆ์„œ๋กœ SSL/TLS ์ฒ˜๋ฆฌ
3. AWS ALB๋Š” ๋ชจ๋“  ์š”์ฒญ์„ ๋Œ€์ƒ ๊ทธ๋ฃน์— ๋“ฑ๋ก๋œ EC2์˜ 80ํฌํŠธ๋กœ ๋ณด๋ƒ„
4. NginX์˜ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•ด ๋ธ”๋ฃจ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‚ฌ์šฉ ์ค‘์ธ 8081ํฌํŠธ์™€ ๊ทธ๋ฆฐ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‚ฌ์šฉ ์ค‘์ธ 8082ํฌํŠธ ์ค‘ ์—ฐ๊ฒฐ ๊ฐ€๋Šฅํ•œ ๊ณณ์œผ๋กœ ์—ฐ๊ฒฐํ•จ

 

 

 

 

๐ŸŽˆ SSL offloading์ด๋ž€?

API ์„œ๋ฒ„๊ตฐ ์•ž์— proxy ์„œ๋ฒ„๋ฅผ ๋‘๊ณ  ํ•ด๋‹น Proxy ์„œ๋ฒ„์— SSL ๊ด€๋ จ ์ž‘์—…์„ ์œ„์ž„ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

AWS ALB์—์„œ SSL ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ณ  ์›น ์„œ๋ฒ„์—์„œ๋Š” SSL ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š๋Š” ์œ„ ๊ตฌ์กฐ๋Š” SSL offloading์„ ์ ์šฉํ•˜๊ณ  ์žˆ๋‹ค. 

์ด๋Ÿฌํ•œ ๋ฐฉ์‹์€ WAS๋ฅผ ๋„˜์–ด WS์— SSL ์ฒ˜๋ฆฌ๋กœ ์ธํ•œ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ฃผ์ง€ ์•Š๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ๋œ๋‹ค. 

 

 

 

๋ฌด์ค‘๋‹จ ๋ฐฐํฌ ๊ธฐ๋ก, ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…

nginx

blue-green์€ ์‚ฌ์‹ค ์„œ๋ฒ„ 2๋Œ€ ์ด์ƒ์„ ์‚ฌ์šฉํ•ด์„œ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ๋ฐฐํฌํ•ด์„œ ํด๋ผ์ด์–ธํŠธ ๋‹จ์—์„œ ์ค‘๋‹จ์„ ๋А๋ผ์ง€ ๋ชปํ•˜๊ฒŒ ํ•˜๋Š” ๊ฑฐ๋ผ๊ณ  ํ•˜๋Š”๋ฐ ํ”„๋ฆฌํ‹ฐ์–ด๋กœ EC2 ๋‘ ๊ฐœ ์“ธ ์ˆ˜๋Š” ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋„์ปค์™€ nginx, codedeploy๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

์„œ๋ฒ„์— nginx ๋“ฑ ํ•„์š”ํ•œ ๊ฒƒ๋“ค์„ ์„ค์น˜ํ•œ ํ›„ 

sudo vim /etc/nginx/sites-enabled/default ์„ ํ•ด์„œ proxy์„ค์ •์„ ๋ฐ”๊ฟจ๋‹ค.

upstream blog-api-server {
        least_conn;
        server 127.0.0.1:8081 max_fails=3 fail_timeout=10s;
        server 127.0.0.1:8082 max_fails=3 fail_timeout=10s;
}

server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        if ($http_x_forwarded_proto != 'https') {
                return 301 https://$host$request_uri;
        }

        location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header HOST $http_host;
                proxy_set_header X-NginX-Proxy true;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://blog-api-server;
                proxy_redirect off;
        }
 }

์„ค์ • ๋ณ€๊ฒฝ ํ›„์—๋Š”

sudo service nginx reload

 

 

docker

 

aws codedeploy permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock

docker ๋ฐ๋ชฌ ์†Œ์ผ“์— ์—ฐ๊ฒฐํ•  ๊ถŒํ•œ์ด ์—†์„ ๋•Œ

->

sudo usermod -aG docker $USER
sudo systemctl restart docker

 

sudo apt install docker-compose

 

๋””ํดํŠธ์ธ docker-compose.yml๊ณผ ๋‹ค๋ฅธ ์ด๋ฆ„์„ ๊ฐ€์ง„ docker-composeํŒŒ์ผ์„ ์ง€์ •ํ•˜๋Š” ๊ฒฝ์šฐ -f ์˜ต์…˜์„ ์‚ฌ์šฉ

docker-compose -f custom-compose-file.yml start

Untitled2Untitled3

๋ฐฐํฌ์—๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์ง€๋งŒ ์ปค๋ฐ‹์„ ํ•  ๋•Œ๋งˆ๋‹ค ์ปจํ…Œ์ด๋„ˆ๊ฐ€ blue ↔ green์œผ๋กœ ๋ฐ”๋€Œ์ง€ ์•Š๊ณ  ๊ณ„์† blue๋กœ๋งŒ ๋ฐฐํฌ๊ฐ€ ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋Š”๋ฐ

docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml ps | grep running

์—์„œ docker-compose ps๋ฅผ ํ–ˆ์„ ๋•Œ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋˜์—ˆ๋Š”์ง€ running์ด ์•„๋‹Œ Up์ด๋ผ๊ณ  ํ‘œ์‹œ๋˜์–ด์„œ ์‹คํ–‰ ์ค‘์ธ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๋Š” ๊ฑฐ์˜€๋‹ค. Up์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๋‹ˆ ์ž‘๋™ํ–ˆ๋‹ค.

Untitled4

Codedeploy๊ฐ€ ์‹คํ–‰ํ•œ๋Š” deploy.sh ํŒŒ์ผ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•œ๋‹ค.

#!/bin/bash

cd /home/ubuntu/app

DOCKER_APP_NAME=spring

# ์‹คํ–‰์ค‘์ธ blue๊ฐ€ ์žˆ๋Š”์ง€
EXIST_BLUE=$(docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml ps | grep Up)
echo "$EXIST_BLUE" >> debug.log

# green์ด ์‹คํ–‰์ค‘์ด๋ฉด blue up
if [ -z "$EXIST_BLUE" ]; then
    echo "blue up" >> debug.log
    docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml up -d --build

    sleep 30

    docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml down
    docker image prune -af # ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด๋ฏธ์ง€ ์‚ญ์ œ

# blue๊ฐ€ ์‹คํ–‰์ค‘์ด๋ฉด green up
else
    echo "green up" >> debug.log
    docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml up -d --build

    sleep 30

    docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml down
    docker image prune -af
fi

 

shell

shell script์—์„œ ์—๋Ÿฌ ๋กœ๊ทธ ๊ธฐ๋กํ•˜๋ ค๋ฉด

‘>’ - ๋ช…๋ น 1ํšŒ ๋™์ž‘ ์‹œ ๊ฒฐ๊ณผ๋ฅผ ํŒŒ์ผ๋กœ ์ €์žฅ, ์ดํ›„ ๋™์ผํ•œ ํŒŒ์ผ๋ช… ์‚ฌ์šฉ ์‹œ ํŒŒ์ผ ๋ฎ์–ด์”Œ์›€

‘>>’ - ๋ช…๋ น 1ํšŒ ๋™์ž‘์‹œ ๊ฒฐ๊ณผ๋ฅผ ํŒŒ์ผ๋กœ ์ €์žฅ, ์ดํ›„ ๋™์ผํ•œ ํŒŒ์ผ๋ช… ์‚ฌ์šฉ ์‹œ ๋งˆ์ง€๋ง‰ ์ €์žฅ์— ๋‚ด์šฉ ์ถ”๊ฐ€๋จ.

ex) echo “blue up” >> debug.log

if๋ฌธ์—์„œ -z ์˜ต์…˜์€?

string์ด empty์ธ์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ๋จ. ๋งŒ์•ฝ string์ด empty๋ผ๋ฉด if block ์•ˆ์— ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด else block์„ ์‹คํ–‰ํ•œ๋‹ค.

 

์šฉ๋Ÿ‰์ด ๋ถ€์กฑํ•ด์„œ ๋ฐฐํฌ๊ฐ€ ์•ˆ๋˜๋ฉด

์„œ๋น„์Šค ๊ธฐ๋Šฅ์ด ๊ฝค ๋งŽ๋‹ค ๋ณด๋‹ˆ ๋””์Šคํฌ ์šฉ๋Ÿ‰์ด ๋ถ€์กฑํ•ด์„œ ์ฝ”๋“œ๋””ํ”Œ๋กœ์ด, ๋„์ปค ๋“ฑ ์•„๋ฌด ๋ช…๋ น์–ด๋„ ์‹คํ–‰์ด ์•ˆ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊น€. ์Šค์›น ๋ฉ”๋ชจ๋ฆฌ๋งŒ ์ ์šฉํ•ด๋„ 2GB์ด๋‹ˆ ๊ทธ๋ƒฅ ์ฒจ๋ถ€ํ„ฐ 8GB๋Š” ์•ˆ์“ฐ๋Š”๊ฒŒ ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

์Šคํ† ๋ฆฌ์ง€์—์„œ ๋ณผ๋ฅจ์„ ๋Š˜๋ ค๋ณด์•˜๋Š”๋ฐ ๋ฐ˜์˜๋˜๋Š”๋ฐ 1์‹œ๊ฐ„ ์ •๋„ ๊ฑธ๋ฆฐ ๊ฒƒ ๊ฐ™๋‹ค. ๊ทธ๋™์•ˆ ๊ณต๊ฐ„์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ๊ฐ€์ง€๋ฅผ ํ•ด๋ดค๋‹ค.

ํด๋” ๋ณ„ ์šฉ๋Ÿ‰ ํ™•์ธ ๋ช…๋ น์–ด → ๋ถˆํ•„์š”ํ•œ ๋กœ๊ทธ ๋“ฑ ์šฉ๋Ÿ‰ ํฐ ํŒŒ์ผ์„ ์‚ญ์ œ

sudo du -shx /* | sort -h

์ „์ฒด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ ๋ช…๋ น์–ด → ์–ผ๋งˆ๋‚˜ ๋‚จ์•˜๋Š”์ง€ ํ™•์ธํ•  ๋•Œ

df -h

๋ถˆํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค ์ œ๊ฑฐ ๋ช…๋ น์–ด

docker system prune -a -f

์ปค๋„ ์‚ญ์ œ ๋ช…๋ น์–ด

sudo apt autoremove --purge