DevOps/CI CD

[CI/CD] GitLab CI/CD 구축 (with. Gitlab Runner)

kmindev 2024. 4. 24. 10:16

1. 개요

CI/CD 환경이 구축되어 있지 않다면 애플리케이션 변경 사항이 발생할 때 매번 로컬에서 빌드하고, 빌드된 jar 파일 config 등을 직접 서버에 SFTP로 개발/운영 다수의 서버에 배포를 해야한다.(배포할 때마다 신경 쓸 것이 많다......)  

 

2. CI/CD 란?

a. CI(Continuous Integration) - 지속적 통합

요즘은 개발자가 소스코드를 Git으로 관리하고, GitHub나 Gitlab과 같은 원격 저장소를 통해 여러 개발자들과 소스코드를 공유하고 있다. 

 

원격 저장소에 공용으로 사용하는 Repository를 생성하고, 각 개인은 브랜치를 생성하여 작업한다. 이를 통해 여러 개발자가 병렬적으로 작업할 수 있으며, 작업한 코드는 충분한 테스트와 코드리뷰를 통해 통합브랜치(예: main)에 merge 하여 소스코드를 통합한다.

 

CI란 병렬적으로 작업한 새로운 소스 코드에 대해 자동으로 빌드 -> 테스트를 통해 검증한 뒤 코드 검증이 끝나면, 변경사항을 공유 레포지토리에 통합하는 것을 의미한다.  

 

CI를 도입함으로써, 소스코드의 품질을 유지하고, 여러 개발자들이 협업하는 과정에서 생길 수 있는 오류를 최소화 하는데 도움 되고, 개발자들은 안정적이고 신뢰할 수 있는 애플리케이션을 빠르게 제공할 수 있다.  

 

 

1. 각 브랜치 별로 새로운 코드에 대해서 commit & push를 진행

2. 미리 구축되어 있는 ci pipline을 통해 빌드 - 테스트 등 작업을 자동으로 진행

3. 빌드 - 테스트가 성공적으로 끝나면 review를 통해 소스 검증 뒤 승인되면 통합 branch에 통합 

 

 

b. CD(Continous Deliver | Continuous Deployemnt) - 지속적 제공(배포) 

변경된 서비스를 실제 사용자 환경(production)에 제공해야 한다.

  

Continuous Delivery는 소프트웨어를 지속적으로 릴리스할 수 있는 프로세스를 의미한다. 

Continuous Deployment는 Continuous Delivery의 한 유형으로, 테스트 및 검증이 완료된 모든 변경사항이 자동으로 production 환경에 배포되는 것을 의미한다.

 

위 ci/cd 파이프라인은 단순 예시일 뿐이며 회사 업무 스타일 상황 등을 고려하여 커스텀하게 구성해야 한다.

 

실제 서비스를 제공해야 할 브랜치를 main으로 가정하자.

 

1. ci를 적용하여 코드를 검증

2. production 환경에 배포하기 전 production 환경과 유사한 staging 환경해서 검증

3. 검증된 서비스를 실제 production 환경에 배포 

 

CI/CD를 적용하면 빌드 - 테스트 배포 과정이 자동화 되어 있기 때문에 개발자는 배포보다 개발에 더욱 신경쓸 수 있다.

 

요즘 jenkins, github action, gitlab ci/cd 등 다양한 도구를 제공하지만, 사내에서 gitlab을 on-premise 로 사용하고 있기 때문에 gitlab ci/cd 를 활용하여 ci/cd 를 구축하기로 결정했다. (gitlab과 jenkins 연동해서 사용 가능하다.) 

 

3. Gitlab CI CD

