
저번 포스트에서는 CD 파트까지 테스트를 완료했다.
이번 포스트에서는 지금까지 했던 CI/CD 구조를 다시 한번 살펴보고, Github에 Push를 했을 때, 자동으로 빌드하고 배포되게끔 자동화해보자.
지금까지 해온 CI/CD 구조를 그림으로 나타낸 것이다.
사용자가 Jenkins 인스턴스에 접속해서 Jenkins에게 Deploy 하라는 지시를 내리게 되면, Jenkins는 Jenkins Pipeline 스크립트에 정의된대로 따라간다.
먼저, 등록된 Github 레포지토리에 접속하여 소스 코드를 가져온다.
소스 코드를 가져오면, 적절한 처리(보안에 민감한 파일 등)를 거치고, gradle을 통해서 Build를 수행한다.
Build를 하게되면 .jar 파일이 산출되고, 이 파일을 각 서버 인스턴스에 전달한다.
위의 CI/CD 구조는 결국 사용자가 Jenkins 인스턴스에 접속해서 Deploy 명령을 내려야 하는 것이다. (자동화 X)
처음에 계획한 대로, Github Webhook을 이용해서 Github에 Push만 해도 자동으로 빌드, 배포까지 완료할 수 있도록 자동화를 해보도록 하자.
Github Webhook을 이용하게 되면, 사용자가 직접 Deploy 명령을 Jenkins에게 내릴 필요 없이, Github에 Push 하기만 하면, Github Webhook에서 Jenkins 인스턴스로 Deploy 요청을 보내게 된다.
요청을 받은 Jenkins는 이전과 같은 Deploy 과정을 수행하게 된다.
Github Webhook을 사용하기 위해서는, 토큰을 발급받아야 한다.
Github에 접속하여 Developer settings에 들어간다.

Token을 클릭한다.
토큰을 새로 생성하기 위해 Generate New Token(Classic)를 클릭하자.

Note에 토큰의 이름을 지정할 수 있다.Expiration은 토큰의 유효기간을 설정하는 것이다. 단순 배포 및 공부를 위해서 생성하는 것이라면 30일 정도로 설정해두자. 만약, 오랫동안 배포를 지속해야한다면, No Expiration으로 만료기간 없이 설정할 수 있다.Select Scopes에서는 이 토큰으로 할 수 있는 동작들을 설정할 수 있다. 만약 우리가 Jenkins에 deploy 명령을 webhook 하기 위해서는 admin:repo_hook 이라고 하는 곳을 체크해주면 된다.
만약 프로젝트 저장소가 private 이거나, private로 전환할 가능성이 있다면, 맨 위의 scopes인
repo도 체크해주어야 한다.repo를 선택하지 않으면, 저장소가 private한 상태에서는 Jenkins가 저장소의 소스 코드를 가져오지 못할 수 있기 떄문이다.
repo에 체크만 한다고 Jenkins에서 바로 가져오는 것은 아니고, Jenkins에서도 별도의 설정을 해주어야한다.
이제 우리의 프로젝트 레포지토리로 이동하자.
레포지토리의 Settings에서 Webhooks로 들어가자.
Add webhook 버튼을 클릭하자.

Payload URL은 어디로 Request를 보낼 것인지를 지정하는 URL이다. 우리는 Jenkins로 보낼 것이기 때문에, Jenkins 인스턴스의 IP로 보내주어야한다./github-webhook/ 이라는 주소가 추가적으로 붙어야 한다. 따라서 전체적인 주소는 다음과 같다.http://{Instance-ip:8030}/github-webhook/Content-Type은 어떤 형식으로 보낼 것인지인데, 일반적으로 application/json을 사용한다.Secret은 아까 발급받은 Token의 값을 입력해주자.Just the push event는 push하는 경우에 대해서만 webhook request가 전송된다.everything은 모든 동작에 대해 webhook request가 전송된다.select individual events는 어떤 이벤트에 대해 webhook을 동작시킬 것인지를 커스터마이징해 선택할 수 있다. ex) pull request, merge 등...새로운 Credentials를 생성해야한다. Jenkins에 접속하여 Jenkins 관리 - Credentials로 들어가자.
(global)을 클릭하여, Add Credentials 버튼을 클릭하자.

Username with password로 선택하자.Username은 우리의 Github 이메일(또는 닉네임)을 넣어야 한다.password는 우리가 발급 받았던 Token 값을 넣어주면 된다.ID는 Jenkins Pipeline에 해당 ID로 credentials 값을 가져오기 위한 alias 이므로, 본인이 알아서 정하면 된다.
이제 Dashboard - 내 작업(gaseyola_pipeline) - 구성 으로 들어가자.

원래는 GitHub project에 체크가 안되어 있다. 체크를 한 후, 우리가 배포할 레포지토리 주소를 입력하자.
그 다음, Triggers에서 GitHub hook trigger for GITScm polling을 체크하자.
이렇게 되면, Jenkins가 Github webhook에 반응하여 deploy를 시작하게 설정할 수 있다.
모든 설정을 마쳤다면, 우리 프로젝트를 수정한 다음 push 해보도록 하자.
그 다음 Jenkins를 확인해보면, 자동으로 deploy가 진행되고 있는 것을 확인할 수 있다.

push를 하자, deploy를 수행하고있다.
성공적으로 완료되었다!
이번 포스트에서는 Github Webhook과 연동하여 push를 수행할 시, 자동으로 서버 인스턴스에 배포를 수행하도록 구성했다. 즉, CI/CD 자동화를 구축한 것이다!
하지만, 배포하는 동안 서비스가 내려가있는다는 문제점이 아직 존재한다. 이런 서비스 다운 타임을 최대한 줄이기 위한 방법으로는, 무중단 배포가 있다.
다음에는 무중단 배포에 관해서도 포스트를 작성하도록 하겠다.
필자는 몇일에 걸쳐 포스팅 하다보니, 비용 걱정에 EC2 인스턴스를 중지했다 실행했다를 반복하며 진행했다.
그러다보니, 인스턴스의 IP가 계속해서 바뀌어서 새로 포스팅 할 때마다, 수정해주어야 하는 요소가 있다.
EC2를 실행하고, Jenkins 인스턴스와 서버 인스턴스를 Git Bash로 한번씩 접속해준 후, Jenkins 인스턴스의 Jenkins 컨테이너로 sudo docker exec -it jenkins bash 명령으로 접속한 다음, ssh -o StrictHostKeyChecking=no ubuntu@[서버 인스턴스 ip]로 SSH 통신을 최초 한번은 연결해 주어야, 서버 인스턴스에서 Jenkins 인스턴스를 신뢰하는 ip로 판단하여 이후 CI/CD 과정에서 오류없이 통과될 수 있다.
Jenkins Pipeline의 Script에서 바뀐 서버 인스턴스 IP 주소를 적용해주어야 한다.