DevOps/CI CD

Runner CI/CD 구성하기

journalctl 2025. 1. 12. 16:08

개요

투자에 실패한 나의 모습. 돈과 시간 모두 소비해버렸다..

 

GitLab에 IaC 코드와 개발했던 소스 코드를 업로드했다. 레포지토리 별로 gitlab-ci.yml 파일을 작성해봐야겠다.

  • GitLab Group 구성정보
    • grpc-auth (auth_service 소스코드)
    • grpc-board (board_service 소스코드)
    • grpc-gateway (gateway 소스코드)
    • grpc-helm (gateway, auth, board Helm Chart가 담겨져있는 레포지토리)
    • grpc-proto (proto 파일이 담겨져있는 레포지토리)

GitLab Runner 구성하기

필요한 구성 정보 만들기

  1. GitLab - Group Access Token 발급

GitLab Group → Settings - Access Tokens → Create Group Access Token

 

  1. ArgoCD - Repository 연결하기

ArgoCD Settings → Repositories → Connect Repo

  1. GitLab - CI/CD Variables 설정

GitLab Admin Area → Settings - CI/CD → Variables

 

공통으로 사용되는 HARBOR 정보는 변수로 추가하기.

Gitlab-ci.yml 작성하기

아래 블로그에서 gitlab-ci.yml 정리가 잘 되어있어서 작성할때 참고하기!

https://bravenamme.github.io/2020/11/09/gitlab-runner/

1.1. Stage 나누기

먼저 Stage를 나눠서 생각해봐야겠다. 총 3단계로 구분지어서 작성할 예정인데 preset, build, deploy로 구성할 예정이다.

  • preset : proto가 담긴 레포지토리를 clone 단계
  • build : proto 파일을 빌드하고 kaniko를 이용해서 container image 빌드 후 harbor에 업로드
  • deploy : ArgoCD가 감지할 수 있도록 helm 차트가 담긴 레포지토리를 clone 후 values.yaml에 이미지 태그 변경

1.2. Stage별 Job 나누기

각 Stage에서 Job을 구성해보자. (preset 부분에서 proto, git clone job을 나눠서 해야겠다.)

  • preset : git_clone, proto_build
  • build : image_build
  • deploy : deploy_argocd

1.3. Job Script 제작하기

먼저 preset에 들어갈 간단한 git_clone 만들기

git_clone:
  stage: preset
  image:
    name: bitnami/git:latest
  script:
    - git clone https://journalctl:그룹토큰그룹토큰@gitlab.journalctl-xe.com/grpc-test/grpc-proto.git --branch dev
    - ls -lh
  artifacts: # proto_build에 사용할 수 있도록 artifact로 저장해서 다음 job에서 다운로드 받을 수 있게 설정
    paths:
      - grpc-proto/
    expire_in : 1 hour
  tags:
    - test

proto 빌드에 사용하는 job 만들기

