Skip to content

Argo CD

Argo CD คือเครื่องมือ GitOps continuous delivery สำหรับ Kubernetes ที่คอยเปรียบเทียบ desired state ใน Git กับ resources ที่อยู่ใน cluster แล้ว sync ให้ตรงกัน รองรับ Helm, Kustomize, plain YAML และ Jsonnet

  • GitOps — Git เป็น source of truth สำหรับ Kubernetes manifests และ deployment history
  • Continuous reconciliation — ตรวจจับ configuration drift และ sync กลับสู่ desired state ได้อัตโนมัติ
  • Multi-cluster — จัดการ application บนหลาย Kubernetes clusters จาก Argo CD instance เดียว
  • Access control — กำหนดสิทธิ์ด้วย Project, RBAC และ SSO/OIDC

Application คือ resource ที่บอก Argo CD ว่า manifests อยู่ Git repository ใด, deploy ไป cluster/namespace ใด และจะ sync ด้วยวิธีใด

Project ใช้กำหนดขอบเขตของ Application เช่น repository ที่อนุญาต, destination cluster/namespace และ resource kinds ที่ deploy ได้

  • Synced — resources ใน cluster ตรงกับ manifests ใน Git
  • OutOfSync — resources ต่างจาก desired state หรือยังไม่เคย deploy
  • Unknown — Argo CD อ่านสถานะ resource ไม่ได้
  • Healthy — application พร้อมใช้งาน
  • Progressing — กำลัง rollout หรือรอ resource พร้อม
  • Degraded — resource ทำงานผิดปกติ เช่น Deployment มี replica ไม่พร้อม
Avatar whiteCat
Argo CD ไม่ได้สร้าง pipeline เอง แต่ทำหน้าที่ deploy state ที่อยู่ใน Git ไปยัง Kubernetes. CI สามารถ build image แล้ว commit tag ใหม่กลับเข้า Git เพื่อให้ Argo CD sync ต่อได้
Terminal window
# สร้าง namespace สำหรับ Argo CD
kubectl create namespace argocd
# ติดตั้ง Argo CD แบบ stable ด้วย server-side apply
kubectl apply -n argocd --server-side --force-conflicts -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# รอให้ pods พร้อมใช้งาน
kubectl wait --for=condition=Ready pods --all -n argocd --timeout=300s
Terminal window
# ติดตั้ง Argo CD CLI บน macOS ด้วย Homebrew
brew install argocd
# ตรวจสอบ version ของ CLI
argocd version --client
Terminal window
# เปิด Argo CD API server ผ่าน local port 8080
kubectl port-forward svc/argocd-server -n argocd 8080:443
# อ่าน password เริ่มต้นของ admin
argocd admin initial-password -n argocd
# login ผ่าน CLI โดยไม่ตรวจสอบ TLS สำหรับ port-forward
argocd login localhost:8080 --username admin --insecure

เปิด UI ที่ https://localhost:8080 แล้ว login ด้วย user admin และ password ที่อ่านได้จากคำสั่งข้างต้น

Avatar blackCat
เปลี่ยน password ของ admin หลัง login ครั้งแรก และตั้งค่า Ingress พร้อม TLS ก่อนเปิดให้ใช้งานนอก cluster

ดูและสร้าง Application

Section titled “ดูและสร้าง Application”
Terminal window
# แสดง applications ทั้งหมด
argocd app list
# ดูรายละเอียดและสถานะของ application
argocd app get my-app
# สร้าง application จาก manifests ใน Git
argocd app create my-app \
--repo https://github.com/example/platform-config.git \
--path apps/my-app \
--dest-server https://kubernetes.default.svc \
--dest-namespace production
Terminal window
# sync application ให้ state ใน cluster ตรงกับ Git
argocd app sync my-app
# ดู resource tree และ health แบบต่อเนื่อง
argocd app wait my-app --health --sync --timeout 300
# ดู deployment history
argocd app history my-app
# rollback ไปยัง history ID ที่ต้องการ
argocd app rollback my-app <history-id>
# ลบ application และ resources ที่ Argo CD จัดการ
argocd app delete my-app --cascade
Terminal window
# refresh ข้อมูล application จาก Git และ cluster
argocd app get my-app --refresh
# เปรียบเทียบ desired state ใน Git กับ resources ใน cluster
argocd app diff my-app
# ดู logs ของ resource ใน application
argocd app logs my-app

