
목표는 아래 흐름을 한 번에 연결하는 것
GitHub hook trigger for GITScm polling 활성화환경 변수
SOURCE_GITHUB_URL: 소스 코드 레포MANIFESTS_GITHUB_URL: k8s manifests 레포GIT_USERNAME, GIT_EMAIL: manifests 레포 커밋용 사용자 정보Docker 이미지 태그 전략
${currentBuild.number}: 버전 태그latest: 최신 태그pipeline {
agent any
environment {
SOURCE_GITHUB_URL = '{source code repo url}'
MANIFESTS_GITHUB_URL = '{manifests repo url}'
GIT_USERNAME = '{git username}'
GIT_EMAIL = '{git email}'
}
stages {
stage('Source Build') {
steps {
git branch: 'main', url: "${env.SOURCE_GITHUB_URL}"
script {
if (isUnix()) {
sh "chmod +x ./gradlew"
sh "./gradlew clean build"
} else {
bat "gradlew.bat clean build"
}
}
}
}
stage('Run Tests') {
steps {
script {
if (isUnix()) {
sh "./gradlew test"
} else {
bat "gradlew.bat test"
}
}
}
post {
always {
junit '**/build/test-results/test/*.xml'
}
}
}
stage('Docker Build and Push') {
steps {
script {
withCredentials([usernamePassword(credentialsId: 'DOCKERHUB_PASSWORD', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
if (isUnix()) {
sh "docker build -t ${DOCKER_USER}/argocd-pipe:${currentBuild.number} ."
sh "docker build -t ${DOCKER_USER}/argocd-pipe:latest ."
sh "docker login -u ${DOCKER_USER} -p ${DOCKER_PASS}"
sh "docker push ${DOCKER_USER}/argocd-pipe:${currentBuild.number}"
sh "docker push ${DOCKER_USER}/argocd-pipe:latest"
sh "docker logout"
} else {
bat "docker build -t ${DOCKER_USER}/argocd-pipe:${currentBuild.number} ."
bat "docker build -t ${DOCKER_USER}/argocd-pipe:latest ."
bat "docker login -u %DOCKER_USER% -p %DOCKER_PASS%"
bat "docker push ${DOCKER_USER}/argocd-pipe:${currentBuild.number}"
bat "docker push ${DOCKER_USER}/argocd-pipe:latest"
bat "docker logout"
}
}
}
}
}
stage('K8S Manifest Update') {
steps {
// manifests 레포 clone (credentialsId: github 사용)
git credentialsId: 'github',
url: "${env.MANIFESTS_GITHUB_URL}",
branch: 'main'
script {
if (isUnix()) {
sh "sed -i '' 's/argocd-pipe:.*\$/argocd-pipe:${currentBuild.number}/g' boot-deployment.yml"
sh "git add boot-deployment.yml"
sh "git config user.name '${env.GIT_USERNAME}'"
sh "git config user.email '${env.GIT_EMAIL}'"
sh "git commit -m '[UPDATE] ${currentBuild.number} image versioning'"
sh "git push -u origin main"
} else {
bat "powershell -Command \"(Get-Content boot-deployment.yml) -replace 'argocd-pipe:.*', 'argocd-pipe:${currentBuild.number}' | Set-Content boot-deployment.yml\""
bat "git add boot-deployment.yml"
bat "git config user.name \"${env.GIT_USERNAME}\""
bat "git config user.email \"${env.GIT_EMAIL}\""
bat "git commit -m \"[UPDATE] ${currentBuild.number} image versioning\""
bat "git push -u origin main"
}
}
}
}
}
post {
success { echo 'Pipeline succeeded!' }
failure { echo 'Pipeline failed!' }
}
}
git push가 Jenkins Credentials가 아니라 로컬/에이전트의 인증 상태에 의존withCredentials로 GitHub username/token을 주입https://user:token@github.com/... 형태로 변환해서 push 수행stage('K8S Manifest Update') {
steps {
withCredentials([usernamePassword(credentialsId: 'github', usernameVariable: 'GIT_USER', passwordVariable: 'GIT_TOKEN')]) {
git credentialsId: 'github',
url: "${env.MANIFESTS_GITHUB_URL}",
branch: 'main'
script {
def gitUser = env.GIT_USER
def gitToken = env.GIT_TOKEN
def repoUrl = env.MANIFESTS_GITHUB_URL
def authUrl = repoUrl.replace("https://", "https://${gitUser}:${gitToken}@")
if (isUnix()) {
sh """
sed -i '' 's/argocd-pipe:.*\$/argocd-pipe:${currentBuild.number}/g' boot-deployment.yml
git add boot-deployment.yml
git config user.name '${env.GIT_USERNAME}'
git config user.email '${env.GIT_EMAIL}'
git commit -m '[UPDATE] ${currentBuild.number} image versioning'
git push "${authUrl}" main
"""
} else {
bat """
powershell -Command "(Get-Content boot-deployment.yml) -replace 'argocd-pipe:.*', 'argocd-pipe:${currentBuild.number}' | Set-Content boot-deployment.yml"
git add boot-deployment.yml
git config user.name "${env.GIT_USERNAME}"
git config user.email "${env.GIT_EMAIL}"
git commit -m "[UPDATE] ${currentBuild.number} image versioning"
git push "${authUrl}" main
"""
}
}
}
}
}
Jenkins Credentials에 id: github로 등록
Kind: Username with password (또는 Username/Token)
토큰 권한 가이드
Contents: Read and writerepo 권한(Private repo면 필수)로컬에서 manifests 전용 디렉토리를 만들고 git init 후 아래 파일들을 관리한다.
원격 레포는 private로 만들어도 되며, 이후 remote 연결해서 push 해둔다.
image가 Jenkins에서 업데이트될 대상latest로 두고, 파이프라인에서 ${currentBuild.number}로 치환apiVersion: apps/v1
kind: Deployment
metadata:
name: boot-deployment
spec:
selector:
matchLabels:
app: boot
replicas: 3
template:
metadata:
labels:
app: boot
spec:
containers:
- name: boot-container
image: limu810/argocd-pipe:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: boot-service
spec:
type: ClusterIP
ports:
- port: 8001
targetPort: 8080
selector:
app: boot
apiVersion: apps/v1
kind: Deployment
metadata:
name: vue-deployment
spec:
selector:
matchLabels:
app: vue
template:
metadata:
labels:
app: vue
spec:
containers:
- name: vue-container
image: limu810/k8s_vue_ing:latest
imagePullPolicy: Always
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: vue-service
spec:
type: ClusterIP
ports:
- port: 8000
targetPort: 80
selector:
app: vue
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /()(.*)
pathType: ImplementationSpecific
backend:
service:
name: vue-service
port:
number: 8000
- path: /boot(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: boot-service
port:
number: 8001
brew install argoproj/tap/argo-cd
설치 확인
argocd version
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
서비스 확인
kubectl get svc -n argocd
UI 접근 (port-forward)
kubectl port-forward svc/argocd-server -n argocd 8888:443
초기 admin 비밀번호 확인
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
CLI 로그인
argocd login localhost:8888
argocd repo add {github_repo_url} --username {github_username} --password {github_access_token}
argocd app create my-app \
--repo {github_repository_url} \
--path ./ \
--dest-server https://kubernetes.default.svc \
--dest-namespace default
옵션 의미
--repo: manifests 레포 URL--path: 레포 내부에서 매니페스트가 위치한 디렉토리--dest-server: 쿠버네티스 API 서버(클러스터 내부 기본 주소)--dest-namespace: 배포 대상 네임스페이스argocd app set my-app --sync-policy automated
/health 응답 코드를 변경하고 source repo에 push${currentBuild.number}와 latest로 pushboot-deployment.yml 이미지 태그를 ${currentBuild.number}로 변경 후 push/health 응답이 바뀐 것을 확인해 end-to-end 흐름 검증argocd app delete argocd/my-app --cascade
--cascade: 해당 애플리케이션이 관리하던 Kubernetes 리소스(Deployment/Service/ConfigMap 등)까지 함께 삭제kubectl delete로 별도 정리 가능