“๋ฐฐํฌ๋ฅผ ์๋ํํ๋ค”๋ ๋ง์ ๋ค์ด๋ดค๋๋ฐ, ์ค์ ๋ก ์ด๋ป๊ฒ ์๋ํ๋ ๊ฑธ๊น์? ์ฝ๋๋ฅผ ์์ ํ๊ณ Git์ ์ฌ๋ฆฌ๋ฉด ์๋ฒ์ ์๋์ผ๋ก ๋ฐ์๋๋ ๊ทธ ๋ง๋ฒ. ๊ทธ๋ฆฌ๊ณ ๋๊ตฐ๊ฐ ์๋ฒ๋ฅผ ์ค์๋ก ๊ฑด๋๋ฆฌ๋ฉด ์๋์ผ๋ก ๋๋์์ค๋ ์๊ฐ์น์ . ์ด๋ฒ ์ค์ต์ ArgoCD๋ก ์ด ๋ ๊ฐ์ง๋ฅผ ์ง์ ๊ตฌํํด๋ณธ ๊ธฐ๋ก์ ๋๋ค.
๐ค ArgoCD๋ฅผ ์ ์ฐ๋๊ฐ โ Push vs Pull
๊ธฐ์กด CI/CD ๋๊ตฌ(Jenkins ๋ฑ)๋ Push ๋ชจ๋ธ์ ๋๋ค. ์ธ๋ถ์์ ํด๋ฌ์คํฐ์ ์ ๊ทผ ๊ถํ์ ๊ฐ์ง๊ณ ๋ค์ด์์ ๋ฐฐํฌํฉ๋๋ค. ์๋ฒ ์ด์ ๋ฅผ ์ธ๋ถ์ ์ค์ผ ํ๋ ๊ตฌ์กฐ์ฃ .
ArgoCD๋ Pull ๋ชจ๋ธ์ ๋๋ค. ArgoCD๊ฐ ํด๋ฌ์คํฐ ์์ ์ด๋ฉด์ Git์ ๊ฐ์ํฉ๋๋ค. Git์ ๋ณ๊ฒฝ์ด ์๊ธฐ๋ฉด ์ค์ค๋ก ๊ฐ์ ธ์์ ์ ์ฉํฉ๋๋ค.
[๊ธฐ์กด Push ๋ฐฉ์]
Jenkins โ (ํด๋ฌ์คํฐ ์ ๊ทผ ๊ถํ ํ์) โ Kubernetes Cluster
[ArgoCD Pull ๋ฐฉ์]
Git Repository โ ArgoCD (ํด๋ฌ์คํฐ ๋ด๋ถ์์ ๊ฐ์) โ ์๋ ๋ฐฐํฌ
๋ณด์ ๊ด์ ์์ Pull์ด ์ ๋ฆฌํ ์ด์ : ์ธ๋ถ์์ ๋ค์ด์ค๋ ๊ฒ ์๋๋ผ ๋ด๋ถ์์ ๋๊ฐ๋ ๊ตฌ์กฐ์ด๋ฏ๋ก, ํด๋ฌ์คํฐ ์ธ์ฆ ์ ๋ณด๋ฅผ ์ธ๋ถ์ ์ค ํ์๊ฐ ์์ต๋๋ค.
๐ ๏ธ Step 1 โ ArgoCD ์ค์น
# ArgoCD๊ฐ ์ด ๋ค์์คํ์ด์ค ์์ฑ
kubectl create namespace argocd
# ๊ณต์ ๋งค๋ํ์คํธ๋ก ์ค์น (๋ชจ๋ ๋ฆฌ์์ค๊ฐ ํ ๋ฒ์)
kubectl apply -n argocd -f \
https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# ๋ชจ๋ ํ๋๊ฐ Running์ด ๋ ๋๊น์ง ๋๊ธฐ
kubectl get pods -n argocd -w
์ธ๋ถ ์ ์ ์ค์ (NodePort)
# ArgoCD UI์ ์ธ๋ถ์์ ์ ์ํ ์ ์๋๋ก NodePort๋ก ๋ณ๊ฒฝ
kubectl patch svc argocd-server -n argocd \
-p '{"spec": {"type": "NodePort"}}'
# ํ ๋น๋ ํฌํธ ํ์ธ
kubectl get svc argocd-server -n argocd
# PORT(S): 80:3xxxx/TCP, 443:3yyyy/TCP
์ด๊ธฐ admin ๋น๋ฐ๋ฒํธ ํ์ธ
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
๋ธ๋ผ์ฐ์ ์์ https://192.168.56.10:3xxxx๋ก ์ ์ โ admin / (์ ๋น๋ฐ๋ฒํธ)๋ก ๋ก๊ทธ์ธํฉ๋๋ค.
๐ Step 2 โ GitOps ํ์ดํ๋ผ์ธ ์ฐ๊ฒฐ
GitHub์ Helm Chart ์ฌ๋ฆฌ๊ธฐ
์ง๋ ์ค์ต์์ ๋ง๋ mywebapp Helm Chart๋ฅผ GitHub์ ์ฌ๋ฆฝ๋๋ค.
cd ~
git init
git add mywebapp
git commit -m "Add mywebapp helm chart: v.init"
git branch -M main
git remote add origin https://github.com/<๋ด์์ด๋>/helm-argocd-lab.git
git push -u origin main
ArgoCD Application ์ฃผ๋ฌธ์ ์์ฑ
ArgoCD์๊ฒ “์ด๋์ ๊ฐ์ ธ์์, ์ด๋์ ๋ฐฐํฌํด”๋ฅผ ์๋ ค์ฃผ๋ YAML ํ์ผ์ ๋๋ค.
# application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-webapp
namespace: argocd
spec:
project: default
# ์ด๋์ ๊ฐ์ ธ์? (Source)
source:
repoURL: https://github.com/<๋ด์์ด๋>/helm-argocd-lab.git
targetRevision: main
path: mywebapp # Git ์ ์ฅ์ ์์ ํด๋๋ช
# ์ด๋์ ๋ฐฐํฌํด? (Destination)
destination:
server: https://kubernetes.default.svc
namespace: default
# ์ด๋ป๊ฒ ๊ด๋ฆฌํด? (Sync Policy)
syncPolicy:
automated:
prune: true # Git์์ ํ์ผ ์ง์ฐ๋ฉด ํด๋ฌ์คํฐ์์๋ ์ญ์
selfHeal: true # ํด๋ฌ์คํฐ ์ํ๊ฐ Git๊ณผ ๋ฌ๋ผ์ง๋ฉด ์๋ ๋ณต๊ตฌ
kubectl apply -f application.yaml
ArgoCD ์น UI๋ฅผ ๋ณด๋ฉด my-webapp ์นด๋๊ฐ ์๊ธฐ๊ณ , ์ ์ ํ Synced โ
/ Healthy ๐ ์ํ๊ฐ ๋ฉ๋๋ค.