เก็บ Application manifest ไว้ใน Git เพื่อให้การตั้งค่า Argo CD เองเป็น GitOps ด้วย:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/example/platform-config.git
targetRevision: main
path: apps/my-app
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
FieldDescription
source.repoURLGit repository ที่เก็บ manifests หรือ Helm chart
source.targetRevisionbranch, tag หรือ commit SHA ที่ต้องการ deploy
source.pathdirectory ของ manifests ภายใน repository
destination.serverKubernetes API endpoint, ใน cluster ใช้ https://kubernetes.default.svc
destination.namespacenamespace ปลายทางของ resources
automated.pruneลบ resources ที่เอาออกจาก Git
automated.selfHealsync กลับเมื่อมีการแก้ resources โดยตรงใน cluster
Avatar blackCat
เปิด prune เมื่อมั่นใจว่า Git เก็บ resources ครบ เพราะ resource ที่ลบออกจาก Git อาจถูก Argo CD ลบออกจาก cluster ด้วย
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx
namespace: argocd
spec:
project: default
source:
repoURL: https://charts.bitnami.com/bitnami
chart: nginx
targetRevision: 22.0.0
helm:
parameters:
- name: service.type
value: ClusterIP
destination:
server: https://kubernetes.default.svc
namespace: nginx
source:
repoURL: https://github.com/example/platform-config.git
targetRevision: main
path: apps/my-app/overlays/production
kustomize:
images:
- ghcr.io/example/my-app:1.2.3
Terminal window
# เพิ่ม private Git repository ด้วย HTTPS credentials
argocd repo add https://github.com/example/private-config.git \
--username <git-username> \
--password <access-token>
# แสดง repositories ที่ Argo CD เชื่อมต่ออยู่
argocd repo list
# เพิ่ม Kubernetes context ปัจจุบันให้ Argo CD จัดการ
argocd cluster add <kube-context>
# แสดง clusters ที่เชื่อมต่ออยู่
argocd cluster list

สำหรับ Git provider ควรใช้ deploy key หรือ access token แบบ read-only และเก็บ credentials ใน secret manager เมื่อใช้งานจริง

เชื่อม Git repository ด้วย SSH

Section titled “เชื่อม Git repository ด้วย SSH”
Terminal window
# สร้าง SSH key เฉพาะสำหรับ Argo CD (ไม่มี passphrase)
ssh-keygen -t ed25519 -b 4096 -C "argocd-repo" -f argocd-key -N ""
# เพิ่ม public key เป็น deploy key (read-only) ใน GitHub:
# Settings > Deploy keys > Add deploy key แล้ววาง argocd-key.pub
# เพิ่ม private Git repository ด้วย SSH private key
argocd repo add git@github.com:example/private-config.git \
--ssh-private-key-path ./argocd-key
# แสดง repositories ที่เชื่อมต่ออยู่ พร้อมตรวจสอบ connection status
argocd repo list

ถ้าต้องใช้ SSH ผ่าน port 443 (กรณี network บล็อก port 22) ให้เขียน known hosts ทับแล้วระบุ URL แบบ ssh://:

Terminal window
# override known_hosts ด้วย host key ของ ssh.github.com port 443
argocd repo add ssh://git@ssh.github.com:443/example/private-config.git \
--ssh-private-key-path ./argocd-key \
--insecure-ignore-host-key

ตัวอย่าง Project สำหรับจำกัดทีม payments ให้ deploy ได้เฉพาะ repository และ namespace ที่ระบุ:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: payments
namespace: argocd
spec:
description: Applications owned by the payments team
sourceRepos:
- https://github.com/example/payments-config.git
destinations:
- namespace: payments-*
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: ''
kind: Namespace
Terminal window
# แสดง projects ทั้งหมด
argocd proj list
# ดู policy และขอบเขตของ project
argocd proj get payments
# สร้าง role ใน project สำหรับผู้ที่ sync application ได้
argocd proj role create payments deployer
# เพิ่ม policy ให้ role sync applications ใน project
argocd proj role add-policy payments deployer \
--action sync \
--object 'payments/*' \
--permission allow

การ stop service ทำได้ด้วยการ scale Deployment เป็น 0 replicas แต่เมื่อใช้ร่วมกับ Argo CD ต้องระวังระบบ Auto Sync กับ selfHeal ที่อาจ scale กลับตามค่าใน Git รวมถึง HPA ที่คุม replicas อยู่

Scale เป็น 0 แบบชั่วคราว

Section titled “Scale เป็น 0 แบบชั่วคราว”

สมมติมี Deployment ชื่อ one-id-service ใน namespace production:

