프로젝트 중에 새로운 버전이 개발되면 원격 서버에도 해당 버전으로 업그레이드해줘야 한다.
이전에는 원격 서버에 배포하기 위해서 직접 테스트하고 빌드 후에 Filezilla로 서버 파일을 옮겨서 배포했다.
프로젝트가 진행되면서 배포해야 할 일이 잦아졌는데 그럴 때마다 새로 빌드하고 테스트해서 배포하는 과정이 번거로웠다.
그래서 CI/CD를 도입하게 되었고 추가로 배포할 때에는 서버를 종료시켜야 하므로 안정적으로 서비스를 제공할 수 없는 상황이 생겼는데 이를 해결하기 위해서 무중단 배포 방식 중에 rolling 방식을 도입해 배포 중에도 서비스가 중단 없이 제공되도록 했다.
무중단 배포 과정을 간략하게 설명하자면 이렇다.
Github에 push를 하면 Webhook을 발생시키는데 Jenkins는 hook을 감지해서 그때 레포에서 새로운 버전의 애플리케이션을 끌어온다. 이후에 테스트를 진행하고 빌드 해서 각 서버에 배포하는데 jar 파일을 배포한 후에 서버에 있는 배포 스크립트를 원격 실행시켜서 현재 서버외에 살아있는 서버가 있는지 health check 후에 있다면 현재 서버를 update하는식으로 순서대로 배포된다.
Naver cloud 크레딧이 있어서 서버 구축에 필요한 모든 인스턴스는 Naver cloud를 이용했다. Naver cloud제공하는 상품을 이용하면 더 쉽게 구축할 수 있다.
하지만 필자는 직접 서버를 세팅하고 docker를 사용해 보기 위해서 상품을 사용하지 않고 server만 대여해서 직접 구축했다.
하나의 server에 여러 docker container를 생성해서 해도 되지만 필자는 각 서버를 따로 분리해서 구축하고 싶어서 다음과 같이 구성했다.
CI/CD의 CI는 개발자를 위한 자동화 프로세스인 지속적인 통합(Continuous Integration)을 의미한다.
쉽게 말해 빌드, 테스트, 코드 품질 체크 등…. 과 같은 일들을 CI 툴이 대신해주는 것이다.
CD는 지속적인 서비스 제공(Continuous Delivery) 및/또는 지속적인 배포(Continuous Deployment)를 의미한다.
CD도 마찬가지로 서버에 자동으로 배포해 주는 것을 말한다.
이런 CI/CD를 도와주는 도구들이 여러 가지 있는데 그중에서 Jenknis를 선택한 이유는 여러 가지 설루션이 있지만 관련 문서나 커뮤니티에 많은 정보가 있어서 선택하게 되었다.
Jenkins가 Github 레포지토리에 접근할 수 있도록 accesstoken을 발급받아야 한다.
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를 설치하기 전에 나의 project java 버전을 확인해보자. 현재 프로젝트는 java 17 버전을 사용하고 있다.
Jenkins 설치 후에 JDK 버전을 바꿔줘도 되지만 필자는 jenkins + jdk 17 버전의 image를 다운받았다.
Jenkins 다운로드후 이미지
Jenkins를 image를 다운받았다면 이제 docker image를 container로 만들어 실행시켜보자
docker run -d -p 8080:8080 이미지명
우리는 docker를 사용하기 때문에 로컬이 아닌 docker container 내부에 있는 파일을 확인해야 한다.
docker exec 컨테이너명 cat /var/jenkins_home/secrets/initialAdminPassword
이렇게 초기 비밀번호를 획득할 수 있다.
Jenkins 추천하는 plugin을 설치해서 설치 후에 앞으로 접근할 Jenkins admin 계정을 만든 후에 기본 설치를 완료하도록 하자.
이제 Jenkins에 추가로 필요한 설정과 플러그인을 설치 해보도록 하자.
먼저 여러 원격 서버에 파일을 배포하고 빌드 스크립트를 실행하기 위해서 Publish Over SSH Plugin을 설치해야 한다.
Jenkins 관리 > 플러그인 관리로 들어간다.
Available plugins > Publish Over SSH 검색 > 체크 > Download now and install after restart 클릭
plugin 설치를 누르면 Jenkins가 재부팅되고 설치가 완료된다.
배포할 서버를 등록해줘야 한다.
Jenkins 관리 > Configure System > 하단부 Publish over SSH
SSH servers 설정
여기서는 사용할 JDK, Gradle, Maven 등…. 버전을 설정할 수 있다. 각자의 프로젝트에 맞게 설정해두자
Jenkins 관리 > Global Tool Configuration
Add Gradle 선택 후 필요한 버전을 선택하자
Freestyle project > ok
프로젝트를 설정을 세팅해야 한다
GitHub hook trigger for GITS CM polling
을 선택해준다.원하는 옵션을 Gradle 명령어로 써주면 된다.
ex) test build bootjar clean 등
빌드 후에 어떤 동작을 할지 선택해야 함
프로젝트 > Configuration > 빌드 후 조치
추가 버튼을 선택한 다음 배포를 원하는 서버의 정보를 입력하자
watch 명령어를 이용해서 배포 디렉터리에 잘 배포되는지 확인해보자.
클릭시 영상 재생
마지막에 보면 jar 파일이 배포된 것을 볼 수 있다.
이외에도 Project 방식 외에 Pipeline으로 구축하는 방식도 있는데 애플리케이션 v1 은 최대한 쉽고 간단하게 구축해 봤다. 추후에 v2는 Pipeline 방식을 이용해서 배포하는 방법으로 변경할 예정이다.
다음 편은 어떻게 무중단 배포를 할지 무중단 배포 방법을 알아보고 실제로 무중단 배포를 테스트 해볼 예정이다.