카테고리 없음

Jenkins Pipeline (Harbor + ArgoCD)

자바바라 2025. 3. 14. 21:41
  1. GitHub에 코드 푸시
  2. Jenkins가 GitHub Webhook을 받아 빌드 실행
  3. Docker 이미지 빌드 및 Harbor에 Push
  4. ArgoCD가 자동으로 새로운 이미지 배포

1. GitHub Webhook 설정

GitHub에서 Settings → Webhooks에서 Jenkins의 Webhook을 추가해.
URL 예시:

http://your-jenkins-server:8080/github-webhook/

2. Jenkinsfile 작성

Jenkins가 빌드하고 Harbor에 이미지를 Push하는 Jenkinsfile을 루트 디렉토리에 추가해.

pipeline {
    agent any
    environment {
        HARBOR_URL = "harbor.example.com"
        IMAGE_NAME = "my-app"
        IMAGE_TAG = "latest"
        HARBOR_PROJECT = "dev"
    }
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/your-repo.git'
            }
        }
        stage('Build Docker Image') {
            steps {
                script {
                    sh "docker build -t $HARBOR_URL/$HARBOR_PROJECT/$IMAGE_NAME:$IMAGE_TAG ."
                }
            }
        }
        stage('Push to Harbor') {
            steps {
                script {
                    sh "docker login -u admin -p password $HARBOR_URL"
                    sh "docker push $HARBOR_URL/$HARBOR_PROJECT/$IMAGE_NAME:$IMAGE_TAG"
                }
            }
        }
        stage('Trigger ArgoCD Sync') {
            steps {
                script {
                    sh "argocd app sync my-app"
                }
            }
        }
    }
}

3. ArgoCD 배포 설정

ArgoCD는 새로운 이미지가 푸시되면 이를 감지해 배포해야 해.

GitOps 방식으로 ArgoCD가 참조할 Helm Chart 저장소 설정

  1. values.yaml 파일에서 image.tag를 업데이트
  2. ArgoCD가 이를 자동으로 감지하고 배포

ArgoCD Application 선언 (argocd-app.yaml)

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  destination:
    namespace: my-app
    server: https://kubernetes.default.svc
  project: default
  source:
    repoURL: https://github.com/your-repo/helm-chart.git
    targetRevision: HEAD
    path: my-app
    helm:
      values: |
        image:
          repository: harbor.example.com/dev/my-app
          tag: latest
  syncPolicy:
    automated:
      selfHeal: true
      prune: true

4. 배포 확인

ArgoCD에 배포된 애플리케이션을 확인하려면 다음 명령어를 사용하면 돼.

argocd app list
argocd app get my-app

이제 GitHub → Jenkins → Harbor → ArgoCD로 이어지는 CI/CD 자동화 파이프라인이 완성된 거야. 🚀

 

 

Jenkins, Harbor, ArgoCD를 활용한 CI/CD 파이프라인을 구축하는 전체 코드와 명령어를 제공할게.
이 파이프라인은 다음 흐름을 따른다:

  1. 개발자가 GitHub에 코드 푸시
  2. Jenkins가 이를 감지하고 빌드 수행
  3. Docker 이미지를 빌드하고 Harbor에 푸시
  4. ArgoCD가 Harbor의 새 이미지를 감지하여 자동 배포

전체 코드

pipeline {
    agent any

    environment {
        REPO_NAME = 'my-app'
        HARBOR_URL = 'harbor.example.com'
        HARBOR_PROJECT = 'library'
        IMAGE_TAG = "${env.BUILD_NUMBER}"
        K8S_NAMESPACE = 'my-namespace'
    }

    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'git@github.com:your-repo.git'
            }
        }

        stage('Build Docker Image') {
            steps {
                script {
                    sh "docker build -t ${HARBOR_URL}/${HARBOR_PROJECT}/${REPO_NAME}:${IMAGE_TAG} ."
                }
            }
        }

        stage('Push to Harbor') {
            steps {
                script {
                    sh "docker login ${HARBOR_URL} -u harbor_user -p harbor_password"
                    sh "docker push ${HARBOR_URL}/${HARBOR_PROJECT}/${REPO_NAME}:${IMAGE_TAG}"
                }
            }
        }

        stage('Update ArgoCD') {
            steps {
                script {
                    sh "kubectl set image deployment/${REPO_NAME} ${REPO_NAME}=${HARBOR_URL}/${HARBOR_PROJECT}/${REPO_NAME}:${IMAGE_TAG} -n ${K8S_NAMESPACE}"
                }
            }
        }
    }
}

이 Jenkinsfile은 다음 작업을 수행해:

  1. GitHub에서 코드 체크아웃
  2. Docker 이미지를 빌드
  3. Harbor에 푸시
  4. ArgoCD를 통해 최신 이미지로 배포