๐ฅ Step 3 โ GitOps ๋ฐฐํฌ ํ๋ฆ ํ์ธ
์ด์ ์ค์ GitOps๋ฅผ ์ฒดํํด๋ด
๋๋ค. kubectl edit ๋ช
๋ น์ด๋ฅผ ์ฐ์ง ์๊ณ , Git ์์ ๋ง์ผ๋ก ๋ฐฐํฌ๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค.
ArgoCD ์น UI์์ Progressing (ํ๋ ํ์ ) ์ํ๊ฐ ๋ณด์ด๋ฉด, ํ๋ ์์ฑ ์ค์ธ ๊ฒ๋๋ค.

๋ฐฐํฌ๊ฐ ์๋ฃ๋๋ฉด ํ๋, ์๋น์ค, Replica Set์ด ์ฐ๊ฒฐ๋ ํ ํด๋ก์ง ๊ทธ๋ํ๊ฐ ๋ณด์ ๋๋ค.

๐ก๏ธ Step 4 โ ์๊ฐ ์น์ (Self-Healing) ์คํ
ArgoCD์ ๊ฐ์ฅ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ํ ์คํธํด๋ดค์ต๋๋ค.
Git์๋ ํ๋ 2๊ฐ(replicaCount: 2)๋ผ๊ณ ์ ํ ์์ต๋๋ค. ๋๊ตฐ๊ฐ ์ค์๋ก ํ๋๋ฅผ ์ ๋ถ ์ง์๋ฒ๋ ธ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
# ํ๋๋ฅผ ๊ฐ์ ๋ก 0๊ฐ๋ก ์ถ์ (์ฌ๊ณ ์๋ฎฌ๋ ์ด์
)
kubectl scale deployment my-webapp-mywebapp --replicas=0
ArgoCD ์น UI๋ฅผ ๋ณด๋ฉด:
- ์๊ฐ์ ์ผ๋ก
OutOfSync(๋ ธ๋์) ํ์ โ “์ด? Git์ด๋ ๋ค๋ฅด๋ค?” - ์ฆ์ ์๋์ผ๋ก ํ๋ ์ฌ์์ฑ ์์
- ์ ์ ํ ๋ค์ ํ๋ 2๊ฐ๊ฐ
Running์ํ๋ก ๋ณต๊ตฌ

