Argo CD μ€μ΅(2)
Kubernetesμμ Finalizerλ 리μμ€μ μμ μμ μ μ μ΄νκΈ° μν λ©μ»€λμ¦μ΄λ€.
리μμ€μ metadata.finalizers νλμ μ μλ Finalizerλ μμ μμ²μ΄ λ€μ΄μμ λ 곧λ°λ‘ 리μμ€λ₯Ό μ κ±°νμ§ μκ³ , μ§μ λ μμ μ΄ μλ£λ λκΉμ§ 리μμ€λ₯Ό μ’ λ£ μ€(Terminating) μνλ‘ μ μ§νκ² λ§λ λ€. μ΄ κ³Όμ μ ν΅ν΄ μμ μ μ νμν μ 리(cleanup) μμ μ μμ νκ² μνν μ μλ€.
ArgoCDλ μ΄ Kubernetes Finalizer λ©μ»€λμ¦μ νμ©νμ¬ μ ν리μΌμ΄μ μμ μ ν΄λΉ μ ν리μΌμ΄μ μ΄ κ΄λ¦¬νλ 리μμ€λ₯Ό ν¨κ» μ 리νλλ‘ μ μ΄νλ€
cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: dev-nginx
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
helm:
valueFiles:
- values-dev.yaml
path: nginx-chart
repoURL: http://$MyIP:3000/devops/ops-deploy
targetRevision: HEAD
syncPolicy:
automated:
prune: true
syncOptions:
- CreateNamespace=true
destination:
namespace: dev-nginx
server: https://kubernetes.default.svc
EOF

kubectl get pod,svc,ep,cm -n dev-nginx
NAME READY STATUS RESTARTS AGE
pod/dev-nginx-744568f6b4-9f49w 1/1 Running 0 42s
pod/dev-nginx-744568f6b4-m6zn7 1/1 Running 0 42s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/dev-nginx NodePort 10.96.255.22 <none> 80:30000/TCP 43s
NAME ENDPOINTS AGE
endpoints/dev-nginx 10.244.1.12:80,10.244.3.16:80 43s
NAME DATA AGE
configmap/dev-nginx 1 43s
configmap/kube-root-ca.crt 1 27m
λ°°ν¬ ν νμΈνλ©΄ μ±ν¬κ° λ°λ‘ λΌμμΌλ©° μμ μμλ λ°λ‘ λ°μμ΄ λκ² λλ€.
μΉν ν μ€νΈ

μΉν ν μ€νΈλ₯Ό νλ€.
cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: dev-nginx
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
helm:
valueFiles:
- values-dev.yaml
path: nginx-chart
repoURL: http://$MyIP:3000/devops/ops-deploy
targetRevision: HEAD
syncPolicy:
automated:
prune: true
syncOptions:
- CreateNamespace=true
destination:
namespace: dev-nginx
server: https://kubernetes.default.svc
EOF
kubectl get pod,svc,ep,cm -n dev-nginx
jenkins + argocd + k8s
cd ops-deploy
mkdir dev-app
DHUSER=<λ컀 νλΈ κ³μ >
# λ²μ μ 보
VERSION=0.0.1
cat > dev-app/VERSION <<EOF
$VERSION
EOF
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
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 add . && git commit -m "Add dev-app deployment yaml" && git push -u origin main
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

ops-deploy λ ν¬λ₯Ό λ°λΌλ³΄λ ArgoCd μ±μ μμ±νλ€.
pipeline {
agent any
environment {
DOCKER_IMAGE = '<μμ μ λ컀 νλΈ κ³μ >/dev-app' // Docker μ΄λ―Έμ§ μ΄λ¦
GOGSCRD = credentials('gogs-crd')
}
stages {
stage('dev-app Checkout') {
steps {
git branch: 'main',
url: 'http://<μμ μ μ§ IP>: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://<μμ μ μ§ IP>: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 '' "s/$OLDVER/$NEWVER/" dev-app/timeserver.yaml
sed -i '' "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}@<μμ μ μ§ IP>: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."
}
}
}