[ 이준형 애플리케이션 배포 자동화와 CI/CD #5 ] nginx를 활용한 무중단 배포 환경 만들기

김수호·2024년 7월 6일
0
post-thumbnail

이번 내용에서는 nginx 를 활용해서 무중단 배포 환경을 만들어보자.

이를 위해서 먼저,

  • NGINX 설치를 위한 인스턴스를 생성하자.
    • 참고) 인스턴스 이름: nginx-instance 로 해주었다.
    • 참고) jenkins-instance 와 동일한 스펙으로 생성했다.
  • 애플리케이션 인스턴스 2개를 더 생성하자.
    • 참고) 인스턴스 이름: application-instance-2 로 해주었다.
    • 참고) 인스턴스 이름: application-instance-3 로 해주었다.
    • 참고) application-instance-1 와 동일한 스펙으로 생성했다.

👉 nginx-instanceNGINX 를 설치하자.
( ChatGPT 4o : 로키 리눅스에 nginx 설치하는 명령어 알려줘. )

  • 1) 시스템 패키지 업데이트
    • sudo dnf update
  • 2) EPEL (Extra Packages for Enterprise Linux) 리포지토리 설치
    • sudo dnf install epel-release
  • 3) Nginx 설치
    • sudo dnf install nginx
  • 4) Nginx 실행
    • sudo systemctl start nginx
  • 5) Nginx 가 부팅 시 자동으로 시작되도록 설정
    • sudo systemctl enable nginx
  • 6) 이제 접속해보자.
    • 참고) Nginx 의 기본 포트는 80 포트이다.
    • 접속이 안된다. ( 방화벽이 아직 해제되어 있지 않기 때문 )
  • 7) 방화벽을 열어주자.
    • sudo firewall-cmd --permanent --add-service=http
      • 참고) http 라고 되어있으면 80포트를 여는 것이다.
    • sudo firewall-cmd --reload
  • 8) 다시 접속해보자.
    • 잘 접속된다.
    • nginx 초기 페이지로 들어온 것을 확인할 수 있다. ( nginx 설치는 끝났다. )

 

👉 application-instance-2 , application-instance-3 두 애플리케이션 인스턴스에 각각 자바 애플리케이션을 띄워주기 위한 작업을 진행해야 한다.

  • 1) application-instance-2application-instance-3 에 기본으로 설치된 자바 버전은 8버전이다. 프로젝트의 jdk 버전은 17이므로 해당 버전으로 설치해야 한다.
    • sudo dnf install java-17-openjdk-devel
    • 설치 후 기본 자바 버전을 바꿔주자.
      • sudo alternatives --config java
      • 몇 번 기준으로 버전을 변경할 것인지 입력 후 엔터
      • java -version 으로 기본 버전 확인
  • 2) Jenkins 에서 각 애플리케이션 인스턴스에 접근할 수 있도록 Jenkins 의 공개키를 각 애플리케이션 서버 authorized_keys 에 등록해줘야 한다.
    • 이전에 application-instance-1 에서 vi ~/.ssh/authorized_keys 경로에 넣어줬던 Jenkins 의 공개키를, application-instance-2application-instance-3 에도 넣어주자.
  • 이제 애플리케이션 서버 입장에서는 배포 준비가 끝났다.

 

👉 이번에는 Jenkins 배포 스크립트에서 application-instance-1 뿐만 아니라, 다른 두 애플리케이션 서버에도 배포를 해주도록 수정해야 한다.

  • 1) 2_1_1_pipeline_script 적용
    • 참고) ChatGPT 3.5
  • 2) "지금 빌드"를 클릭해보자.
    • 정상적으로 배포된 것을 확인할 수 있다.
  • 3) application-instance-2application-instance-3 에 실제로 애플리케이션이 떴는지 확인해보기 위해 8080 포트로 접속해보자.
    • 먼저, 방화벽부터 열어주자.
      • sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
      • sudo firewall-cmd --reload
    • 접속해보자.
      • 2번, 3번 둘 다 잘뜬다.

 

👉 이제 마지막으로 한 가지 더 해줘야 하는 작업이 있다.