Terminal window
# scale deployment เป็น 0 replicas เพื่อ stop service
kubectl scale deployment one-id-service --replicas=0 -n production
# ตรวจสอบว่า pods ถูก terminate หมดแล้ว
kubectl get pods -n production
# ตรวจสอบ replicas ของ deployment (ควรเห็น 0/0)
kubectl get deployment one-id-service -n production
Avatar blackCat
ถ้า Argo CD เปิด selfHeal: true ไว้ จะตรวจพบว่า replicas ไม่ตรงกับ Git แล้วปรับกลับเป็นค่าเดิม และถ้ามี HPA คุม Deployment อยู่ก็อาจ scale กลับเช่นกัน ตรวจสอบด้วย kubectl get hpa -n production

Stop แบบ GitOps (แนะนำสำหรับ Maintenance)

Section titled “Stop แบบ GitOps (แนะนำสำหรับ Maintenance)”

แก้ replicas ใน Git แล้วให้ Argo CD sync เอง เพื่อให้ Git ยังเป็น single source of truth:

apiVersion: apps/v1
kind: Deployment
metadata:
name: one-id-service
spec:
# เดิมเป็น 3 เปลี่ยนเป็น 0 เพื่อ stop service
replicas: 0
Terminal window
# commit และ push แล้ว Argo CD จะตรวจพบการเปลี่ยนแปลงและ terminate pods ทั้งหมด
git commit -m "stop one-id-service for maintenance" && git push

เมื่อ maintenance เสร็จ เปลี่ยน replicas กลับเป็นค่าเดิมแล้ว push ได้เลย

กรณี production มีปัญหาและต้องหยุด service ทันทีโดยไม่รอ Git:

Terminal window
# step 1: ปิด auto-sync ชั่วคราวกัน Argo CD แก้ค่ากลับ
argocd app set one-id-service --sync-policy none
# step 2: scale เป็น 0
kubectl scale deployment one-id-service --replicas=0 -n production
# step 3: ตรวจสอบผลลัพธ์
kubectl get deployment one-id-service -n production

เมื่อแก้ปัญหาเสร็จ ให้ reconcile ค่าเข้า Git ก่อน แล้วค่อยเปิด auto-sync กลับ:

Terminal window
# แก้ replicas ใน Git ให้ตรงกับ state ที่ต้องการ แล้ว sync
argocd app sync one-id-service
# เปิด auto-sync กลับพร้อม self-heal
argocd app set one-id-service --sync-policy automated --self-heal
Avatar blackCat
ถ้า Application ถูกสร้างจาก ApplicationSet การปิด auto-sync อาจถูกคืนค่ากลับมา ต้องแก้นโยบายที่ template ต้นทางด้วย และการปิด auto-sync ไม่ได้หยุด HPA
Terminal window
# เปิด k9s ที่ namespace production
k9s -n production

จากนั้นพิมพ์ :deploy เลือก Deployment ที่ต้องการ กด s เพื่อ scale ใส่ 0 แล้ว confirm — ต้องระวัง selfHeal เหมือนกัน

สิ่งที่ไม่ควรทำ

Section titled “สิ่งที่ไม่ควรทำ”
Terminal window
# อย่าใช้ delete pod เพื่อ stop service เพราะ Deployment controller จะสร้าง pod ใหม่ทันที
kubectl delete pod one-id-service-xxxxx

การ delete pod เหมาะกับการ restart หรือ replace pod มากกว่า สำหรับ restart ให้ใช้:

Terminal window
# rolling restart ทั้ง deployment
kubectl rollout restart deployment/one-id-service -n production

สรุปวิธีเลือกใช้

Section titled “สรุปวิธีเลือกใช้”
สถานการณ์วิธีแนะนำ
Restart podkubectl rollout restart
Stop ชั่วคราวScale replicas = 0
Stop แบบ GitOpsแก้ replicas: 0 ใน Git
Stop ฉุกเฉินปิด auto-sync แล้ว scale 0
Stop ผ่าน k9sScale deployment เป็น 0
Stop ถาวรลบ Deployment จาก Git แล้ว sync
Avatar whiteCat
สำหรับ production ควรกำหนดแนวทาง maintenance ไว้เลย: Planned Maintenance ทำผ่าน GitOps, Emergency Operation ใช้ kubectl/k9s แล้ว reconcile กลับเข้า Git, ส่วน restart ปกติใช้ rolling restart — เพราะในระยะยาวเราไม่ควรต้องปิด auto-sync ทุกครั้งที่ maintenance