Git

주먹구구식 Gradle 빌드/배포 자동화 (Gitlab-runner, ArgoCD)

황동리 2024. 8. 13. 14:02
반응형

앞서 진행했던 Gradle 빌드 참고해주세요.

 

2024.07.25 - [Git] - Gitlab-runner 사용해서 Gradle 빌드 해보기

 

Gitlab-runner 사용해서 Gradle 빌드 해보기

이번엔 Gitlab-runner 사용해서 Gradle 빌드 해보겠습니다.1. Gitlab Project에 build 할 때 필요한 파일 업로드저 같은 경우에는 Gitlab에서 Project를 하나 생성을 한 후에 빌드에 필요한 파일들을 모두 올려두

ksh-cloud.tistory.com

 


docker_build 단계

Gradle 빌드를 완료하면,

해당 jar 파일 가지고 이미지 빌드를 해준 후에 Harbor 레지스트리에 push 해줍니다.

우선 Dockerfile의 내용을 변수로 생성해줍니다.
(GitLab Project -> Setting -> CI/CD -> Variables)

$DOCKERFILE_CONTENT

# Use the official OpenJDK image from the Docker Hub
FROM openjdk:17-jdk-alpine

# Set the working directory inside the container
WORKDIR /app

# Copy the JAR file from the host to the container
COPY sbb-0.0.1-SNAPSHOT.jar /app/sbb-0.0.1-SNAPSHOT.jar

# Expose the port your application runs on
EXPOSE 8080

# Define the command to run the JAR file
ENTRYPOINT ["java", "-jar", "/app/sbb-0.0.1-SNAPSHOT.jar"]

 

그리고 이제 .gitlab-ci.yml에서 docker_build 단계를 작성해줍니다.

docker_build:
  stage: docker_build
  before_script:
    - mkdir -p ~/.ssh
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - ssh-keyscan 10.10.92.31 >> ~/.ssh/known_hosts
    - GRADLE_USER_HOME="$(pwd)/.gradle"
    - export GRADLE_USER_HOME
  image: docker:latest
  services:
    - docker:dind
  script: 
    - ssh root@10.10.92.31 "cd /root/jar/ && echo '$DOCKERFILE_CONTENT' > Dockerfile"
    - ssh root@10.10.92.31 "cd /root/jar/ && docker build -t harbor2.smrc.klab-a/ksh_was/gradle:$CI_PIPELINE_ID ." 
    - ssh root@10.10.92.31 "docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY"
    - ssh root@10.10.92.31 "docker push harbor2.smrc.klab-a/ksh_was/gradle:$CI_PIPELINE_ID"

 

설명

  1. before_script에서 실행하는 내용들은 10.10.92.31 서버와 ssh 통신하기 위함
  2. script에 적힌 내용을 해석해보자면, 10.10.92.31 서버의 /root/jar 디렉터리에 위에서 변수로 생성한 내용으로 Dockerfile을 생성
  3. harbor에 올릴 수 있도록 이미지 빌드 후 harbor에 push, 여기서 tag 값은 Pipeline의 ID 값이 들어가도록 설정

create_yaml 단계

이 단계에서는 쿠버네티스에서 사용할 deployment와 service를 정의 해줍니다.

create_yaml:
  stage: create_yaml
  script:
    - echo "Creating gradle.yaml file with pipeline ID..."
    - |
      cat <<EOF > gradle.yaml
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: gradle
        labels:
          app: gradle
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: gradle
        template:
          metadata:
            labels:
              app: gradle
          spec:
            containers:
            - name: gradle
              image: harbor2.smrc.klab-a/ksh_was/gradle:$CI_PIPELINE_ID
              ports:
              - containerPort: 8080
                protocol: TCP
      ---
      apiVersion: v1
      kind: Service
      metadata:
        labels:
          app: gradle
        name: gradle
      spec:
        ports:
        - port: 8080
          protocol: TCP
          targetPort: 8080
        selector:
          app: gradle
        type: LoadBalancer
      EOF
  artifacts:
    paths:
      - gradle.yaml

 

설명

  1. gradle.yaml 파일을 위와 같은 내용으로 생성해줍니다.
  2. containers에서 사용하는 이미지의 태그 값을 Pipeline의 ID 값이 되도록 설정 해줍니다.

Commit_and_Push 단계

이 단계에서는 위에서 생성한 gradle.yaml 파일을 저의 GitLab-Project에 Push 해줍니다.

왜냐하면, 모든 단계에서 실행하는 환경은 gradle:alpine 이미지 내부에서 진행이 되기 때문 입니다. (docker_build 단계 제외)

commit_and_push:
  stage: commit_and_push
  script:
  # 전역(Global)으로 Git 사용자 이메일 설정
    - git config --global user.email "<Gitlab에 등록한 이메일>"
  # 전역(Global)으로 Git 사용자 이름 설정
    - git config --global user.name "<Gitlab에서 사용하는 사용자명>"
  # SSL 인증서 검증 비활성화
    - git config --global http.sslVerify false
  # 기존 리모트 저장소 제거 (혹시 cache에 남아있는 것을 방지)
    - git remote remove origin
  # 새로운 리모트 저장소 추가
    - git remote add origin https://<Gitlab에서 사용하는 사용자명>:<Token 값>@<Gitlab_project의 https 주소>
  # 원격 저장소에서 메인 브랜치 가져오기, 원격 <-> 로컬 리포지토리간 동기화
    - git fetch origin main
  # 로컬 저장소의 main 브랜치로 전환
    - git checkout main
  # 변경사항 임시 저장, 다른 작업을 수행하기 전에 로컬 변경사항을 안전하게 보관할 때 사용
    - git stash
  # 원격 저장소의 main 브랜치에서 변경사항을 가져와 로컬 main 브랜치에 병합
  # --rebase 옵션을 사용하여 병합 시 커밋 이력 정리, 이는 충돌 최소화하기 위함
    - git pull origin main --rebase
  # 임시 저정한 변경사항 복원
    - git stash pop
  # 파일 추가
    - git add gradle.yaml
  # git commit
    - git commit -m "Update gradle.yaml with pipeline ID $CI_PIPELINE_ID [ci skip]"
  # 원격 저장소에 푸시
    - git push origin main
  dependencies:
    - create_yaml

 

설명

  1. gradle:alpine 이미지에서 작업하다보면 cache가 남을 때가 있어서 코드 통합을 해주어야 합니다.
  2. 파이프라인은 git push 될 때마다 동작을 하는데, git commit 단계에서 보면 [ci skip] 이 명령어를 넣어두지 않으면 무한 파이프라인이 생성이 되어서 그것을 막기 위함 입니다.

동작 확인

먼저 ArgoCD에서 Gitlab 프로젝트와 연결을 하여 Application을 생성 해줍니다.

 

현재 사용하는 이미지 태그 번호는 179 입니다.

 

변경사항 없이 Commit and Push를 해서 파이프라인을 생성 해주고 결과를 봐줍니다.

 

 

정상적으로 진행이 되었고, ArgoCD에서 rollout 되는지 확인 해줍니다.

 

이상 입니다.

반응형