# ํ์ธ
kubectl get pods
# my-webapp-xxx Running โ ์ด์๋ฌ๋ค!
# my-webapp-yyy Running
๐ก GitOps ๋กค๋ฐฑ์ ๋ฒํผ์ด ์๋๋ผ Git revert
ArgoCD ์น UI์ ROLLBACK ๋ฒํผ์ด ์์ง๋ง, Auto Sync + Self Heal์ด ์ผ์ง ์ํ์์ ๋ฒํผ์ผ๋ก ๋กค๋ฐฑํด๋ ArgoCD๊ฐ ์ฆ์ ์ต์ Git ์ํ๋ก ๋๋๋ ค๋ฒ๋ฆฝ๋๋ค.
์ง์ ํ GitOps ๋กค๋ฐฑ์:
# Git์์ ์ด์ ์ปค๋ฐ์ผ๋ก ๋๋๋ฆฌ๊ธฐ
git revert HEAD
git push origin main
# ArgoCD๊ฐ ๊ฐ์งํ๊ณ ์๋์ผ๋ก ์ด์ ๋ฒ์ ๋ฐฐํฌ
Git์ด ์ง์ค์ ์์ฒ(Single Source of Truth)์ ๋๋ค. ํด๋ฌ์คํฐ ์ํ๋ ํญ์ Git๊ณผ ๋์ผํด์ผ ํฉ๋๋ค.
๐ ArgoCD ํต์ฌ ๋ช ๋ น์ด
| ๊ตฌ๋ถ | ๋ช ๋ น์ด | ์ค๋ช |
|---|---|---|
| ์ค์น | kubectl apply -n argocd -f [URL] | ArgoCD ์ค์น |
| ์ ์ | kubectl get svc argocd-server -n argocd | UI ํฌํธ ํ์ธ |
kubectl -n argocd get secret ... | base64 -d | ์ด๊ธฐ ๋น๋ฐ๋ฒํธ | |
| ๋ฐฐํฌ | kubectl apply -f application.yaml | App ์ฃผ๋ฌธ์ ์ ์ถ |
| Git | git add . && git commit -m "..." && git push | ๋ณ๊ฒฝ โ ์๋ ๋ฐฐํฌ ํธ๋ฆฌ๊ฑฐ |
| ๋ชจ๋ํฐ๋ง | kubectl get pods -w | ํ๋ ์์ฑ ์ค์๊ฐ ํ์ธ |
๐ ์ ์ฒด GitOps ํ๋ก์ฐ ์ ๋ฆฌ
[๊ฐ๋ฐ์]
โโ ์ฝ๋ ์์
โโ git push
[GitHub]
โโ ๋ณ๊ฒฝ ๊ฐ์ง๋จ
[ArgoCD (ํด๋ฌ์คํฐ ๋ด๋ถ)]
โโ Git ๋ณ๊ฒฝ ๊ฐ์ง (3๋ถ ์ฃผ๊ธฐ or Webhook)
โโ ์ YAML ๋ค์ด๋ก๋
โโ kubectl apply (์๋)
โโ ์ํ ๋ชจ๋ํฐ๋ง โ Self-Heal
[Kubernetes Cluster]
โโ ๋ฐฐํฌ ์๋ฃ โ
โ ๋ง์น๋ฉฐ
K8s ํด๋ฌ์คํฐ ๊ตฌ์ถ โ Helm์ผ๋ก ํจํค์ง โ ArgoCD๋ก GitOps ํ์ดํ๋ผ์ธ ์์ฑ. ์ด ์ธ ๋จ๊ณ๊ฐ ํ๋ ์ฟ ๋ฒ๋คํฐ์ค ์ด์์ ํต์ฌ ํ๋ฆ์ ๋๋ค.
ArgoCD๋ฅผ ์ฐ๊ณ ๋๋ฉด “๋๊ฐ, ์ธ์ , ๋ฌด์์ ๋ฐฐํฌํ๋์ง”๊ฐ ์ ๋ถ Git ํ์คํ ๋ฆฌ๋ก ๋จ์ต๋๋ค. ์ฌ๊ณ ๊ฐ ๋๋ ์์ธ์ ์ถ์ ํ๊ธฐ ์ฝ๊ณ , ๋กค๋ฐฑ๋ git revert ํ ์ค์ด๋ฉด ๋ฉ๋๋ค. ๋ฐฐํฌ๊ฐ ์ฝ๋๋ก ๊ด๋ฆฌ๋๋ ์ธ์, GitOps์
๋๋ค.