AWS

[AWS 무중단 배포] Nginx설치 설정 및 서버 파일 script추가

운덩하는 개발자 2022. 12. 8.
반응형

1. Nginx

 

 

 

1. 1 소개

Nginx는 널리 쓰이는 웹 서버 중 하나이다.


Nginx는 정적 자원의 처리 외에도 proxy 서버의 역할이나, reverse proxy 서버의 역할 등 여러 방면에서 높은 활용도를 보여준다.


여기서는 Nginx가 CodeDeploy Agent에 의해 두 WAS간의 스위칭 역할을 담당하도록 구성해 보겠다.



1. 2 Nginx 설치와 설정

 

sudo amazon-linux-extras install nginx1
sudo nginx -v # 설치 버전 확인


설치 후 /etc/nginx/ 로 이동해 보시면 다양한 nginx 설치파일들을 볼 수 있다.


우리가 관심있게 보아야 할 것은 설정파일인 nginx.conf 파일이다.



파일 수정이 필요하니 sudo 권한으로 nginx.conf 파일을 연다.

 

sudo vim /etc/nginx/nginx.conf



다음과 같이 스크립트를 추가


include /home/ec2-user/service_url.inc;

location / {
    proxy_set_header    X-Forwarded-For $remote_addr;
    proxy_set_header    Host $http_Host;
    proxy_pass          $service_url;
}

 

 

  • include
    • 다른 곳에 존재하는 설정 파일 등을 불러올 수 있다
  • proxy_pass
    • 우리가 지정할 $service_url로 요청을 보낼 수 있도록 하는 프록시 설정

include로 불러올 파일 경로에 다음과 같이 파일을 생성하고 $service_url 변수를 설정

 

 

vim /home/ec2-user/service_url.inc

 

 

# service_url.inc

set $service_url http://127.0.0.1:8081;

 

 


이렇게 nginx 설정은 끝이 났다.

 

 


다음 명령어로 nginx를 시작하고 nginx의 status를 확인할 수 있다.

 

sudo service nginx start
sudo service nginx status

 

2. 배포 스크립트 추가

 
마지막으로 프로젝트에 CodeDeploy Agent가 참고하여 배포를 진행하기 위한 스크립트들을 추가할 것이다.


appspec.yml에 다음과 같이 스크립트를 추가하자


# appspec.yml

version: 0.0
os: linux
files:
  - source: / #전부
    destination: /home/ec2-user/Board/ #인스턴스에서 파일이 복사되어야 하는 위치 식별
    overwrite: yes #선택 값으로, 동일한 파일이 있을 경우 덮어쓰기 여부

#정의한 파일이 인스턴스에 복사된 후 해당 파일에 권한이 어떻게 적용되어야 하는 지를 지정
permissions:
  - object: / #문자열을 사용하여 대상을 지정합니다. /는 전부
    pattern: "**" #권한을 적용할 패턴을 지정합니다. 특수 문자"**"를 사용하여 지정하면 권한이 type에 따라 일치하는 모든 파일에 적용됩니다.
    owner: ec2-user # object의 소유자 이름, 지정하지 않으면 원본 파일에 적용된 기존의 모든 소유자가 복사 작업 후에도 아무것도 변경되지 않습니다.
    group: ec2-user # object의 그룹 이름, 지정하지 않으면 원본 파일에 적용된 기존의 모든 소유자가 복사 작업 후에도 아무것도 변경되지 않습니다.
### 새로 추가한 부분 ###
hooks:
  ApplicationStart:
    - location: scripts/run_new_was.sh
      timeout: 180
      runas: ec2-user
    - location: scripts/health_check.sh
      timeout: 180
      runas: ec2-user
    - location: scripts/switch.sh
      timeout: 180
      runas: ec2-user

 

 

  • hooks
    • CodeDeploy의 배포에는 각 단계 별 수명 주기가 존재. 수명 주기에 따라 원하는 스크립트를 수행할 수 있다.

ApplicationStart라는 수명 주기에 세 가지 스크립트를 차례로 실행할 것이기에, 

프로젝트 최상단에 scripts 디렉토리와  다음과 같이 세 개의 파일을 생성하자




# run_new_was.sh

#!/bin/bash

CURRENT_PORT=$(cat /home/ec2-user/service_url.inc | grep -Po '[0-9]+' | tail -1)
TARGET_PORT=0

echo "> Current port of running WAS is ${CURRENT_PORT}."

if [ ${CURRENT_PORT} -eq 8081 ]; then
  TARGET_PORT=8082
elif [ ${CURRENT_PORT} -eq 8082 ]; then
  TARGET_PORT=8081
else
  echo "> No WAS is connected to nginx"
fi

