Jenkins Pipeline (Harbor + ArgoCD)
- GitHub에 코드 푸시
- Jenkins가 GitHub Webhook을 받아 빌드 실행
- Docker 이미지 빌드 및 Harbor에 Push
- 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 저장소 설정
- values.yaml 파일에서 image.tag를 업데이트
- 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 파이프라인을 구축하는 전체 코드와 명령어를 제공할게.
이 파이프라인은 다음 흐름을 따른다:
- 개발자가 GitHub에 코드 푸시
- Jenkins가 이를 감지하고 빌드 수행
- Docker 이미지를 빌드하고 Harbor에 푸시
- 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은 다음 작업을 수행해:
- GitHub에서 코드 체크아웃
- Docker 이미지를 빌드
- Harbor에 푸시
- ArgoCD를 통해 최신 이미지로 배포
추가적으로, kubectl set image 명령어 대신 GitOps 방식으로 values.yaml을 수정하고 Git에 푸시하는 방법도 가능해.
더 개선하거나 Helm과 연동하고 싶다면 말해줘! 🚀
CI/CD 파이프라인 구축 주요 단계
- GitHub → 코드 푸시
- Jenkins → 빌드 및 Docker 이미지 생성 후 Harbor에 저장
- 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 설정
- GitHub SSH Key 등록
- Manage Jenkins → Manage Credentials → Global
- ID: github-ssh-key
- GitHub SSH Key 등록
- Harbor 로그인 정보 등록
- ID: harbor-credentials
- Harbor 사용자명/비밀번호 등록
- 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
동작 방식
- GitHub에 코드 푸시
- Jenkins가 Webhook을 받아 빌드 및 Harbor에 Docker 이미지 업로드
- Helm Chart의 values.yaml 파일을 업데이트하여 변경 사항 푸시
- 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 배포