Giao diện
Challenge: GitOps Drift Scenario
🎮 Thử thách dành cho Senior Operator - HPN
Module này là bài thực hành hands-on để hiểu sâu về GitOps Drift Detection và Self-Healing trong ArgoCD.
🎭 Kịch Bản: "The Naughty Junior"
Bối cảnh
Bạn là Senior Operator tại HPN. Hệ thống đang chạy ổn định với GitOps:
yaml
# Git Repository: k8s-manifests/apps/my-app/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: production
spec:
replicas: 3 # 👈 Đây là "Desired State" từ Git
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: hpn/my-app:v1.2.3
resources:
requests:
memory: "128Mi"
cpu: "100m"ArgoCD đã sync thành công. Cluster đang chạy 3 replicas.
Sự cố xảy ra
Một junior engineer mới vào công ty, chưa quen với quy trình GitOps. Vào lúc 2 giờ sáng, khi hệ thống báo high load, junior hoảng loạn và chạy:
bash
# ❌ Junior's "quick fix"
kubectl scale deployment my-app --replicas=5 -n production📝 Câu Hỏi Cho Học Viên
Question 1: ArgoCD Status hiển thị gì?
Sau khi junior chạy kubectl scale, bạn mở ArgoCD UI. Status của Application sẽ hiển thị gì?
💡 Click để xem đáp án
Đáp án: OutOfSync ⚠️
text
Application Status:
├── Sync Status: OutOfSync
├── Health Status: Healthy
└── Summary:
└── Deployment my-app: Live differs from Desired
└── spec.replicas: 5 (live) ≠ 3 (desired)Giải thích:
- Live State (Cluster):
replicas: 5 - Desired State (Git):
replicas: 3 - ArgoCD phát hiện sự khác biệt → OutOfSync
bash
# Kiểm tra bằng CLI
argocd app diff my-app
# Output hiển thị:
# ===== apps/Deployment production/my-app ======
# --- Desired
# +++ Live
# @@ -1,5 +1,5 @@
# spec:
# - replicas: 3
# + replicas: 5Question 2: Điều gì xảy ra nếu Self-Healing được bật?
Giả sử ArgoCD Application được cấu hình với selfHeal: true. Điều gì xảy ra ngay sau khi junior chạy lệnh scale?
💡 Click để xem đáp án
Đáp án: ArgoCD ngay lập tức "giết" 2 pods để quay về 3 replicas
Timeline thực tế:
| Time | Event |
|---|---|
| T+0s | Junior runs kubectl scale --replicas=5 |
| T+0s | Kubernetes creates 2 new pods |
| T+3s | ArgoCD detects drift (sync interval) |
| T+5s | ArgoCD applies desired state (replicas: 3) |
| T+7s | Kubernetes terminates 2 excess pods |
| T+10s | Junior: "WTF?!" 😱 |
Log message trong ArgoCD:
text
[INFO] Detected drift in Deployment/my-app: spec.replicas 5 -> 3
[INFO] Auto-syncing due to selfHeal policy
[INFO] Successfully synced (dry run: false)Question 3: Tại sao đây là điều tốt cho Security?
Giải thích tại sao hành vi self-healing này lại tăng cường bảo mật cho hệ thống?
💡 Click để xem đáp án
Đáp án: Ngăn chặn unauthorized changes & đảm bảo audit trail
| Security Benefit | Giải thích |
|---|---|
| Prevent unauthorized changes | Kể cả attacker có cluster access, không thể thay đổi persistent state |
| Immutable infrastructure | Cluster state luôn khớp với Git (reviewed & approved) |
| Audit trail | Mọi thay đổi hợp lệ đều có Git commit → Biết ai, khi nào, tại sao |
| Blast radius limitation | Manual changes chỉ tồn tại trong vài giây |
| Compliance | Đáp ứng yêu cầu SOC2, ISO27001 về change management |
Kịch bản tấn công bị chặn:
Nếu không có GitOps:
- Attacker modify → Changes persist
- Không ai biết cho đến khi incident xảy ra
- Không có baseline để rollback
Với GitOps + Self-Heal:
- Attacker modify → ArgoCD revert trong < 10 giây
- Alert được trigger
- Git = trusted state, không bị compromise
🛠️ Challenge Code: Cấu hình ArgoCD Application
Yêu cầu
Viết một ArgoCD Application CRD với các tính năng:
- ✅ Automated Sync - Tự động deploy khi Git thay đổi
- ✅ Self-Healing - Tự động fix drift
- ✅ Prune - Xóa resources không còn trong Git
- ✅ Create Namespace - Tự tạo namespace nếu chưa có
Template
yaml
# Điền vào chỗ trống (???)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app-production
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/hpn/k8s-manifests.git
targetRevision: main
path: apps/my-app/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
???💡 Click để xem Solution
yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app-production
namespace: argocd
# Thêm finalizer để an toàn khi xóa Application
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://github.com/hpn/k8s-manifests.git
targetRevision: main
path: apps/my-app/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
# ⚡ SYNC POLICY - Đây là phần quan trọng nhất!
syncPolicy:
# Tự động sync khi có thay đổi
automated:
# Xóa resources không còn trong Git
prune: true
# TỰ ĐỘNG FIX DRIFT - Self-healing!
selfHeal: true
# Cho phép sync nếu có resource đang OutOfSync
allowEmpty: false
# Sync options bổ sung
syncOptions:
# Tự tạo namespace nếu chưa tồn tại
- CreateNamespace=true
# Validate YAML trước khi apply
- Validate=true
# Sử dụng server-side apply (K8s 1.22+)
- ServerSideApply=true
# Retry policy cho trường hợp sync fail
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3mGiải thích các config quan trọng:
| Config | Giá trị | Ý nghĩa |
|---|---|---|
automated.prune | true | Xóa resource khi bị remove khỏi Git |
automated.selfHeal | true | Tự động revert manual changes |
syncOptions.CreateNamespace | true | Tự tạo namespace |
retry.limit | 5 | Retry tối đa 5 lần nếu sync fail |
📊 Kiến Thức Bổ Sung
Sync Waves & Hooks
Trong production, bạn có thể cần kiểm soát thứ tự sync:
yaml
# ConfigMap phải được tạo TRƯỚC Deployment
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config
annotations:
argocd.argoproj.io/sync-wave: "-1" # Sync trước
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
annotations:
argocd.argoproj.io/sync-wave: "0" # Sync sauHealth Checks Custom
yaml
# argocd-cm ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
resource.customizations.health.mycrd.example.com_MyResource: |
hs = {}
if obj.status ~= nil then
if obj.status.phase == "Running" then
hs.status = "Healthy"
else
hs.status = "Progressing"
end
end
return hs✅ Checklist Hoàn Thành
Học viên đã hoàn thành challenge khi:
- [ ] Hiểu được OutOfSync status nghĩa là gì
- [ ] Giải thích được cơ chế Self-Healing của ArgoCD
- [ ] Liệt kê được ít nhất 3 lợi ích security của GitOps
- [ ] Viết được ArgoCD Application CRD đầy đủ tính năng
- [ ] Hiểu được tại sao không nên dùng
kubectl applytrực tiếp
🔗 Liên kết
- Module liên quan: Module 13: GitOps với ArgoCD
- Module liên quan: Module 14: CI/CD Pipeline Strategy
- Tiếp theo: Module 7: Network Policy