추가적으로, kubectl set image 명령어 대신 GitOps 방식으로 values.yaml을 수정하고 Git에 푸시하는 방법도 가능해.
더 개선하거나 Helm과 연동하고 싶다면 말해줘! 🚀

 


CI/CD 파이프라인 구축 주요 단계

  1. GitHub → 코드 푸시
  2. Jenkins → 빌드 및 Docker 이미지 생성 후 Harbor에 저장
  3. ArgoCD → Harbor의 이미지를 감지하고 Kubernetes에 자동 배포

GitHub Actions 설정 (선택 사항)

Jenkins Webhook을 설정하기 전에, GitHub에 Jenkinsfile과 Helm Chart 배포 파일을 추가해야 합니다.

Jenkinsfile 예제

이 파일을 GitHub 저장소 루트에 추가합니다.

pipeline {
    agent any

    environment {
        HARBOR_URL = "harbor.example.com"
        HARBOR_PROJECT = "myproject"
        IMAGE_NAME = "myapp"
        IMAGE_TAG = "${env.BUILD_NUMBER}"
        GITHUB_REPO = "git@github.com:your-repo.git"
        K8S_NAMESPACE = "myapp-namespace"
    }

    stages {
        // Jenkins가 GitHub에서 코드 가져오기
        stage('Clone Repository') {
            steps {
                git credentialsId: 'github-ssh-key', url: "${GITHUB_REPO}", branch: 'main'
            }
        }
        // Docker 이미지 빌드 및 Harbor에 푸시
        stage('Build Docker Image') {
            steps {
                script {
                    sh "docker build -t ${HARBOR_URL}/${HARBOR_PROJECT}/${IMAGE_NAME}:${IMAGE_TAG} ."
                }
            }
        }

        stage('Push to Harbor') {
            steps {
                script {
                    withDockerRegistry([credentialsId: 'harbor-credentials', url: "https://${HARBOR_URL}"]) {
                        sh "docker push ${HARBOR_URL}/${HARBOR_PROJECT}/${IMAGE_NAME}:${IMAGE_TAG}"
                    }
                }
            }
        }

        // helm/values.yaml을 업데이트하여 새로운 이미지 태그 반영
        stage('Update Helm Values') {
            steps {
                script {
                    sh """
                    sed -i 's|image: .*|image: ${HARBOR_URL}/${HARBOR_PROJECT}/${IMAGE_NAME}:${IMAGE_TAG}|' helm/values.yaml
                    git add helm/values.yaml
                    git commit -m "Update image tag to ${IMAGE_TAG}"
                    git push origin main
                    """
                }
            }
        }
        // GitHub에 values.yaml 변경 사항 푸시 (ArgoCD가 감지)
        // ArgoCD를 통해 Kubernetes에 배포
        stage('Trigger ArgoCD Sync') {
            steps {
                script {
                    sh "argocd app sync myapp"
                }
            }
        }
    }
}

 


Jenkins 설정

Jenkins에서 GitHub Webhook을 활용하여 CI/CD를 자동 실행합니다.

Jenkins 플러그인 설치

  • Pipeline
  • GitHub Branch Source
  • Docker Pipeline
  • Kubernetes CLI
  • Git Plugin

Jenkins Credentials 설정

  1. GitHub SSH Key 등록
    • Manage Jenkins → Manage Credentials → Global
    • ID: github-ssh-key
    • GitHub SSH Key 등록
  2. Harbor 로그인 정보 등록
    • ID: harbor-credentials
    • Harbor 사용자명/비밀번호 등록
  3. ArgoCD CLI 인증
    • Manage Jenkins → Manage Credentials
    • ID: argocd-auth
    • argocd login <ARGOCD_SERVER> --username <USER> --password <PASSWORD>

Kubernetes 배포 (Helm)

Helm values.yaml

image:
  repository: harbor.example.com/myproject/myapp
  tag: latest

replicaCount: 2

service:
  type: ClusterIP
  port: 8080

GitHub Webhook 설정

GitHub → Settings → Webhooks에서 Jenkins URL 등록

  • Payload URL: http://JENKINS_IP:8080/github-webhook/
  • Content type: application/json
  • 이벤트: Just the push event

ArgoCD 설정

ArgoCD가 GitHub의 Helm Chart 변경을 감지하도록 설정합니다.

ArgoCD 애플리케이션 생성

argocd app create myapp \
    --repo https://github.com/your-repo.git \
    --path helm \
    --dest-server https://kubernetes.default.svc \
    --dest-namespace myapp-namespace \
    --sync-policy automatic

동작 방식

  1. GitHub에 코드 푸시
  2. Jenkins가 Webhook을 받아 빌드 및 Harbor에 Docker 이미지 업로드
  3. Helm Chart의 values.yaml 파일을 업데이트하여 변경 사항 푸시
  4. ArgoCD가 GitHub의 변경을 감지하고 Kubernetes에 자동 배포

