Jenkins/Nginx로 무중단 배포 하기 1편

HYK·2022년 12월 25일
2

project

목록 보기
4/8
post-thumbnail
post-custom-banner

1편 CI/CD 구축하기

도입 배경

프로젝트 중에 새로운 버전이 개발되면 원격 서버에도 해당 버전으로 업그레이드해줘야 한다.
이전에는 원격 서버에 배포하기 위해서 직접 테스트하고 빌드 후에 Filezilla로 서버 파일을 옮겨서 배포했다.
프로젝트가 진행되면서 배포해야 할 일이 잦아졌는데 그럴 때마다 새로 빌드하고 테스트해서 배포하는 과정이 번거로웠다.
그래서 CI/CD를 도입하게 되었고 추가로 배포할 때에는 서버를 종료시켜야 하므로 안정적으로 서비스를 제공할 수 없는 상황이 생겼는데 이를 해결하기 위해서 무중단 배포 방식 중에 rolling 방식을 도입해 배포 중에도 서비스가 중단 없이 제공되도록 했다.

간단한 서버구성도

무중단 배포 과정을 간략하게 설명하자면 이렇다.
Github에 push를 하면 Webhook을 발생시키는데 Jenkins는 hook을 감지해서 그때 레포에서 새로운 버전의 애플리케이션을 끌어온다. 이후에 테스트를 진행하고 빌드 해서 각 서버에 배포하는데 jar 파일을 배포한 후에 서버에 있는 배포 스크립트를 원격 실행시켜서 현재 서버외에 살아있는 서버가 있는지 health check 후에 있다면 현재 서버를 update하는식으로 순서대로 배포된다.

Naver Cloud Platform

Naver cloud 크레딧이 있어서 서버 구축에 필요한 모든 인스턴스는 Naver cloud를 이용했다. Naver cloud제공하는 상품을 이용하면 더 쉽게 구축할 수 있다.
하지만 필자는 직접 서버를 세팅하고 docker를 사용해 보기 위해서 상품을 사용하지 않고 server만 대여해서 직접 구축했다.
하나의 server에 여러 docker container를 생성해서 해도 되지만 필자는 각 서버를 따로 분리해서 구축하고 싶어서 다음과 같이 구성했다.

CI/CD 구축

CI/CD의 CI는 개발자를 위한 자동화 프로세스인 지속적인 통합(Continuous Integration)을 의미한다.
쉽게 말해 빌드, 테스트, 코드 품질 체크 등…. 과 같은 일들을 CI 툴이 대신해주는 것이다.
CD는 지속적인 서비스 제공(Continuous Delivery) 및/또는 지속적인 배포(Continuous Deployment)를 의미한다.
CD도 마찬가지로 서버에 자동으로 배포해 주는 것을 말한다.
이런 CI/CD를 도와주는 도구들이 여러 가지 있는데 그중에서 Jenknis를 선택한 이유는 여러 가지 설루션이 있지만 관련 문서나 커뮤니티에 많은 정보가 있어서 선택하게 되었다.

Github Token/Webhook

Jenkins가 Github 레포지토리에 접근할 수 있도록 accesstoken을 발급받아야 한다.

  • 먼저 Settings > Developer settings > Personal access tokens (classic)에 접속한다.
  • 오른쪽 위에 있는 generate new token을 클릭하고 두 번째 버튼을 누르면 된다.

  • token 만료일을 지정하고 권한을 지정한 후에 token을 생성하면 된다.

  • token을 생성하면 다음과 같이 보여주는데 이 값을 복사해두고 나중에 Jenkins 설정할 때 넣으면 된다.

  • 그다음은 프로젝트의 Webhook을 설정해 줘야 한다

  • ProjectRepo > Settings > Webhooks > Add webhook을 클릭하면 다음과 같은 화면이 나온다.

  • Payload URL는 https://jenkins 도메인/github-webhook/ 혹은 https://{jenkins Ip}:{port}/github-webhook/로 입력해 주면 된다.

  • Content type은 json으로 변경해 준다.

  • Add hook 버튼을 누르면 github 세팅은 끝난다.

Jenkins

먼저 Jenkins를 설치하기 전에 나의 project java 버전을 확인해보자. 현재 프로젝트는 java 17 버전을 사용하고 있다.
Jenkins 설치 후에 JDK 버전을 바꿔줘도 되지만 필자는 jenkins + jdk 17 버전의 image를 다운받았다.

Jenkins 설치

  • Jenkins 다운로드후 이미지

  • Jenkins를 image를 다운받았다면 이제 docker image를 container로 만들어 실행시켜보자

