STUDY/Web

배포 자동화 (3) Jenkins 파이프라인 작성

sinawi95 2022. 1. 4. 21:04
728x90

(1) Docker 설치 및 Jenkins 설정

(2) 백엔드, 프론트 엔드 도커 이미지 빌드

(3) 원격 서버에서 도커 이미지 실행: Jenkins 파이프라인 작성

(4) HTTPS 적용 및 Nginx 설정 : letsencrypt와 certbot을 사용한 SSL 인증서 설치, 리버스 프록시 적용


프로젝트가 끝난지 벌써 2개월이 지났다. 기억을 많이 잃어버렸지만 있는 지식, 없는 지식까지 총동원해서 빠르게 완성시켜야겠다.

지난 포스팅에서 jenkins, express, nginx 각각 도커 이미지를 만들고 실행하는것까지 확인하였다.

이제 Gitlab의 master가 업데이트 되었을 때 프론트엔드와 백엔드의 이미지를 만들고(CI), 배포(CD)까지의 작업을 자동화 시켜야한다.

 

1. Jenkins 트리거 생성

push, merge 등의 Gitlab 이벤트가 생기면 Jenkins가 알수 있도록 웹 훅을 보내도록 만들어야한다.

Jenkins에 로그인을 하고 새로운 프로젝트를 등록하자.

  • Dashboard - 새로운 item - 이름 작성후 Freestyle project 클릭

그리고 만든 프로젝트에서 secret token을 생성한다. gitlab에서 jenkins에 트리거를 전송하려면 필요하다

  • Build Triggers(빌드 유발) 탭 클릭 - Build when a change is pushed to Gitlab. Gitlab webhook URL 체크
  • URL은 Gitlab 설정에 필요하니 복사해두자.
  • 고급... 클릭 후 아래 Secret token Generate 클릭
  • secret token 값 복사 후 설정을 저장하고 나오면 된다.

 

다음은 Gitlab에 연동하는 작업이다. 

연동할 프로젝트에서 웹훅을 설정한다.(연동할 Gitlab 프로젝트 - Setting - webhooks)

  • jenkins에서 복사해둔 URL과 Secret token을 붙여 넣는다.
  • Trigger: push events 는 push 이벤트를 적용할 브랜치를 작성한다. 빈 값으로 두면 모든 브랜치에 push 이벤트 트리거가 적용되니 master 브랜치에만 적용한다.
  • Add webhook 을 눌러 작성한 내용을 저장한다.

연동이 되었는지 확인해보자

  • Test - push event 를 클릭해서 Hook executed successfully: HTTP 200 가 보이면 성공이다.

 

2. Jenkins 파이프라인 작성

1에서 생성한 프로젝트에 gitlab 계정을 등록하고 파이프라인을 작성한다.

만들려고하는 파이프라인 순서는 다음과 같다.

  1. git clone을 해서 코드를 받는다.
  2. 현재 컨테이너에서 도커이미지를 만든다. 컨테이너를 생성할 위치로 도커 이미지를 옮긴다.
  3. 원격 서버에 접속하여 도커 이미지로 프론트, 백엔드 컨테이너를 생성한다.

프론트엔드와 백엔드 모두 컨테이너로 만들긴하지만 생성하는 위치는 같다. jenkins 컨테이너가 돌아가는 위치와 같다.

파이프라인은 프로젝트의 구성에 들어가서 작성할수 있다.

1. 소스코드 관리 - Git

  • Repository URL: https://<id>:<passwd>@<repo_address>
  • credentials: none
  • Branch Specifier: */master

2. Build

순서대로 진행할 쉘 스크립트를 작성한다.