GitHub에 코드가 푸시되면 Jenkins가 이를 감지하여 빌드하고,
Docker 이미지를 생성하여 Harbor에 푸시한 후,
ArgoCD가 배포


1. GitHub Repository 준비

프로젝트 구조

my-app/
│── .github/workflows/
│   └── jenkins-trigger.yml  # Jenkins 트리거용 GitHub Actions (선택)
│── Dockerfile               # Docker 이미지 빌드용
│── deployment/
│   ├── k8s-deployment.yaml  # Kubernetes 배포 YAML
│   ├── k8s-service.yaml      # Kubernetes 서비스 YAML
│── src/                      # 애플리케이션 소스 코드
│── Jenkinsfile               # Jenkins 파이프라인 스크립트
│── helm-chart/               # Helm 차트 (선택)
│── README.md

2. Jenkins 구성

Jenkins 설치 및 플러그인

Jenkins에서 다음 플러그인을 설치해야 해:

  • Pipeline
  • Git
  • Docker Pipeline
  • Kubernetes CLI
  • ArgoCD
  • Harbor Registry

3. Jenkinsfile 작성

GitHub에서 코드가 푸시되면 Jenkins가 실행될 Jenkinsfile을 작성할게.

Jenkinsfile

pipeline {
    agent any

    environment {
        HARBOR_URL = 'harbor.example.com'
        HARBOR_PROJECT = 'my-project'
        IMAGE_NAME = 'my-app'
        IMAGE_TAG = 'latest'
        K8S_NAMESPACE = 'dev'
        ARGOCD_APP_NAME = 'my-app'
    }

    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', credentialsId: 'github-credentials', url: 'https://github.com/user/my-app.git'
            }
        }

        stage('Build Docker Image') {
            steps {
                script {
                    sh """
                    docker build -t $HARBOR_URL/$HARBOR_PROJECT/$IMAGE_NAME:$IMAGE_TAG .
                    """
                }
            }
        }

        stage('Push to Harbor') {
            steps {
                script {
                    sh """
                    docker login -u admin -p mypassword $HARBOR_URL
                    docker push $HARBOR_URL/$HARBOR_PROJECT/$IMAGE_NAME:$IMAGE_TAG
                    """
                }
            }
        }

        stage('Update Kubernetes Deployment') {
            steps {
                script {
                    sh """
                    kubectl set image deployment/$IMAGE_NAME $IMAGE_NAME=$HARBOR_URL/$HARBOR_PROJECT/$IMAGE_NAME:$IMAGE_TAG -n $K8S_NAMESPACE
                    """
                }
            }
        }

        stage('Trigger ArgoCD Sync') {
            steps {
                script {
                    sh """
                    argocd app sync $ARGOCD_APP_NAME
                    """
                }
            }
        }
    }

    post {
        success {
            echo "Deployment successful!"
        }
        failure {
            echo "Deployment failed!"
        }
    }
}

4. Kubernetes Deployment YAML

Harbor에서 이미지를 가져와서 배포하는 k8s-deployment.yaml을 작성할게.

deployment/k8s-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: dev
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: harbor.example.com/my-project/my-app:latest
        ports:
        - containerPort: 8080

deployment/k8s-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: my-app-service
  namespace: dev
spec:
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: ClusterIP

5. ArgoCD Application 생성

ArgoCD에서 관리할 Application 리소스를 작성해.

argocd-app.yaml

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  destination:
    namespace: dev
    server: https://kubernetes.default.svc
  project: default
  source:
    repoURL: https://github.com/user/my-app.git
    targetRevision: main
    path: deployment
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

ArgoCD에 적용:

kubectl apply -f argocd-app.yaml

6. GitHub Actions (선택)

GitHub에 코드 푸시될 때 Jenkins를 트리거하는 Actions을 작성할 수도 있어.

.github/workflows/jenkins-trigger.yml

name: Trigger Jenkins Build

on:
  push:
    branches:
      - main

jobs:
  trigger-jenkins:
    runs-on: ubuntu-latest
    steps:
      - name: Trigger Jenkins
        run: |
          curl -X POST "http://jenkins.example.com/job/my-app/build" --user "admin:jenkins-password"

7. 실행 명령어 정리

Jenkins 수동 실행

jenkins_url="http://jenkins.example.com/job/my-app/build"
curl -X POST $jenkins_url --user "admin:jenkins-password"

Docker Build & Push (테스트)

docker build -t harbor.example.com/my-project/my-app:latest .
docker login -u admin -p mypassword harbor.example.com
docker push harbor.example.com/my-project/my-app:latest

Kubernetes 배포 확인

kubectl get pods -n dev
kubectl get deployments -n dev
kubectl describe deployment my-app -n dev

ArgoCD Sync

argocd app sync my-app
argocd app get my-app

결론

GitHub에 코드 푸시 → Jenkins가 빌드 → Harbor에 Docker 이미지 저장 → ArgoCD 배포