본문 바로가기
Spring Framework/스프링

(1) Jenkins 스프링 무중단 CI/CD 배포 구현 - Jenkins Docker 설치

by 스코리아 2024. 7. 13.
반응형

안녕하세요, 스코리아입니다.

오늘은 Jenkins를 이용한 스프링 무중단 CI/CD 배포, 첫 번째 시간: Jenkins Docker 설치에 대한 포스팅입니다.

 

Jenkins CI/CD 구현을 위해 이틀 동안 밤을 새워가며 정말 많은 문제를 맞닥뜨렸고, 계속 해결해 나갔습니다. Docker 컨테이너/이미지만 4~5번 지웠다가 다시 만들고, 시놀로지 DSM 6에서 7로 업그레이드하는 등, 다양한 부분에서 매우 많은 시간이 소비되었습니다.

여러분들은 저처럼 많이 헤매지 않으시도록 최대한 상세하게 포스팅을 작성하겠습니다.

 

또한 포스팅을 작성하는 2024년 7월 기준, 가장 최신 버전의 Jenkins스프링 3.0 이상(Gradle 8.0 이상), JDK 17을 사용하였습니다. 다른 블로그 포스팅들을 보면 버전이 낮은 상태로 시작하는 경우가 많아, 쉽게 따라 할 수 없는 경우가 많았습니다. 때문에, 저는 가장 최신 버전에서 여러분이 이해하기 쉽도록 설명드리겠습니다.

 

목차

무중단 서비스까지 추가하려다 보니 분량이 조금 되는 관계로, 4개의 포스팅으로 나누어보겠습니다.

 

(1) <현재> Jenkins 소개 및 Docker에 Jenkins 설치

(2) Jenkins에 Github 연동 + credentials 파일(application-prod.yml) 추가 + gradle 설치 : 바로가기

(3) Jenkins 빌드 Item 추가 + Docker, Jenkins 설정 파일 작성 + Nginx 로드밸런싱 설정 : 바로가기

(4) Jenkins와 Slack 연동 : 바로가기

 

서비스 Diagram

Github에 push가 일어나면 -> Jenkins가 Github에서 파일을 내려받고 -> 빌드/테스트를 진행한 후 -> 스프링 Blue 혹은 Green Docker에 배포하여 무중단 배포가 일어나도록 설계하였습니다.

 

또한 사용자가 접속할 때는 Nginx에서 LoadBalancing을 통해 Blue 혹은 Green 중 활성화되어 있는 서버로 연결되게끔 설정하였습니다.

저는 시놀로지(Synology DSM 7)를 사용하고 있어, 'Nginx' 대신 'Nginx Proxy Manager'를 사용하였지만, 둘이 설정방식이 똑같기 때문에 Nginx를 사용하셔도 문제없습니다.

 

아래 그림에 Cloudfront를 앞단으로 넣어 놓았는데, 테스트로만 서비스를 운영하신다면 적용할 필요 없습니다.

Jenkins 스프링 무중단 CI/CD 배포 구현 (Docker) - Diagram

 

CI/CD 의미

예전에는 스프링 부트 빌드를 위해 jar 파일을 만든 후, 서비스 FTP 서버에 올리고, 서비스 터미널에서 java 명령어를 통해 직접 실행하는 방식을 사용하였는데, 이는 보기만 해도 매우 귀찮습니다..!

그리하여 우리는 Github push 클릭 한 번으로 서버에 자동으로 배포되길 원합니다. 이러한 배포 자동화는 매번 일관되게 진행되는 배포 과정을 설계하여, 사람이 수동적으로 배포하는 과정에서 발생하는 실수들을 낮출 수 있습니다.

 

CI/CD 용어와 방식에 대해서 간략히 살펴보겠습니다.

CI Continous Integration (지속적인 통합), CD Continuous Delivery/Deployment(서비스제공, 배포)의 의미를 담고 있습니다.

 

CI/CD

Github Repository에서 push가 일어나면, CI 단계에서는 변경사항이 적용된 새로운 코드를 빌드 및 테스트하는 과정을 거칩니다. 즉, 빌드 및 테스트 단계를 먼저 거쳐서, 새로 적용할 코드에 문제가 없는지 미리 체크하는 용도입니다.

CD 단계에서는 빌드 및 테스트를 진행한 후 서비스를 제공하는 서버에 배포하는 작업을 진행하게 됩니다.

 

대표적인 CI/CD 툴로 Jenkins 및 Github Actions가 존재합니다.

 

Jenkins 소개

Jenkins는 CI/CD를 지원하는 오픈소스 자동화 서버입니다. 개발 과정을 자동화하여 테스트 및 배포과정을 간소화하고 오류를 사전에 잡아줍니다. Jenkins는 CI/CD 툴 중 개발된 지 오래된 편에 속해, 다양한 플러그인과 설정들이 지원되며 많은 기업들이 사용하고 있는 보편적인 툴입니다.

Jenkins 소개

다음과 같은 특징들을 갖고 있습니다.

  • 플러그인으로 확장 가능: Jenkins의 플러그인 개수는 수천 가지를 넘습니다. Git, Docker와 같은 다양한 개발, 테스트, 배포 도구들이 존재합니다.
  • Java 기반 : JDK, Maven, Gradle 등 설정이 용이합니다.
  • 간편한 설정/관리 : 웹 기반의 GUI로 구성되어 있기 때문에 설정 변경과 빌드 관리가 쉽습니다.
  • 알림 : 빌드 상태 결과를 이메일, Slack 등 다양한 수단으로 알림을 받아볼 수 있습니다.

Jenkins는 코드의 변경이 있을 때 빌드, 테스트, 배포하는 모든 자동화 과정을 '파이프라인' 형식으로 정의하고 관리합니다.

