서버 인프라/DevOps

Jenkins를 이용하여 Docker 애플리케이션 배포하기 [1]

트리맨스 2022. 1. 26. 00:25
반응형

 

현재 우리 회사의 배포환경은 절반은 자동, 절반은 수동으로 배포를 하는 중이다. 대략적인 플로우는 github에 push를 하게 되면 dockerhub에서 자동으로 빌드가 되고, 이 이미지를 수동으로 elastic beanstalk에 배포하는 방식이다. 테스트 환경은 상관없는데 프로덕션 환경에서는 상당히 거추장스럽다는 생각이 들게 되었다. 그래서 자동 배포 툴을 찾아보다가 Jenkins 라는 CI/CD 툴을 발견하게 되었다. 내가 사용하는 환경에서 상당히 적합하다는 느낌을 많이 받아서 Jenkins를 사용하기로 했다.

 

구상하기


구상한 환경은 다음과 같다.

 

 

내가 대강 구상한 플로우는 번호 순서대로 따라가면 된다.

 

1. 로컬에서 코드 작성 후 Github에 push한다.

2. webhook을 통해서 코드 저장소에 변화가 생겼다는 신호를 Jenkins에 준다.

3. 신호를 받은 Jenkins는 로컬에서 (Jenkins를 설치한 컨테이너에서) 도커 이미지를 빌드한다.

4. 만들어진 도커 이미지를 AWS ECR에 업로드한다.

5. AWS Elastic Beanstalk에 배포 요청을 한다.

6. Elastic Beanstalk에서는 ECR에 업로드된 도커 이미지를 이용해 배포한다.

 

젠킨스 설치하기


먼저 젠킨스를 설치해야한다. 나의 경우에는 EC2 인스턴스를 하나 파서 거기다가 설치했다. 로컬에서 도커 이미지를 빌드해야 해서 2코어 이상의 인스턴스로 설정했다. 

 

사실 EC2에 설치하는 것은 큰 문제가 없었다. 공식 문서에서 친절하게 설명을 잘 해서 큰 어려움 없이 진행할 수 있었다. 중간에 daemon에 관한 에러가 발생했는데, sudo amazon-linux-extras install epel 명령어를 사용해서 바로 넘길수 있었다.

 

https://www.jenkins.io/doc/tutorials/tutorial-for-installing-jenkins-on-AWS/

 

Jenkins on AWS

A security group acts as a firewall that controls the traffic allowed to reach one or more EC2 instances. When you launch an instance, you can assign it one or more security groups. You add rules to each security group that control the traffic allowed to r

www.jenkins.io

https://exerror.com/error-package-jenkins-2-306-1-1-noarch-jenkins-requires-daemonize/

 

[Solved] Error: Package: jenkins-2.306-1.1.noarch jenkins Requires: daemonize - Exception Error

To Solve Error: Package: jenkins-2.306-1.1.noarch jenkins Requires: daemonize Run this command line to solve this issue. amazon-linux-extras i

exerror.com

 

기본적인 설정을 마치고 다음과 같은 화면이 뜨면 성공이다.

 

 

여기서 Jenkins는 기본 유저가 아닌 jenkins 유저로 실행이 된다! 이게 나중에 엄청나게 내 발목을 잡았다. 꼭 기억해두자. 권한 문제로 삽질을 유도한다.

 

 

깃허브와 연결하기


이 글은 public repo가 아니라 private repo를 기준으로 하기 때문에 인증에 관한 내용이 좀 많다.

 

내 목적은 깃허브의 저장소(deploy branch)에 변화가 생길 경우 jenkins가 알아채는 것이다. 이를 구현하기 위해서는 깃허브의 '웹훅'을 사용해야 한다.

 

Webhook이란?

위키백과에 따르면,  '사용자 정의 콜백을 사용하여 웹 페이지 또는 웹 애플리케이션의 동작을 보강하거나 변경하는 방법' 으로 나와있다. 이게 뭔 소리인가 하니, 일반적인 REST API는 데이터를 받기 위해서 서버에 요청을 보낸다. 하지만 서버의 상태가 변경된 것을 실시간으로 알기는 힘들다. 왜냐하면 서버의 상태가 변경된 것을 알기 위해서는 주기적으로 요청을 보내야 응답이 오기 때문이다. 하지만 Webhook을 쓰면 서버에서 클라이언트에게 신호를 준다!

 

 

우리는 클라이언트인 Jenkins의 주소가 고정되어 있어서 Webhook을 사용하면 Github와 잘 연동할 수 있다!

 

 

우리의 목표는 deploy branch에 변화가 생겼을 경우에 Jenkins에서 응답을 받게 하는 것이다.

 

 

1. 키 생성

 

github와 연결하기 위해서는 ssh key가 필요하다. 젠킨스가 설치된 인스턴스에서 ssh key를 만들자. 여기서 주의할 것은 ec2-user에서 만드는 것이 아닌 jenkins 유저에서 만들어야 한다.

 

# 젠킨스 유저로 변경하기

sudo -u jenkins bash

 

# ssh key 만들기

ssh-keygen

 

# ssh key 보기

cat /var/lib/jenkins/.ssh/id_rsa.pub

 

 

2. 키 등록

 

Github의 repo에서 setting에 진입하면 Deploy key 메뉴가 있다. 여기서 방금 만들고 본 ssh key의 정보를 입력한다.

 

 

3. Webhook 설정하기 

 

Github의 repo에서 현재 Jenkins의 주소를 Webhook 주소로 등록한다. ( 예 : 젠킨슨주소/github-webhook )

 

 

3. jenkins에서 확인하기

 

메인화면 -> 새로운 아이템 -> 프리스타일 프로젝트 -> 소스 코드 관리 -> git 주소를 입력한다. 여기서 git 주소는 git clone 할때 뒤에 붙는 ssh 주소를 입력해야 한다.

 

사실 여기서 나는 많이 고생했다. 다른 예시들을 보면 Credentials에 Kind: Secret text 옵션으로 인증 수단을 설정하기 때문이다. 여기에 내 github 계정의 Personal access token을 입력하면 된다....라고 다른곳에서 말했다. 나도 이러면 될 줄 알았으나, 계속 진도가 나가지 않았다. 그래서 Jenkins에서 터미널 켜고 git ls-remote 명령어를 혹시나 해서 쳐 보았다. 그제서야 연동이 되는 것이다! 하루 날린 것 치고는 너무 쉽게 해결되서 힘이 다 빠져버렸다.

 

인증이 되었으면 Branch Specifier를 */deploy로 바꾼 다음 빌드 유발-> GitHub hook trigger for GITScm polling 를 체크, script path는 Jenkinsfile로 설정한다.

 

 

4. 깃허브에 push 해보기

 

deploy branch에 push 해보고 Jenkins에서 반응하는지 확인한다. 빌드 작업이 생성되면 성공한 것이다. 그리고 중간에 deploy branch 에서 Jenkinsfile이 하나 생겼을 것이다. 여기는 파이프라인을 코드로 정할 수 있는 파일인데, 이 부분부터는 다음 게시물에서 설명할 예정이다.

 

https://tre2man.tistory.com/286

 

Jenkins를 이용하여 Docker 애플리케이션 배포하기 [2]

저번 글에서는 Jenkins와 Github를 연결해 보았다. 연결하는 순간 Github에 Jenkins 파일이 생성될 것이다. 젠킨스 파일을 이용해서 파이프라인을 구성하면 배포 과정을 비교적 쉽게 알아챌 수 있다. 3번

tre2man.tistory.com

 

 

반응형