GitLab & Jenkins를 활용한 CI/CD 파이프라인 구축 (3편 : CI/CD 파이프라인)

steve·2024년 3월 11일
0

DevOps

목록 보기
3/8

개요

  • 아래 사진과 같이 private GitLab 저장소와 Jenkins를 활용한 CI/CD 파이프라인을 구축한다

CI/CD 파이프라인 구축을 위한 Git Repository 생성하기

  1. Config Repository 생성
    • Jenkins workspace에서 사용할 환경 설정 파일들을 배포하기 위한 “Config” Repository 저장하기
  2. API Repository 생성
    1. Java, Node 등 서버 사이드 프로젝트 생성

Jenkins 파이프라인 구성 1 - Config Repository 배포

  1. Jenkins의 config 파이프라인 생성 및 설정
    • Configuration → Build Triggers의 Build when a change is pushed to GitLab 에 체크
    • 하단 Advanced를 확장시켜 Secret token 생성
      • 추후 GitLab Webhook에서 사용될 토큰이므로 클립보드에 복사해둔다
    • Pipeline 정의
      • 아래와 같이 SCM, Repositories 정보를 입력

  2. GitLab Webhook 설정
    1. local network 를 사용하는 경우 web hook 사용 설정 필요
      • root 계정 로그인 → Settings → Network에서 아래 체크박스 확인
    2. Webhoooks 생성
      • Git Repository 이동 후 Setting → Webhooks
        • URL : Jenkins 파이프라인 Configure 진입 시 보이는 Build Triggers URL 입력
        • Secret token : Jenkins 파이프라인 생성 시 생성한 Secret token 입력 (Jenkins pipeline 생성 과정에서 클립보드에 복사해뒀던 token)
        • Trigger : 해당하는 이벤트 발생 조건에 체크
          • 기본 main 브랜치를 사용하므로 main으로 기재하였음
      • 파이프라인 테스트
        1. 저장해둔 Git Repository에서 code를 push하여 성공 확인

          2. Jenkins Docker container에 진입하여 Jenkins workspace에 Git Repository 파일을 잘 가져왔는지 확인

Jenkins 파이프라인 구성 2 - API Repository 배포

  1. Jenkins에 파이프라인 생성
    • 파이프라인 명 : DEV_nest-msa
    • Configuration → Build Triggers의 Build when a change is pushed to GitLab 에 체크
    • 파이프라인 스크립트 설명
      1. 저장한 Credential을 통해 GitLab에 접근하여 git url의 dev branch 소스코드를 가져온다

      2. config 저장소에서 배포된 파일들을 copy

      3. Dockerfile로 이미지를 빌드하여 로컬 네트워크 192.168.10.100의 Container Registry (Port 5000)로 이미지를 push

      4. 배포 스크립트를 실행

        pipeline {
            agent any
            stages {
                stage('Sync Source') {
                    steps {
                        script {
                            echo '####################### Sync Source #######################'
                            git url: 'http://192.168.10.200:5001/dobecom/nest-msa.git', branch: 'dev', credentialsId: 'GitLab-Credential'
                            sh "cp -rf ../config/nest-msa/.env.dev ./.env"
                            sh 'cp -rf ../config/nest-msa/Dockerfile.dev ./Dockerfile'
                        }
                    }
                }
                stage('Docker Build & Push') {
                    steps {
                        echo '####################### Docker Build & Push #######################'
                        sh 'sudo docker build -f Dockerfile -t 192.168.10.100:5000/nest-msa:dev .'
                        sh 'sudo docker push 192.168.10.100:5000/nest-msa:dev'
                        sh 'ssh -i ../key.pem ubuntu@192.168.10.100 /home/ubuntu/deploy/nest-msa.sh'
                    }
                }
            }
        }
  2. GitLab에서 Webhook 연결 (dev branch)

배포 준비

  1. Jenkins 서버에 Docker Engine 설치
  • Jenkins Container 내부에서 pipeline을 통해 Docker 명령어를 실행하기 위해 Docker Engine을 설치해야 한다
  • Jenkins Container에 root 권한으로 진입
    • docker exec -it --user root 34954743a64b /bin/bash
      • apt update
      • apt install sudo
      • jenkins user에 sudo 사용 처리를 위해 sudoers 파일에 NOPASSWD 설정
        • vi /etc/sudoers

          # User privilege specification
          root    ALL=(ALL:ALL) ALL
          **jenkins ALL=(ALL) NOPASSWD:ALL**
  • 아래의 공식 Docker Engine 설치 과정 진행
  1. Container를 배포 할 HOST 서버에 Docker Container Registry 설치하기
  • docker pull registry:3.0.0-alpha.1
  • docker run -itd --restart unless-stopped --name do-registry -p 5000:5000 -v /home/dobecom/Docker/registry:/tmp/registry registry:3.0.0-alpha.1
  • Host 서버에서 docker local 저장소를 사용하기 위한 값 적용
    • sudo vi /etc/docker/daemon.json

      {
          "insecure-registries": ["192.168.10.100:5000"]
      }
  1. 배포 스크립트 작성 및 HOST_DEV - 2 서버에 저장
  • 배포 스크립트 작성 (nest-msa.sh)
#!/bin/bash
sudo docker pull 192.168.10.200:5000/nest-msa:dev
sudo docker rm -f nest-msa
sudo docker run -itd --restart unless-stopped -v /home/ubuntu/logs:/log --name nest-msa -p 3001:3000 192.168.10.200:5000/nest-msa:dev
sudo docker image prune -af
  • 저장 경로 : /home/ubuntu/deploy/nest-msa.sh
  1. Config Repository의 Dockerfile 작성
    • Docker Container Registry로 push된 이미지를 사용함
## Dockerfile.dev
FROM 192.168.10.200:5000/nest-msa:dev AS base

FROM base AS runner
WORKDIR /app

USER node

COPY --from=base --chown=node:node /app/dist ./dist
COPY --from=base --chown=node:node /app/node_modules ./node_modules

EXPOSE 3001

ENV PORT 3000

CMD ["node", "dist/main.js"]
  • 최초 Container Image 빌드를 위한 Dockerfile 작성
## Dockerfile.init
FROM node:18-alpine AS base

FROM base AS deps

RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN \
  if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
  elif [ -f package-lock.json ]; then npm ci; \
  elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
  else echo "Lockfile not found." && exit 1; \
  fi

FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ARG SERVICE
RUN npm run build $SERVICE
  1. 최초 Container Image 빌드

    • 소스 코드 push 전, 이미지 초기화 작업 필요
    • Jenkins workspace DEV_nest-msa 진입하여 아래 명령어 실행
      • sudo cp ../config/nest-msa/Dockerfile.init .
      • sudo docker build -f Dockerfile.init -t 192.168.10.200:5000/nest-msa:dev .
  2. API Repository 배포 테스트

    • DEV_nest-msa 코드 푸시
    • GitLab WebHook 동작 확인 및 파이프라인 실행 성공 확인
    • HOST를 구분하지 않고 All-In-One HOST로 구성한 결과
  • 실습 방식에 따라 All-In-One 서버로 구성할 수도 있고, 해당 포스팅의 구성도 사진처럼 HOST를 분리한 환경에서도 가능하다

0개의 댓글