docker run -d -p 8080:8080 이미지명
  • {ip}:{설정한 port} 로 접속
    • 해당 포트로 접근 시에 이런 화면을 볼 수 있는데 Jenkins 의 초기 비밀번호를 입력해줘야 접근할 수 있다.
  • 우리는 docker를 사용하기 때문에 로컬이 아닌 docker container 내부에 있는 파일을 확인해야 한다.

    docker exec 컨테이너명 cat /var/jenkins_home/secrets/initialAdminPassword
  • 이렇게 초기 비밀번호를 획득할 수 있다.

  • Jenkins 추천하는 plugin을 설치해서 설치 후에 앞으로 접근할 Jenkins admin 계정을 만든 후에 기본 설치를 완료하도록 하자.

추가 plugin 설치

이제 Jenkins에 추가로 필요한 설정과 플러그인을 설치 해보도록 하자.
먼저 여러 원격 서버에 파일을 배포하고 빌드 스크립트를 실행하기 위해서 Publish Over SSH Plugin을 설치해야 한다.

  • Jenkins 관리 > 플러그인 관리로 들어간다.

  • Available plugins > Publish Over SSH 검색 > 체크 > Download now and install after restart 클릭

    plugin 설치를 누르면 Jenkins가 재부팅되고 설치가 완료된다.

Publish Over SSH 설정

배포할 서버를 등록해줘야 한다.

  • Jenkins 관리 > Configure System > 하단부 Publish over SSH

  • SSH servers 설정

    • Name - 서버 이름
    • Hostname - 서버 IP
    • Username - 접속할 user id
    • Remote Directory - 접속 후 이동할 디렉터리
    • Use password authentication, or use a different key
      체크박스를 선택하고 접속할 때 필요한 비밀번호(cloud일 경우 인증 key)를 입력하고 저장을 눌러서 정보를 저장

Jenkins build 설정

여기서는 사용할 JDK, Gradle, Maven 등…. 버전을 설정할 수 있다. 각자의 프로젝트에 맞게 설정해두자

  • Jenkins 관리 > Global Tool Configuration

  • Add Gradle 선택 후 필요한 버전을 선택하자

프로젝트 생성 및 설정

  • Freestyle project > ok

  • 프로젝트를 설정을 세팅해야 한다

소스 코드 관리

  • 구성 > 소스 코드 관리
  • 다음과 같이 우리가 관리할 git URL과 add를 눌러서 git에 인증정보를 추가해 주면 된다.
  • add를 눌러서 인증정보를 추가하자 위의 Github 에서 발급받았던 access token을 이용하면 된다
    • Username - Github id 입력
    • Password - 토큰 입력
    • Id - 인증 식별자 (아무거나 적어도 됨)
  • 인증정보 생성 후 다음과 같이 설정해 주면 된다.
    • Credentials - 인증 정보 선택
    • branch 선택

빌드 유발

  • Jenkins가 자동으로 build를 하기 위해서 조건을 선택해준다. Github WebHook을 이용해서 brach에 push 될 때 빌드를 진행할 것이기 때문에 GitHub hook trigger for GITS CM polling을 선택해준다.

Build step

원하는 옵션을 Gradle 명령어로 써주면 된다.
ex) test build bootjar clean 등

  • 원하는 Gradle 버전과 tasks 설정

빌드 후 조치

빌드 후에 어떤 동작을 할지 선택해야 함

  • 우리는 ssh를 통해서 jar 배포 파일을 보내야 한다. 때문에 Send build artifacts over SSH를 선택한다.
  • 프로젝트 > Configuration > 빌드 후 조치

  • 추가 버튼을 선택한 다음 배포를 원하는 서버의 정보를 입력하자

    • Name - 배포할 서버 선택
    • Source files - 전송할 source file 위치 입력
    • Remove prefix - Source files에서 jar만 보내기 위해서 나머지 제거할 경로
    • Remote directory - 전송 시 다운로드 받을 원격 디렉터리 위치
    • Exec command - 파일 전송 후 진행할 작업 script

watch 명령어를 이용해서 배포 디렉터리에 잘 배포되는지 확인해보자.

클릭시 영상 재생

IMAGE ALT TEXT HERE

마지막에 보면 jar 파일이 배포된 것을 볼 수 있다.

이외에도 Project 방식 외에 Pipeline으로 구축하는 방식도 있는데 애플리케이션 v1 은 최대한 쉽고 간단하게 구축해 봤다. 추후에 v2는 Pipeline 방식을 이용해서 배포하는 방법으로 변경할 예정이다.

다음 편은 어떻게 무중단 배포를 할지 무중단 배포 방법을 알아보고 실제로 무중단 배포를 테스트 해볼 예정이다.

profile
Test로 학습 하기
post-custom-banner

0개의 댓글