클라이언트에서 각각의 애플리케이션에 대해서 직접 8080 포트로 접속하는게 아니라, NGINX 를 통해서 접속을 하도록 만들어야 한다.

따라서 클라이언트에서 NGINX 로 접속을 했을 때, 애플리케이션 서버로 연결되도록 만들어보자.

  • 1) nginx 인스턴스에 접속하자.
  • 2) nginx 설정 파일을 변경하자. ( ChatGPT 3.5 )
    • vi /etc/nginx/nginx.conf
      • nginx로 들어온 요청이 3가지 서버로 포워딩 되도록 설정해야 한다. ( nginx에서는 80포트로 요청을 받고, 각 서버로는 8080 포트로 보내져야 한다. )
  • 3) nginx 설정이 정상적으로 되었는지 확인해보자. (문법 등 이상없는지 체크)
    • sudo nginx -t
  • 4) 변경한 설정으로 반영하자.
    • sudo systemctl reload nginx
  • 5) 이제 NGINX 의 IP주소로 80번 포트로 요청을 했을 때, 3가지 애플리케이션 서버 8080 포트로 연결이 된다.
    • 확인해보자.
      • 뭔가 안되는 것 같다. nginx 에서 발생하는 에러 로그를 확인해보자.
        • tail -f /var/log/nginx/error.log
        • 뭔가 Permission Denied 관련 로그가 나온다.
  • 6) 리눅스에 시큐리티 관련 설정 변경 ( 이 부분에 대한 자세한 내용은 추후 찾아보자. )
    • setsebool -P httpd_can_network_connect 1
    • 참고) httpd 프로세스에서 네트워크 연결 허용 여부를 결정하는 SELinux 설정
  • 7) 다시 NGINX 의 IP주소로 80번 포트로 요청해보자.
    • 드디어 잘 된다.

 

✔️ 참고) Host key verification failed (08:50)

  • 참고) 강의에서는 2_1_0_pipeline_script2_1_1_pipeline_script 의 내용이 다르지만, 강의 자료에서는 내용이 같아보인다. (강사님의 업로드 착오로 보인다.)
    • 강의에서 2_1_0_pipeline_script 적용 후 Host key verification failed 관련 오류가 발생해서 2_1_1_pipeline_script(StrictHostKeyChecking 옵션 적용) 로 수정한 것.
    • 따라서 원래 2_1_0_pipeline_script 에는 StrictHostKeyChecking 옵션이 없어야 함.
  • Host key verification failed 문제 참고)
    • https://hellorennon.tistory.com/20

 

✔️ 참고) 배포 스크립트 개선 - 2_2_pipeline_script

  • sleep 20
    • 현재 각각의 서버에서 애플리케이션이 시작될 시간을 20초 동안 sleep 으로 대기를 해주고 있다.
    • 이렇게 했을 때는 문제가 될 만한 여지가 있다.
    • 바로 20초 안에 애플리케이션이 배포가 완료되지 못했을 때 이다.
      • 2_2_pipeline_script 보다 이전의 스크립트 로직을 보면, 그렇게 될 시 result 가 0이 아니므로, 에러쪽으로 빠져서, 배포가 실패했다라고 간주가 될 것이다.
      • 따라서 20초를 기다리도록 하는 게 아니라, 계속 주기적으로 애플리케이션이 배포가 완료되었는지를 체크하도록 하는편이 더 낫다.
        • e.g. 3초씩 쉬면서(sleepInterval), 40번까지 반복해서 시도한다(maxAttempts).
          • 물론 애플리케이션이 배포되는 시간이 120초(3*40) 보다 더 오래걸린다고 하면 이 조차도 물론 부족해질 수도 있다.
          • 그러나 이렇게 했을 때의 장점은, 애플리케이션이 빠르게 배포되었을때, 다음 서버로 배포를 빠르게 넘어갈 수 있다.
            • (테스트를 해보면) 수정하기 전이었던, 20초를 무조건 기다릴 때보다, 실제로 배포 시간이 더 빨라진 것을 확인할 수 있다.

강의를 듣고 정리한 글입니다. 코드와 그림 등의 출처는 이준형 강사님께 있습니다.

profile
현실에서 한 발자국

0개의 댓글