Gitlab CI/CD 구성

  • brach에 변경사항이 발생하면 조건에 맞는 파이프라인의 jop을 단계적으로 수행한다.
  • 각 지정된 jop(빌드, 테스트 배포 등)은 runner에서 실행되는데, runner 환경을 커스텀하게 지정할 수 있다.
    • runner 환경은 docker, shell, window powershell 등 다양하게 지정할 수 있다.
    • runner를 도커환경으로 구성하면, 서로의 jop에 영향을 주지 않기 때문에 각 jop을 독립적으로 실행할 수 있다.

 

Gitlab에서는 기본적으로 ci cd 기능을 제공해준다. ci/cd 기능을 활용하기 전에는 두가지를 세팅해줘야 한다. 

  1. pipline에서 각 jop을 실행할 수 있는 runner를 등록 및 설정해야 한다.
  2. gitlab.ci.yml 파일을 작성하여 pipline을 구성한다.  

 

a. Gitlab-Runner 설치 및 등록

gitlab runner를 등록할 때, 인스턴스 러너, 그룹 러너, 프로젝트 러너가 있다.

 

인스턴스 러너: 같은 gitlab 인스턴스 내의 모든 프로젝트에서 사용 가능(admin 권한이 있으면 등록 가능)

그룹 러너: 그룹의 모든 프로젝트에서 사용 가능(그룹 내에서 등록)

프로젝트 러너: 해당 프로젝트에서만 사용 가능.(프로젝트 소유자 및 권한 있으면 등록)

 

러너를 등록할 때 registration token만 있으면 된다. 프로젝트 러너를 등록해보자. 

gitlab-runner를 도커로 띄울 것이다.

 

1. gitlab-runner 도커 이미지 설치

docker pull gitlab/gitlab-runner:alpine3.12-v14.10.0

 

2. 컨테이너 실행

docker run -d 
--name gitlab-runner 
--restart always 
-v /srv/gitlab-runner/config:/etc/gitlab-runner 
-v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:alpine3.12-v14.10.0

 

3. gitlab-runner 컨테이너 접속

docker exec -it gitlab-runner bash

 

4. runner 등록 시 필요한 url, token 확인

  • project - settings - CI/CD - Runners 확장 버튼을 클릭하면 다음과 같은 화면이 나온다.
  • URL과 Token은 gitlab-runner를 등록할 때 사용된다.

 

5. gitlab-runner 등록

  • gtilab-runner 컨테이너로 돌아가서 runner를 등록해보자.
gitlab-runner register

 

위 명령어를 입력하면 runner에 대한 설정 정보를 입력하라고 나올 것이다.

Enter the GitLab instance URL (for example, https://gitlab.com/):
http://{gitlab_instance_url}/  # url 복붙

Enter the registration token:
{your_registration_token}  # token 복붙

Enter a description for the runner:
[83d843891392]: {runner 설명}  # runner에 대한 설명

Enter tags for the runner (comma-separated): 
{tag1}, {tag2}  # tag 입력(여기서 입력한 tag는 파이프라인을 구성할 때 필요함)

Enter optional maintenance note for the runner:
{추가적인 설명}   #  runner에 대한 부가적인 설명 입력(필수 X)

Registering runner... succeeded                     runner=GR1348941nbsLun54
Enter an executor: custom, docker, shell, virtualbox, docker-ssh+machine, docker-ssh, parallels, ssh, docker+machine, kuberne                                                                                                                                                                 tes:
docker   # Runner 실행환경 구성 (필자는 docker 선택)

Enter the default Docker image (for example, ruby:2.7):
maven:3.8.6-openjdk-11-slim  # 사용할 docker image를 선택(하나만 선택 가능)

참고) https://hub.docker.com/ 도커 hub로 이동해서 필요한 이미지 tag를 붙혀서 입력해주면 된다.

 

6. runner 확인

  • config.toml 에 runner 설정 정보들이 들어있다.
  • more /etc/gitlab-runner/config.toml 입력해서 확인해보자.
  • 여기서 편집해서 설정 정보를 변경하는 것도 가능하다.
