728x90
반응형

[목표]

현재 팀원들이 개발을 진행중인 여러 개의 Application들을 Main branch에 push를 하게 되면 자동으로 쿠버네티스 서버에 배포가 되게 하도록 해야합니다.

[Tool]

  • Gitea : Git은 Gitlab보다 가벼운 Gitea(깃티)라는 소프트웨어 패키지를 사용하고 있습니다.
  • Jenkins : 빌드된 파일들을 Dockerfile을 이용해서 이미지로 만드는 등의 Pipeline CI/CD 작업 툴로 Jenkins를 사용합니다.
  • ArgoCD : ArgoCD는 쿠버네티스 배포를 도와주는 도구입니다.
  • Kubernetes : Microservice를 구현할 수 있게 컨테이너화 된 애플리케이션을 관리합니다.
  • Helm : Kubernetes 패키지 관리를 위하여 사용합니다.

[전체 과정]

Gitea와 Jenkins 연동

1. Jenkins에 Gitea관련 설정 추가

Jenkins에 Gitea를 사용할 수 있는 Plugin을 설치해야 합니다.
https://plugins.jenkins.io/gitea-checks/
https://plugins.jenkins.io/gitea/

2. Gitea 연결 (Jenkins 관리 > 시스템 설정)

  • Name : 사용할 이름을 정해주면 됩니다. gitea로 설정하였습니다.
  • Server URL : Gitea의 URL을 입력해야 합니다. (Gitea 설정이 정상적으로 되었다면 아래에 조그만 글씨로 Gitea Version 정보가 나타나게 됩니다.)
    • Credentials 설정 (Jenkins관리 > Credentials > System > Global credentials)에서 Add Credentials를 클릭합니다.
    • Username with password를 통해 설정합니다. (root / cloud1234)
      • (이미 설정하였기에 This ID is already in use 가 생기고, Unique한 값으로 설정해줍니다)
      • Credentials는 구축된 Gitea에 접근하기 위한 인증입니다. Jenkins는 기본적으로 Credentials Plugin을 제공하며, 이를 통해 인증 정보를 관리하고 사용합니다.Manage hooks : Credentials를 지정해주어야 합니다.

3. Jenkins Webhook 설정

  • Multibranch Pipeline Project로 생성해야 합니다.

(Gitea 연결은 다른 Freestyle Project 또는 Pipeline으로는 연결이 불가능합니다.)

 

    • Multibranch Pipeline을 통해 아래와 같이 설정해줍니다.
      • Gitea Server는 gitea 서버를 설정해줍니다.
      • gitea 서버를 설정하면 아래 Repository 목록이 나올 것입니다. 원하는 Repository를 선택하면 됩니다.

  • Build Configuration
    • Mode는 Jenkinsfile로 설정합니다. 이후에 Webhook은 설정한 Repository에 있는 Jenkinsfile을 실행하게 됩니다
  • Scan Multibranch Pipeline Triggers
    • Scan by webhook에서 Trigger token은 이후에 Gitea에서 Webhook 설정을 할 때 header에 담을 token과 동일하게 설정해야 하기 때문에 기억한 뒤 Gitea Webhook 설정에 사용해야합니다.
    • 4insure-msa-app으로 설정해두었습니다.

4. Gitea Webhook 설정

    • Gitea에서 Repository의 설정 > Webhooks 에서 Webhook을 추가하면 됩니다.
      (Setting이 보이지 않는다면 해당 Repository에 권한이 없기 때문입니다)
    • Target URL
      • http://{Jenkins URL}/multibranch-webhook-trigger/invoke?token={토큰 값}
      • 토큰 값은 위에 Jenkins Webhook 설정 때 만들었던 token입니다.

5. Jenkinsfile 작성

  • Jenkinsfile을 해당 Repository의 main branch에 commit & push해주면 Webhook이 동작하고 Jenkins Pipeline이 동작합니다.

 

Jenkins Pipeline 작성

