Ssoon
Jenkins + ArgoCD : Jenkins CI + Argo CD + K8S(Kind) 본문

1️⃣ Repo(ops-deploy) 기본 코드 작성
root@DESKTOP-72C919S:~/cicd-labs/ops-deploy# mkdir dev-app
root@DESKTOP-72C919S:~/cicd-labs/ops-deploy# DHUSER=kschoi728
root@DESKTOP-72C919S:~/cicd-labs/ops-deploy# VERSION=0.0.1
root@DESKTOP-72C919S:~/cicd-labs/ops-deploy# cat > dev-app/VERSION <<EOF
$VERSION
EOF
- dev-app/timeserver.yaml
root@DESKTOP-72C919S:~/cicd-labs/ops-deploy# cat > dev-app/timeserver.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: timeserver
spec:
replicas: 2
selector:
matchLabels:
pod: timeserver-pod
template:
metadata:
labels:
pod: timeserver-pod
spec:
containers:
- name: timeserver-container
image: docker.io/$DHUSER/dev-app:$VERSION
livenessProbe:
initialDelaySeconds: 30
periodSeconds: 30
httpGet:
path: /healthz
port: 80
scheme: HTTP
timeoutSeconds: 5
failureThreshold: 3
successThreshold: 1
imagePullSecrets:
- name: dockerhub-secret
EOF
- dev-app/service.yaml
root@DESKTOP-72C919S:~/cicd-labs/ops-deploy# cat > dev-app/service.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
name: timeserver
spec:
selector:
pod: timeserver-pod
ports:
- port: 80
targetPort: 80
protocol: TCP
nodePort: 30000
type: NodePort
EOF
- Git에서 변경 사항을 스테이징하고 커밋한 후 원격 저장소의 main 브랜치로 푸시
root@DESKTOP-72C919S:~/cicd-labs/ops-deploy# git add . && git commit -m "Add dev-app deployment yaml" && git push -u origin main
[main 39589f4] Add dev-app deployment yaml
3 files changed, 43 insertions(+)
create mode 100644 dev-app/VERSION
create mode 100644 dev-app/service.yaml
create mode 100644 dev-app/timeserver.yaml
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 12 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 850 bytes | 850.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
To http://172.18.234.111:3000/devops/ops-deploy.git
28d79c1..39589f4 main -> main
branch 'main' set up to track 'origin/main'.
2️⃣ Repo(ops-deploy) 를 바라보는 ArgoCD App 생성
root@DESKTOP-72C919S:~/cicd-labs/ops-deploy# cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: timeserver
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
path: dev-app
repoURL: http://$MyIP:3000/devops/ops-deploy
targetRevision: HEAD
syncPolicy:
automated:
prune: true
syncOptions:
- CreateNamespace=true
destination:
namespace: default
server: https://kubernetes.default.svc
EOF
Warning: metadata.finalizers: "resources-finalizer.argocd.argoproj.io": prefer a domain-qualified finalizer name including a path (/) to avoid accidental conflicts with other finalizer writers
application.argoproj.io/timeserver created