[[runners]]
  name = "maven jdk8"
  url = "http://{gitlab_instance_url}/"
  token = "{your_registration_token}"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "maven:3.8.6-openjdk-11-slim"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    shm_size = 0

 

b. piplien(파이프라인) 구성

gitlab-ci.yml 파일을 추가해서 파이프라인을 구성해보자.

gitlab.ci.yml 문법이나 작성 가이드를 보고 싶으면 공식문서에서 확인 가능하다.

https://docs.gitlab.com/ee/ci/yaml/index.html

 

CI/CD YAML syntax reference | GitLab

GitLab product documentation.

docs.gitlab.com

 

gitlab-ci.yml 예시

  • 파이프라인 구성에 따라 특정 조건에 jop을 실행하거나 상황에 따라 얼마든지 커스텀하게 구성해서 사용할 수 있다.
stages:
  - build
  - test
  - dev_deploy
  - oper_deploy

variables:
  # 사용할 변수 설정
  DEV_SERVICE_URL: google.com # 예시
  OPER_SERVICE_URL: naver.com # 예시

job_build:
  stage: build
  tags:
    - mavenjdk8
  script:
    - echo "빌드 작업을 시작합니다."
    - mvn clean package
  artifacts: # 성공시 작업에 연결할 파일 및 디렉토리 목록
    name: ${CI_COMMIT_SHA}
    expire_in: 1 days
    paths:
      - target/*.jar
 
job_test:
  stage: test
  tags:
    - mavenjdk8
  script:
    - echo "테스트 작업을 시작합니다."
    - mvn test

job_dev_deploy:
  stage: dev_deploy
  tags:
    - deploy-tag
  script:
    - echo "개발 배포 작업을 시작합니다."
    # 개발 배포 스크립트 추가 작성
  environment:
    name: dev
    url: https://${DEV_SERVICE_URL} # 위 variables 선언한 환경 변수 사용
  dependencies:
    - job_build
  only:
    - main

job_oper_deploy:
  stage: oper_deploy
  tags:
    - deploy-tag
  script:
    - echo "운영 배포 작업을 시작합니다."
    # 운영 배포 스크립트 추가 작성
   environment:
    name: oper
    url: https://${OPER_SERVICE_URL} # 위 variables 선언한 환경 변수 사용
  dependencies:
    - job_build
  only:
    - main

 

환경 변수 설정

gitlab-ci.yml 파일 내에서 환경변수를 선언 해서 사용할 수 있다. 하지만 민감정보는 노출될 위험이 있으므로 project - settings - CI/CD - Variables에서 환경 변수를 설정할 수 있다.

 

환경 변수도 gitlab-runner와 마찬가지로, gitlab 인스턴스 / 그룹 / 프로젝트 공유 가능하도록 설정할 수 있다.

그리고 위 예제에서 사용한  ${CI_COMMIT_SHA}와 같이 gitlab에서 기본적으로 제공하는 환경변수들이 몇 개 있다.   

 

 

4. 결과

위 파이프라인을 구성한 뒤, 브랜치에 변경사항이 발생하면 build -> test -> dev_deploy -> oper_deploy 작업을 자동으로 진행한다.

 

project - CI/CD - Piplines로 이동하면 파이프라인 실행과정을 확인할 수 있다.

 

build

오른쪽 화면에는 artifacts로 저장된 파일들을 확인 및 다운로드 할 수 있다.

artifacts로 저장된 파일들은 다음 jop에서 사용할 수 있도록  자동으로 다운로드 된다. 

 

test

  • 빌드가 끝나면 테스트 작업을 진행한다.
  • 로그를 보면 build에서 수행된 결과물인 artifacts로 저장된 파일들을 test jop을 수행하는 runner에서 자동으로 다운로드 한다.

 

 

dev_deploy

  • test가 끝나고 개발 배포를 진행한다.

 

oper_deploy

  • 개발 배포 작업이 끝나면 운영 배포를 진행한다.