1. Maven 등록 (Jenkins 관리 > Tools)

  • Jenkins가 실행되면 Jenkins에게 Build Tool를 주어야 Build 할 수 있습니다.
  • Maven를 빌드 툴로 설정하였기 때문에 아래와 같이 설치합니다.

2. Jenkins WorkFlow

import java.text.SimpleDateFormat
def dateFormat = new SimpleDateFormat("yyMMdd_HHmmss")
def TAG = dateFormat.format(new Date())
pipeline {
    agent any
    tools {
        maven "M3"
    }
    environment {
        REGISTRY_HOST = 'msa.harbor.com'
        REGISTRY_PROJECT = 'conn-test'
        GIT_OPS_REPOSITORY = 'msa-gitops'
        TAG = 'latest'
        APP = '4insure-msa-api-user'
        APP_PATH = 'UserApi'
        NAMESPACE = 'portal'
        PROFILE = 'msa' //'prod'
        ENV = 'msa'
    }
    stages {
        stage('echo test') {
            steps {
                echo "4insure-msa-api-user app"
            }
        }
        stage('Maven Build') {
            steps {
                 sh 'ls -al' // Run Maven build
                 sh 'mvn -f pom.xml clean install' // Run Maven build
            }
        }
        stage('Docker Build & Push') {
            steps {
                sh "docker login ${REGISTRY_HOST} -u admin -p cloud1234"
                sh "docker build -t ${REGISTRY_HOST}/${REGISTRY_PROJECT}/${APP}:${TAG} ."
                sh "docker push ${REGISTRY_HOST}/${REGISTRY_PROJECT}/${APP}:${TAG}"
            }
        }
        stage('Clean dummy images') {
            steps {
                sh """docker image prune --all --force --filter label=app=${APP} --filter label=io.kubernetes.pod.namespace=jenkins"""
            }
        }
        stage('Remote api updating gitops job') {
            steps {
                sh """curl -X GET -u \"admin:cloud1234\" 'http://172.10.40.243:30070/job/msa-gitops/buildWithParameters?token=MSA_GITOPS_TOKEN&TARGET=${APP}&TAG=${TAG}&ENV=${ENV}'"""
            }
        }
    }   // End of stages
} // End of pipeline

Source Build

  • Source Repository에서 Maven을 이용해 해당 애플리케이션을 Build 합니다

Docker Build & Push

  • Build된 것을 해당 Repository의 Dockerfile을 이용해서 Image를 만듭니다.
  • 만들어진 이미지를 Harbor에 Push합니다.
FROM neduekwunife/openjdk8-jre-alpine-with-fontconfig
LABEL app="4insure-msa-api-user"
ADD ./target/UserApi-3.0.jar /
WORKDIR /
ENV SPRING_PROFILES_ACTIVE=msa
ENTRYPOINT ["java", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}", "-Dfile.encoding=UTF8", "-Duser.timezone=Asia/Seoul", "-jar", "UserApi-3.0.jar"]

 

Clean Docker Image

  • 필요없는 docker image를 삭제합니다.
  • namespace를 제대로 설정해야 정확한 image를 타겟팅하여 삭제할 수 있습니다.

Update GitOps

  • 새롭게 만들어진 Image를 배포하기 위해 Jenkins의 GitOps Job를 호출해서 실행해야 합니다.
  • Jenkins의 원격 빌드를 이용하여 빌드를 유발합니다.

3. Update GitOps

    • 새로운 Item 생성을 통해 Job을 생성합니다. 이번에는 Pipeline을 선택합니다.
    • 매개변수가 있기 때문에 매개변수를 등록하여 사용할 수 있도록 합니다.
      • Jenkins의 매개변수 설정 중 Trim the string 을 해주어야 합니다.
    • 소스코드 관리
      • Gitea에 GitOps를 위한 새로운 Repository를 생성합니다. 이름은 msa-gitops로 하였습니다
      • 소스코드 관리 탭에서 Repository URL과 Credentials를 설정해줍니다

  • 빌드 유발
    • 빌드를 원격으로 유발을 클릭하고 Authentication Token을 등록해줍니다.
    • 해당 Token값은 위에서 마지막 Stage인 Update GitOps를 작성할 때 token={TOKEN_NAME}의 TOKEN_NAME과 동일하여야 합니다.