TARGET_PID=$(lsof -Fp -i TCP:${TARGET_PORT} | grep -Po 'p[0-9]+' | grep -Po '[0-9]+')

if [ ! -z ${TARGET_PID} ]; then
  echo "> Kill WAS running at ${TARGET_PORT}."
  sudo kill ${TARGET_PID}
fi

nohup java -jar -Dserver.port=${TARGET_PORT} /home/ec2-user/playground-logging/build/libs/* > /home/ec2-user/nohup.out 2>&1 &
echo "> Now new WAS runs at ${TARGET_PORT}."
exit 0



  • 새로운 WAS를 띄우는 스크립트
    • service_url.inc 에서 현재 서비스를 하고 있는 WAS의 포트 번호를 읽어온다.
    • 현재 포트 번호가 8081이면 새로 WAS를 띄울 타겟 포트는 8082, 혹은 그 반대 상황이라면 8081을 지정
    • 만약 타겟포트에도 WAS가 떠 있다면 kill 하고 새롭게 WAS를 띄운다.

 

 

  • nohup
    • 터미널 액세스가 끊겨도 실행한 프로세스가 계속 동작하게 한다.
    • 마지막의 &는 프로세스가 백그라운드로 실행 지정



# health_check.sh

#!/bin/bash

# Crawl current connected port of WAS
CURRENT_PORT=$(cat /home/ec2-user/service_url.inc | grep -Po '[0-9]+' | tail -1)
TARGET_PORT=0

# Toggle port Number
if [ ${CURRENT_PORT} -eq 8081 ]; then
    TARGET_PORT=8082
elif [ ${CURRENT_PORT} -eq 8082 ]; then
    TARGET_PORT=8081
else
    echo "> No WAS is connected to nginx"
    exit 1
fi


echo "> Start health check of WAS at 'http://127.0.0.1:${TARGET_PORT}' ..."

for RETRY_COUNT in 1 2 3 4 5 6 7 8 9 10
do
    echo "> #${RETRY_COUNT} trying..."
    RESPONSE_CODE=$(curl -s -o /dev/null -w "%{http_code}"  http://127.0.0.1:${TARGET_PORT}/health)

    if [ ${RESPONSE_CODE} -eq 200 ]; then
        echo "> New WAS successfully running"
        exit 0
    elif [ ${RETRY_COUNT} -eq 10 ]; then
        echo "> Health check failed."
        exit 1
    fi
    sleep 10
done

 

 

  • 새로 띄운 WAS가 완전히 실행되기까지 health check 하는 스크립트



# switch.sh

#!/bin/bash

# Crawl current connected port of WAS
CURRENT_PORT=$(cat /home/ec2-user/service_url.inc  | grep -Po '[0-9]+' | tail -1)
TARGET_PORT=0

echo "> Nginx currently proxies to ${CURRENT_PORT}."

# Toggle port number
if [ ${CURRENT_PORT} -eq 8081 ]; then
    TARGET_PORT=8082
elif [ ${CURRENT_PORT} -eq 8082 ]; then
    TARGET_PORT=8081
else
    echo "> No WAS is connected to nginx"
    exit 1
fi

# Change proxying port into target port
echo "set \$service_url http://127.0.0.1:${TARGET_PORT};" | tee /home/ec2-user/service_url.inc

echo "> Now Nginx proxies to ${TARGET_PORT}."

# Reload nginx
sudo service nginx reload

echo "> Nginx reloaded."



 

  • Nginx 리로드를 통해 서비스하는 포트를 스위칭하는 스크립트
    • sudo service nginx reload -  Nginx서버의 재시작 없이 바로 새로운 설정값으로 서비스를 이어나갈 수 있도록 설정
    • sudo service nginx restart - 말 그대로 서버의 shutdown 이후 재시작하는 명령이므로 의도하지 않았다면 주의해야 한다.
  • tee
    • 출력 내용을 파일로 만들어주는 커맨드
    • 새로 띄운 WAS의 포트를 nginx가 읽을 수 있도록 service_url.inc에 내용을 덮어쓴다

 

 

Reference
https://bbogle2.tistory.com/entry/%EB%AC%B4%EC%A4%91%EB%8B%A8-%EB%B0%B0%ED%8F%AC-Nginx-CodeDeploy-Github-Actions

반응형

'AWS' 카테고리의 다른 글

[AWS CI/CD] nohup사용 및 배포  (0) 2022.12.08
[AWS CI/CD] Codedeploy 배포 오류  (0) 2022.12.08
[AWS CI/CD] Appspec.yml  (0) 2022.12.07
[AWS CI/CD]CodeDeploy 실패 오류  (0) 2022.12.07
[AWS CI/CD] deploy.yml 수정 및 해결  (0) 2022.12.06

댓글