파이프라인은 Groovy 혹은 Yaml 언어로 정의되어 있으며(보통 Jenkinsfile라 함), 하나의 파이프라인을 정의하여 여러 프로젝트에서 재사용할 수 있다는 특징이 있습니다.

 

파이프라인의 구성요소는 다음과 같습니다.

  • Stage(스테이지) : 파이프라인의 주요 단계 (빌드, 테스트, 배포 등의 각각의 단계를 설정)
  • Step (스탭) : 각 스테이지 내에서 실행할 작업들 (스크립트, 쉘 실행)

 

Docker에 Jenkins 설치

일반적인 경우 Docker에 Jenkins 이미지를 불러와서 바로 컨테이너를 실행시켜도 되지만, 저희는 같은 서버 내에서 Jenkins를 Docker로 설치하고 스프링 서버를 Docker로 띄울 것이기 때문에 Docker로 띄운 Jenkins 안에서 Docker를 제어해야 하는데, 이를 위해 DOOD(Docker Out Of Docker) 구조 설정이 필요합니다.

 

DinD vs DooD

Docker로 띄운 Jenkins 안에서 호스트(밖에 있는, OS)에 있는 Docker와의 통신이 필요한 상황입니다.

이를 위해서는 /var/run/docker.sock 마운팅이 필요하며, Jenkins 컨테이너 안에 docker-cli, docker-compose 설치해야 합니다.

 

1. Dockerfile 파일 작성하기

jenkins/jenkins:lts 이미지를 가져와서 root 권한으로 설정한 후, docker-ce-cli와 docker-compose를 설치하는 스크립트입니다. 또한 jenkins 계정에 권한도 추가해 줍니다.

FROM jenkins/jenkins:lts
USER root

RUN apt-get update && \
    apt-get -y install apt-transport-https \
      ca-certificates \
      curl \
      gnupg2 \
      software-properties-common

RUN curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \
    add-apt-repository \
      "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
      $(lsb_release -cs) \
      stable"

RUN apt-get update && apt-get -y install docker-ce-cli

RUN curl -L "https://github.com/docker/compose/releases/download/v2.11.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
RUN chmod +x /usr/local/bin/docker-compose

RUN groupadd -f docker
RUN usermod -aG docker jenkins

 

2. Dockerfile 파일을 이용하여 이미지 생성하기

Dockerfile이 있는 디렉터리로 이동하여 아래 명령어를 실행시켜 주세요. jenkins-custom이라는 이름으로 이미지를 만드는 명령어입니다.

서버 사양이 낮으면 이미지 생성까지 많은 시간이 소요됩니다. (저는 20분 정도 소요되었습니다)

docker build -t jenkins-custom .

 

3. docker-compose.yml 파일 만들기

  • image: 방금 만든 이미지 이름 입력
  • container_name: 원하는 컨테이너 이름 입력
  • ports: 저는 이미 8080 포트를 사용하고 있기 때문에, 8080(웹 GUI 포트)를 9060으로 매핑하였습니다.
  • environment: 'JAVA_OPS=-Xmx1g' 설정을 통해 최소 1GB의 RAM을 사용하도록 설정하여, 추후 빌드시 렉이 걸리지 않도록 하였습니다.
  • volumes: '/var/run/docker.sock:/var/run/docker.sock'을 통해 호스트의 Docker와 소통할 수 있도록 하였고, '/volume1/docker/jenkins:/var/jenkins_home'을 통해 Jenkins 홈 디렉터리를 '/volume1/docker/jenkins'로 매핑하였습니다. 여러분들이 원하는 디렉터리로 설정 바랍니다.
  • restart: 꺼지면 항상 재시작하도록 설정하였습니다.
version: "3"
services:
  jenkins:
    image: jenkins-custom
    container_name: jenkins-main
    user: root
    ports:
      - "9060:8080"
      - "50000:50000"
    environment:
      - JAVA_OPS=-Xmx1g
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /volume1/docker/jenkins:/var/jenkins_home
    restart: always

 

4. docker-compose 실행

방금 만든 docker-compose.yml 파일을 실행해 보겠습니다. docker-compose.yml 파일이 있는 디렉터리로 이동하여 아래 명령어를 실행시켜 주세요.

docker-compose up -d

 

-d 옵션은 Backgroud 실행을 뜻합니다.

 

5. 웹 GUI 접속하기

'http://로컬(서버)주소:도커매핑포트'로 접속합니다. 저 같은 경우는 'http://172.30.1.10:9060'입니다.

Jenkins 설치 후 웹 GUI 접속

위와 같은 화면이 뜨시면 성공하신 겁니다.

 

6. Administrator password 찾는 방법

현재 Jenkins 컨테이너 이름이 'jenkins-main'입니다. 해당 컨테이너의 로그를 확인해 보겠습니다.

docker logs jenkins-main

 

아래와 같이 콘솔에 jenkins 비밀번호를 확인하실 수 있을 겁니다.

*************************************************************
*************************************************************
*************************************************************

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

[____________password____________]

This may also be found at: /var/jenkins_home/secrets/initialAdminPassword

*************************************************************
*************************************************************
*************************************************************

 

이제 이 비밀번호를 웹 화면에 입력해 주세요.

 

7. 기타 설정들

그다음단계는 Install suggested plugins (초기 플러그인 모두 설치)를 누르시고 모든 플러그인이 다운로드되면 계정을 설정해 주시면 됩니다. 어려운 것이 없기 때문에 스킵하도록 하겠습니다!

 

 


다음 포스팅에서는 'Jenkins, Github 연동 방법'에 대해서 자세히 다뤄보겠습니다.

읽어주셔서, 감사합니다.

 

다음글 바로가기 >

반응형