1) Execute shell

 docker image prune -a --force
 mkdir -p /var/jenkins_home/images_tar
 cd /var/jenkins_home/workspace/test2/client/
 docker build -t vue-client .
 docker save vue-client > /var/jenkins_home/images_tar/vue-client.tar
 
 cd /var/jenkins_home/workspace/test2/server/
 docker build -t node-server .
 docker save node-server > /var/jenkins_home/images_tar/node-server.tar
 
 ls /var/jenkins_home/images_tar
  • mkdir -p /var/jenkins_home/images_tar: 젠킨스 컨테이너에 images_tar 디렉토리를 생성한다. (없는 경우만)
  • docker save vue-client > /var/jenkins_home/images_tar/vue-client.tar : 도커 이미지를 tar 파일로 백업한다.(도커 이미지를 jenkins 컨테이너 외부에서 확인할수 없어서 이렇게 진행했다)
  • docker build -t vue-client .: 도커 이미지를 빌드한다.
  • docker image prune -a --force: 사용하지 않는 이미지를 삭제한다.

2) Execute shell script on remote host using ssh

  • ssh를 사용해서 원격 접속을 실행한다. jenkins 컨테이너에서 aws 서버로 접속한다.
  • Execute each line 을 체크한다.
 ls /home/ubuntu/jenkins_home/images_tar
 
 sudo docker load < /home/ubuntu/jenkins_home/images_tar/vue-client.tar
 sudo docker load < /home/ubuntu/jenkins_home/images_tar/node-server.tar
 
 if (sudo docker ps | grep "vue-client"); then sudo docker stop vue-client; fi
 if (sudo docker ps | grep "node-server"); then sudo docker stop node-server; fi
 
 sudo docker run -it -d --rm -p 80:80 -p 443:443 --name vue-client vue-client
 echo "Run client"
 sudo docker run -it -d --rm -p 3000:3000  --name node-server node-server
 echo "Run server"
 
 sudo docker ps
  • sudo docker load < /home/ubuntu/jenkins_home/images_tar/vue-client.tar: 백업된 이미지 파일을 호스트에 로드한다(도커 이미지를 jenkins 컨테이너 외부에서 확인할 수 없어서 이렇게 진행했다).
  • if (sudo docker ps | grep "vue-client"); then sudo docker stop vue-client; fi: 실행되고 있는 같은 이름의 컨테이너가 있는 경우 컨테이너를 정지시킨다.(정지할 때 자동으로 제거가 되게 만들었다.)
  • sudo docker run -it -d --rm -p 80:80 -p 443:443 --name vue-client vue-client: 새로운 이미지로 컨테이너를 생성한다.

빌드후 조치

  • Delete workspace when build is done 를 추가해서 자동으로 workspace를 삭제하게 만들었다.

 

더보기

여기까지 진행하면서 발생한 에러들이다.

1. jenkins 컨테이너 내에서 Docker를 찾을수 없는 문제

$ sudo chmod +x /var/run/docker.sock
 $ sudo docker run -d -u root --restart always --name jenkins \\
 -p 8080:8080 -p 50000:50000 \\
 -v $PWD/jenkins_home:/var/jenkins_home \\
 -v /var/run/docker.sock:/var/run/docker.sock \\
 -v /usr/bin/docker:/usr/bin/docker \\
 jenkins/jenkins
  • 우분투 서버에 있는 도커를 젠킨스에 쓸수있도록 포워딩하면 된다.
  • 실행되고 있는 컨테이너는 삭제한 뒤에 위의 명령어로 다시 실행

2. 빌드 할 때 cpu 100%, mem 100% 찍는 문제

  • 메모리가 1GB 밖에 되지 않아서 생기는 문제이다. (네이버 클라우드 서비스의 무료 서버를 사용했는데 생겼다)
  • 스왑공간을 설정해서 사용한다. 
 $ sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
 $ sudo chmod 600 /swapfile
 $ sudo mkswap /swapfile
 $ sudo swapon /swapfile
 $ sudo swapon -s
 
# `/etc/fstab` 파일을 편집하여 부팅 시 스왑 파일을 활성화한다.

$ sudo vi /etc/fstab

# 파일 끝에 다음 줄을 새로 추가하고
# 파일을 저장한 다음 종료합니다.

/swapfile swap swap defaults 0 0

 

3. jenkins no such dsl method 'sshcommand' found among steps

  • ssh 관련한 커맨드를 찾을수 없다는 에러이다. ssh 관련한 패키지? 라이브러리? 를 설치하면 된다.
  • manage jenkins - manage plugins - ssh pipeline steps 설치

 

참고 글