3️⃣ Repo(dev-app) 코드 작업
pipeline {
agent any
environment {
DOCKER_IMAGE = 'kschoi728/dev-app' // Docker 이미지 이름
GOGSCRD = credentials('gogs-crd')
}
stages {
stage('dev-app Checkout') {
steps {
git branch: 'main',
url: 'http://172.18.234.111:3000/devops/dev-app.git', // Git에서 코드 체크아웃
credentialsId: 'gogs-crd' // Credentials ID
}
}
stage('Read VERSION') {
steps {
script {
// VERSION 파일 읽기
def version = readFile('VERSION').trim()
echo "Version found: ${version}"
// 환경 변수 설정
env.DOCKER_TAG = version
}
}
}
stage('Docker Build and Push') {
steps {
script {
docker.withRegistry('https://index.docker.io/v1/', 'dockerhub-crd') {
// DOCKER_TAG 사용
def appImage = docker.build("${DOCKER_IMAGE}:${DOCKER_TAG}")
appImage.push()
appImage.push("latest")
}
}
}
}
stage('ops-deploy Checkout') {
steps {
git branch: 'main',
url: 'http://172.18.234.111:3000/devops/ops-deploy.git', // Git에서 코드 체크아웃
credentialsId: 'gogs-crd' // Credentials ID
}
}
stage('ops-deploy version update push') {
steps {
sh '''
OLDVER=$(cat dev-app/VERSION)
NEWVER=$(echo ${DOCKER_TAG})
sed -i -e "s/$OLDVER/$NEWVER/" dev-app/timeserver.yaml
sed -i -e "s/$OLDVER/$NEWVER/" dev-app/VERSION
git add ./dev-app
git config user.name "devops"
git config user.email "a@a.com"
git commit -m "version update ${DOCKER_TAG}"
git push http://${GOGSCRD_USR}:${GOGSCRD_PSW}@172.18.234.111:3000/devops/ops-deploy.git
'''
}
}
}
post {
success {
echo "Docker image ${DOCKER_IMAGE}:${DOCKER_TAG} has been built and pushed successfully!"
}
failure {
echo "Pipeline failed. Please check the logs."
}
}
}
⚙️ 세부 단계 요약
🔹 1. dev-app Checkout
dev-app Git 저장소(http://172.18.234.111:3000/devops/dev-app.git)에서
main 브랜치 코드를 Jenkins 워크스페이스로 내려받아요.
→ 인증 정보(gogs-crd)를 사용해 접근합니다.
🔹 2. Read VERSION
내려받은 코드 안의 VERSION 파일을 읽어서
해당 버전 문자열(예: 1.0.3)을 환경 변수 DOCKER_TAG에 저장합니다.
→ 이 값이 Docker 이미지 태그로 사용됩니다.
🔹 3. Docker Build and Push
- docker build로 kschoi728/dev-app:${DOCKER_TAG} 이미지를 빌드
- DockerHub(dockerhub-crd 인증)로 푸시
- 최신 버전 태그(latest)도 같이 푸시
✅ 결과:
DockerHub에 다음 두 개 이미지가 올라갑니다.
kschoi728/dev-app:<버전>
kschoi728/dev-app:latest
🔹 4. ops-deploy Checkout
ops-deploy 저장소(http://172.18.234.111:3000/devops/ops-deploy.git)에서
최신 코드를 main 브랜치 기준으로 내려받습니다.
→ 역시 같은 Gogs 자격증명(gogs-crd)을 사용합니다.
🔹 5. ops-deploy version update push
- 이전 버전(OLDVER)과 새 버전(NEWVER)을 비교
- dev-app/timeserver.yaml과 dev-app/VERSION 파일에서 버전 문자열을 새 버전으로 바꿈
- Git에 변경사항 커밋 후 Gogs 저장소로 푸시
즉, 새로운 Docker 이미지 버전이 빌드되면, 자동으로 배포용 리포지토리의 버전 정보도 업데이트하는 단계입니다.
🧾 마무리(post 블록)
- ✅ 성공 시:
→ "Docker image kschoi728/dev-app:<버전> has been built and pushed successfully!" 출력 - ❌ 실패 시:
→ "Pipeline failed. Please check the logs." 출력
🧠 요약 한 줄 정리
💡 이 파이프라인은 dev-app 코드를 가져와 Docker 이미지로 빌드하고, DockerHub에 푸시한 뒤, ops-deploy 저장소의 버전 정보를 자동으로 갱신하는 Jenkins 자동화 파이프라인입니다.
- VERSION 파일 수정 : 0.0.5
- server.py 파일 수정 : 0.0.5
de0560772841:/data/dev-app# git status
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: Jenkinsfile
modified: VERSION
modified: server.py
no changes added to commit (use "git add" and/or "git commit -a")
de0560772841:/data/dev-app# git add . && git commit -m "VERSION $(cat VERSION) Changed" && git push -u origin main
[main 409daaa] VERSION 0.0.5 Changed
3 files changed, 27 insertions(+), 4 deletions(-)
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 12 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 830 bytes | 830.00 KiB/s, done.
Total 5 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
To http://172.18.234.111:3000/devops/dev-app.git
7c148e6..409daaa main -> main
branch 'main' set up to track 'origin/main'.


4️⃣ Full CI/CD 동작 확인 : Argo CD app Trigger 후 AutoSync 로 신규 버전 업데이트 진행 확인
- dev-app Repo 에서 한번 더 버전 업데이트 수행
- VERSION 파일 수정 : 0.0.7
- server.py 파일 수정 : 0.0.7
de0560772841:/data/dev-app# git status
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: VERSION
modified: server.py
no changes added to commit (use "git add" and/or "git commit -a")
de0560772841:/data/dev-app# git add . && git commit -m "VERSION $(cat VERSION) Changed" && git push -u origin main
[main 80be12a] VERSION 0.0.7 Changed
2 files changed, 2 insertions(+), 2 deletions(-)
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 335 bytes | 335.00 KiB/s, done.
Total 4 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
To http://172.18.234.111:3000/devops/dev-app.git
cddfdf5..80be12a main -> main
branch 'main' set up to track 'origin/main'.

'CICD Study [1기]' 카테고리의 다른 글
| Argo CD in Practice – 2) Argo CD 시작하기 (0) | 2025.10.19 |
|---|---|
| Argo CD in Practice – 1) GitOps와 쿠버네티스 (0) | 2025.10.19 |
| Jenkins + ArgoCD : Argo CD + K8S(Kind) (0) | 2025.10.19 |
| Jenkins + ArgoCD : Jenkins CD by K8S(Kind) (0) | 2025.10.19 |
| Jenkins + ArgoCD : Jenkins CI + K8S(Kind) (0) | 2025.10.19 |
Comments