Shell Script 내용

  • 위에서 설정한 파라미터들이 shell에서 사용됩니다.
  • Shell은 Helm을 사용하여 Kubernetes에 배포하는 과정을 자동화하는 것을 목적으로 합니다.
  • Image tag는 현재 시간값으로 재설정됩니다. 해당 내용은 위에서 작성한 Jenkins Workflow에서 확인할 수 있습니다.
    • def TAG = dateFormat.format(new Date())
  • Image tag를 바꾼 뒤, GitOps를 하기위한 Repository에 commit, push를 진행합니다.
#!/bin/bash
MODULES=$TARGET
APP_LIST="4insure-msa-api-portal 4insure-msa-api-user 4insure-msa-app"
echo "Deploy target application: "$TARGET
echo "TAG: "$TAG
chmod 777 manifests/$TARGET.yaml
helm template -n test $TARGET charts/$TARGET -f charts/$TARGET/values.yaml \
     --set image.tag=${TAG} > manifests/$TARGET.yaml
echo "TAG changed: "$TAG
# git add/commit/push
git add .
git commit -m "updating manifest file completed."
git status
git push origin HEAD:main

4. ArgoCD

ArgoCD는 GitOps Repository를 바라보고 있습니다.

해당 GitOps Job에 의해 변화된 이미지가 Repository에 push 되었으므로 ArgoCD가 이를 감지하여 Sync를 맞추어 쿠버네티스에 새로운 이미지를 사용하여 자동으로 배포합니다.

 

Helm 설정

Helm Chart

Helm은 쿠버네티스 애플리케이션을 관리하기 위한 패키지 매니저입니다.
npm 패키지 매니저의 package.json이 있듯이 Helm에는 Chart를 통해서 쿠버네티스의 리소스를 설치하는데 필요한 모든 정보를 포함하고 있습니다.
helm chart에는 templates폴더, values.yaml파일이 포함되어 있는데, 차트의 설정 값이 있는 values.yaml파일을 통하여 templates파일들을 렌더링하여 쿠버네티스의 리소스 파일을 생성합니다.
values.yaml파일의 설정값을 사용자가 재정의하여 커스터마이징을 할 수 있습니다.

Gitea Helm Chart Install

# gitea 공식 Helm Repo Add 
helm repo add gitea-charts <https://dl.gitea.com/charts/> 
# Offline Mode 
helm fetch gitea-charts/gitea 
# install 
helm install -n gitea gitea . -f values.yaml
helm repo add {사용자 임의 정의 Repo 이름} {추가할 Helm repository URL}
helm fetch {다운로드 받을 Chart} # 다운로드 받은 파일은 .tgz확장자를 가진 압축파일

Gitea의 공식 Repository를 Helm에 추가하여 Helm을 통해 Gitea 차트를 설치하거나 업데이트할 수 있도록 합니다.

Directory 구성

  • charts
    • templates
      • 쿠버네티스 리소스 yaml 파일들이 위치합니다.
        (Deployment.yaml, Service.yaml을 Values.yaml의 변수를 통해서 작성합니다.)
  • manifests
    • 변경된 yaml 파일이 저장됩니다.
    • ArgoCD는 manifests에 변환된 yaml파일을 감지하여 Sync를 맞추어 자동으로 배포합니다.
  • scripts
    • GitOps Job에서 ArgoCD를 동작시키기 위하여 Helm의 Image를 변경하기 위해 실행되는 script입니다
  • Chart.yaml
    • chart에 대한 메타데이터가 저장되어있습니다.
728x90
반응형

+ Recent posts