proto_build:
  stage: preset
  needs: ["git_clone"] # git_clone이 수행된 이후 proto_build 수행하도록 설정.
  image:
    name: harbor.journalctl-xe.com/library/python:grpcio-3.9.6
  artifacts: # proto 컴파일 후 나온 파일들 image build시 포함될 수 있도록 artifact로 저장
    paths:
      - output/
    expire_in: 1 hour
  script:
    - mkdir output
    - python3 -m grpc_tools.protoc -I./grpc-proto/proto --python_out=./output --grpc_python_out=./output ./grpc-proto/proto/*
    - ls -lh
  tags:
    - test

kaniko로 이미지 빌드 후 harbor에 푸시하는 job 만들기

image_build:
  stage: build
  # before_script로 Kaniko에서 사용할 Harbor 인증정보 담기
  before_script: 
    - mkdir -p /kaniko/.docker
    - echo "{\"auths\":{\"$HARBOR_URL\":{\"username\":\"$HARBOR_USERNAME\",\"password\":\"$HARBOR_PASSWORD\"}}}" > /kaniko/.docker/config.json
    - cat /kaniko/.docker/config.json
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  artifacts:
    paths:
      - output/
  script:
    - echo "Building the app"
    - cp ./output/*.py ./
    # $CI로 시작하는 변수는 GitLab Runner에서 전역으로 사용가능한 변수
    - /kaniko/executor --context dir://$CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $HARBOR_URL/library/$CI_PROJECT_PATH:$CI_COMMIT_SHORT_SHA
  tags:
    - test

ArgoCD가 감지할 수 있도록 이미지 태그 변경하는 job 만들기

deploy_argocd:
  stage: deploy
  image:
    name: alpine:latest
  before_script:
    - apk add --no-cache git curl jq yq
  script:
    - git clone https://journalctl:그룹토큰그룹토큰@gitlab.journalctl-xe.com/grpc-test/grpc-helm.git --branch dev
    - yq -i ".image.tag = \"$CI_COMMIT_SHORT_SHA\"" ./grpc-helm/$CI_PROJECT_NAME/values.yaml
    - git config --global user.email "dltkdrnd123@gmail.com"
    - git config --global user.name "journalctl"
    - cd grpc-helm
    - git status
    - git add $CI_PROJECT_NAME/values.yaml
    # Runner CI에서 ':' escape 방법으로 > 후에 작성한다.
    - >
        git commit -m "UPDATE :: $CI_PROJECT_NAME - values.yaml"
    - git push origin dev
  # only 태그 사용해서 dev 브랜치에서만 작업할 수 있도록 강제할 수 있다.
  only:
    - dev
  tags:
    - test

1.4. 완성된 전체 스크립트

#variables:
#  CI_DEBUG_TRACE: "true"

stages:
  - preset
  - build
  - deploy

git_clone:
  stage: preset
  image:
    name: bitnami/git:latest
  script:
    - git clone https://journalctl:glpat-M2kxL54mt7pHxg_h2kGo@gitlab.journalctl-xe.com/grpc-test/grpc-proto.git --branch dev
    - ls -lh
  artifacts:
    paths:
      - grpc-proto/
    expire_in : 1 hour
  tags:
    - test

proto_build:
  stage: preset
  needs: ["git_clone"]
  image:
    name: harbor.journalctl-xe.com/library/python:grpcio-3.9.6
  artifacts:
    paths:
      - output/
    expire_in: 1 hour
  script:
    - mkdir output
    - python3 -m grpc_tools.protoc -I./grpc-proto/proto --python_out=./output --grpc_python_out=./output ./grpc-proto/proto/*
    - ls -lh
  tags:
    - test

image_build:
  stage: build
  needs: ["proto_build"]
  before_script:
    # Setting to Kaniko
    - mkdir -p /kaniko/.docker
    - echo "{\"auths\":{\"$HARBOR_URL\":{\"username\":\"$HARBOR_USERNAME\",\"password\":\"$HARBOR_PASSWORD\"}}}" > /kaniko/.docker/config.json
    - cat /kaniko/.docker/config.json
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  artifacts:
    paths:
      - output/
  script:
    - echo "Building the app"
    - cp ./output/*.py ./
    - /kaniko/executor --context dir://$CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $HARBOR_URL/library/$CI_PROJECT_PATH:$CI_COMMIT_SHORT_SHA
  tags:
    - test

deploy_argocd:
  stage: deploy
  image:
    name: alpine:latest
  before_script:
    - apk add --no-cache git curl jq yq
  script:
    - git clone https://journalctl:glpat-M2kxL54mt7pHxg_h2kGo@gitlab.journalctl-xe.com/grpc-test/grpc-helm.git --branch dev
    - yq -i ".image.tag = \"$CI_COMMIT_SHORT_SHA\"" ./grpc-helm/$CI_PROJECT_NAME/values.yaml
    - git config --global user.email "dltkdrnd123@gmail.com"
    - git config --global user.name "journalctl"
    - cd grpc-helm
    - git status
    - git add $CI_PROJECT_NAME/values.yaml
    - >
        git commit -m "UPDATE :: $CI_PROJECT_NAME - values.yaml"
    #- git commit -m *commit_message
    - git push origin dev
  only:
    - dev
  tags:
    - test

GitLab Runner로 CI 해보기

GitLab에서 레포지토리 최상단에 .gitlab-ci.yml 파일이 있을경우 감지하여 Runner가 해당 파일을 참조하여 동작하게 된다.

GitLab Runner 페이지

GitLab Runner - 간단한 gitlab-ci.yml 파일인데 계속 오류가 발생해서 57번 수정하고 돌렸다. 대단하다!

 

Harbor 페이지

Harbor - Short Commit SHA 태그로 이미지 Push는 정상적으로 업로드 되었다.

 

ArgoCD 페이지

ArgoCD - VKE 클러스터에 잘 배포되었다.

 

Kubernetes

$ kubectl get po -n grpc
NAME                            READY   STATUS    RESTARTS   AGE
grpc-auth-695f47b49f-ct5nf      1/1     Running   0          36h
grpc-board-5cd78b5c5-v95xx      1/1     Running   0          36h
grpc-gateway-6f57c46947-hx9ht   1/1     Running   0          36h

후기

기존 CI 툴로 Jenkins를 주로 사용했었는데 Runner와 비교해서 내가 느끼는 장단점은 확실한 것 같다.

  1. Jenkins는 Groovy 문법을 사용하는데 Runner는 Yaml 형식으로 작성할 수 있어서 개인적으로 Runner가 편했다.
  2. Jenkins는 다양한 플러그인이 지원해서 원하는 기능을 찾아서 설치하면 되지만 Runner는 상대적으로 부족하다
  3. GitLab을 사용하면 Jenkins, Runner 둘 다 사용가능하지만 독립적인 CI로 Runner는 불가능하다.
  4. Jenkins를 Kubernetes에서 사용할때 Agent Pod Template 형태로 여러 이미지를 스크립트 실행 시 사용할 수 있는데 Runner는 각 Job별로 하나의 이미지만 사용가능해서 조금 아쉬웠다.
  5. job별로 pod가 생성되고 삭제되는데 여러 job이 수행되는경우 꽤나 시간이 오래걸린다. log도 pipeline 전체 로그를 한번에 확인하고 싶은데 job별로 로그 확인해야해서 불편함이 있었다. (이건 많이 사용해보지 않아서 Runner에서 해당 기능을 제공하는지 찾아봐야겠다.)

정리하면 소규모 프로젝트나 GitLab을 사용하는 기업이라면 Runner도 괜찮을 것 같다. 하지만 Jenkins가 범용적인 부분에서 더 좋은 것 같다.

너무 늦게까지 작업해서 내일은 이 모습일 것 같다..