Lab 21 — Final Project: Production GitOps Platform với ArgoCD
🎯 1. Mục tiêu
Sau Lab này, bạn sẽ tự xây dựng được một quy trình GitOps hoàn chỉnh:
- Hiểu cách CI/CD và GitOps phối hợp với nhau.
- Dùng Git làm Source of Truth cho Kubernetes.
- Dùng GitHub Actions để build và push Docker Image.
- Dùng ArgoCD để tự động deploy Application lên Kubernetes.
- Quản lý
devvàproductionbằng GitOps. - Thiết lập Auto Sync, Self-Healing và Rollback.
- Kết nối GitOps với Prometheus + Grafana để quan sát hệ thống.
- Biết cách debug một deployment GitOps khi production gặp sự cố.
🤔 2. Vấn đề thực tế
Ở những Lab trước, chúng ta đã biết cách deploy Kubernetes:
kubectl apply -f deployment.yaml
Cách này rất dễ học.
Nhưng hãy tưởng tượng bạn đang làm production.
Developer push code:
Developer
│
│ git push
▼
GitHub
Docker Image được build:
app:v1.0.0
Sau đó bạn phải SSH vào server hoặc chạy:
kubectl set image deployment/backend \
backend=my-registry/backend:v1.0.0
Vài ngày sau có 10 services.
Một tháng sau có:
dev
staging
production
Lúc này việc deploy thủ công bắt đầu trở thành vấn đề.
😵 2.1. Những vấn đề sẽ xuất hiện
1. Không biết production đang chạy version nào
Bạn phải nhớ:
Backend → v1.3.2
Frontend → v2.1.0
Worker → v1.8.4
2. Configuration dễ bị lệch
Git nói:
replicas: 3
Nhưng Kubernetes thực tế lại là:
replicas: 5
3. Khó audit
Ai đã deploy?
Deploy lúc nào?
Deploy version nào?
Tại sao deployment thay đổi?
4. Rollback khó
Nếu version mới lỗi, bạn phải nhớ version cũ và tự chạy command rollback.
🧠 3. GitOps giải quyết vấn đề như thế nào?
GitOps thay đổi một nguyên tắc rất quan trọng:
Git không chỉ lưu source code. Git còn lưu trạng thái mong muốn của hệ thống.
Ví dụ:
Git
│
├── frontend
│ └── image: frontend:v1.2.0
│
├── backend
│ └── image: backend:v1.5.0
│
└── production
└── replicas: 3
Git trở thành:
Source of Truth
ArgoCD liên tục so sánh:
Git
Desired State
│
│ compare
▼
Kubernetes
Actual State
Nếu khác nhau:
Git:
replicas = 3
Kubernetes:
replicas = 1
ArgoCD phát hiện:
OUT OF SYNC
và có thể tự động sửa lại.
Đó chính là Self-Healing.
🧠 4. Hiểu nhanh Architecture
Trong Final Project này, chúng ta xây dựng flow:
┌──────────────────┐
│ Developer │
└────────┬─────────┘
│
git push
│
▼
┌──────────────────┐
│ GitHub │
│ Application │
│ Repo │
└────────┬─────────┘
│
│ CI
▼
┌──────────────────┐
│ GitHub Actions │
│ │
│ Test │
│ Build Image │
│ Push Registry │
└────────┬─────────┘
│
│ update image tag
▼
┌──────────────────┐
│ GitOps Repository│
│ │
│ dev/ │
│ production/ │
└────────┬─────────┘
│
│ watch Git
▼
┌──────────────────┐
│ ArgoCD │
│ │
│ Sync │
│ Self-Healing │
│ Rollback │
└────────┬─────────┘
│
│ deploy
▼
┌──────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌────────┐ ┌────────┐ │
│ │Frontend│ │ Backend│ │
│ └────────┘ └────────┘ │
│ │
└──────────────┬───────────────┘
│
│ metrics
▼
┌──────────────────┐
│ Prometheus │
│ Grafana │
└──────────────────┘
Điểm quan trọng nhất:
Developer
↓
GitHub
↓
CI
↓
Docker Image
↓
GitOps Repo
↓
ArgoCD
↓
Kubernetes
CI tạo artifact.
GitOps quyết định version nào được deploy.
ArgoCD thực hiện deployment.
🏗️ 5. Chuẩn bị môi trường
5.1. Kiến trúc Lab
Chúng ta sử dụng:
macOS
│
├── Docker
│
└── Minikube
│
├── ArgoCD
│
├── Todo Frontend
│
├── Todo Backend
│
├── PostgreSQL
│
└── Monitoring
├── Prometheus
└── Grafana
Bạn có thể dùng Minikube giống các Lab Kubernetes trước.
Kiểm tra:
kubectl get nodes
Kết quả mong đợi:
NAME STATUS ROLES AGE
minikube Ready control-plane ...
Kiểm tra ArgoCD:
kubectl get pods -n argocd
Nếu chưa cài ArgoCD, cài:
kubectl create namespace argocd
kubectl apply \
-n argocd \
-f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Chờ các Pod chạy:
kubectl get pods -n argocd
📁 6. Thiết kế GitOps Repository
🤔 Tại sao phải tách GitOps Repository?
Một sai lầm phổ biến của người mới là đặt tất cả vào một repository:
my-app/
├── src/
├── Dockerfile
├── package.json
├── deployment.yaml
└── service.yaml
Điều này vẫn chạy được.
Nhưng khi hệ thống lớn hơn, việc tách:
Application Code
và:
Deployment Configuration
sẽ dễ quản lý hơn.
Chúng ta tạo:
todo-app/
và:
todo-app-gitops/
📂 7. Cấu trúc GitOps Repository
Chúng ta sử dụng Kustomize:
todo-app-gitops/
│
├── base/
│ ├── namespace.yaml
│ ├── backend-deployment.yaml
│ ├── backend-service.yaml
│ ├── frontend-deployment.yaml
│ ├── frontend-service.yaml
│ ├── postgres-deployment.yaml
│ ├── postgres-service.yaml
│ └── kustomization.yaml
│
└── overlays/
│
├── dev/
│ ├── kustomization.yaml
│ └── patch.yaml
│
└── production/
├── kustomization.yaml
└── patch.yaml
Ý tưởng:
base
│
┌───────┴────────┐
▼ ▼
dev production
base chứa cấu hình chung.
overlay chứa khác biệt của từng environment.
🧩 8. Tạo Base
8.1. base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- backend-deployment.yaml
- backend-service.yaml
- frontend-deployment.yaml
- frontend-service.yaml
- postgres-deployment.yaml
- postgres-service.yaml
Kustomize sẽ gom các Kubernetes Manifest thành một Application.
🧩 9. Tạo Environment Dev
Tạo:
overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: todo-dev
resources:
- ../../base
Dev sử dụng cấu hình từ base.
Sau này chúng ta có thể override:
replicas
image
resources
environment variables
mà không cần copy toàn bộ manifest.
🏭 10. Tạo Environment Production
Tạo:
overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: todo-production
resources:
- ../../base
Bây giờ repository có:
base
│
├── dev
│
└── production
🔍 11. Kiểm tra trước khi deploy
Đây là một thói quen rất quan trọng trong production.
Không nên commit Kubernetes Manifest mà chưa biết nó generate ra cái gì.
Chạy:
kubectl kustomize overlays/dev
Nếu muốn kiểm tra production:
kubectl kustomize overlays/production
Bạn sẽ thấy toàn bộ Kubernetes Manifest sau khi Kustomize render.
🚀 12. Tạo ArgoCD Application
🤔 Tại sao cần Application?
ArgoCD cần biết:
"Tôi phải lấy configuration ở đâu và deploy vào Kubernetes nào?"
ArgoCD Application chính là object mô tả điều đó.
Tạo:
argocd/todo-dev.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: todo-dev
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/YOUR_USERNAME/todo-app-gitops.git
targetRevision: main
path: overlays/dev
destination:
server: https://kubernetes.default.svc
namespace: todo-dev
syncPolicy:
automated:
prune: true
selfHeal: true
Thay:
YOUR_USERNAME
bằng GitHub username của bạn.
🧠 13. Hiểu syncPolicy
Đây là phần rất quan trọng.
syncPolicy:
automated:
prune: true
selfHeal: true
Có thể hiểu:
Git
│
│ desired state
▼
ArgoCD
│
├── Difference?
│ │
│ └── YES
│ │
│ ▼
│ Sync
│
├── Resource deleted?
│ │
│ └── prune
│
└── Kubernetes changed manually?
│
└── selfHeal
automated
Cho phép ArgoCD tự động Sync.
prune
Nếu resource đã bị xóa khỏi Git:
Git:
Deployment
Service
Sau đó Git chỉ còn:
Service
ArgoCD có thể xóa Deployment khỏi Kubernetes.
selfHeal
Nếu ai đó chạy:
kubectl scale deployment backend --replicas=10
trong khi Git quy định:
replicas = 3
ArgoCD sẽ phát hiện drift và đưa hệ thống về trạng thái trong Git.
🚀 14. Deploy Application bằng ArgoCD
Apply Application:
kubectl apply -f argocd/todo-dev.yaml
Kiểm tra:
kubectl get applications -n argocd
Bạn sẽ thấy:
NAME SYNC STATUS HEALTH STATUS
todo-dev Synced Healthy
Kiểm tra namespace:
kubectl get all -n todo-dev
👀 15. Xem ArgoCD UI
Lấy password:
kubectl -n argocd \
get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 --decode
Port-forward:
kubectl port-forward svc/argocd-server \
-n argocd 8080:443
Mở:
https://localhost:8080
Đăng nhập:
Username:
admin
Password:
<password lấy ở trên>
Bạn sẽ thấy:
todo-dev
│
├── Synced
└── Healthy
🧪 16. Test GitOps — Thay đổi Application
Đây mới là phần quan trọng nhất của Lab.
Giả sử hiện tại Backend:
replicas: 1
Thay đổi GitOps:
replicas: 2
Commit:
git add .
git commit -m "scale backend to 2 replicas"
git push
👀 17. See Result
Kiểm tra ArgoCD.
Bạn sẽ thấy:
Git
replicas: 2
│
▼
ArgoCD
│
▼
Kubernetes
replicas: 2
Kiểm tra:
kubectl get pods -n todo-dev
Có thể thấy:
backend-xxxxx Running
backend-yyyyy Running
Bạn vừa thực hiện deployment mà không chạy kubectl apply.
Đó chính là GitOps.
🔥 18. Test Self-Healing
Bây giờ thử cố tình thay đổi Kubernetes bằng tay.
Ví dụ:
kubectl scale deployment backend \
-n todo-dev \
--replicas=5
Kiểm tra:
kubectl get deployment -n todo-dev
Bạn sẽ thấy:
READY
5/5
Nhưng Git vẫn nói:
replicas: 2
ArgoCD phát hiện:
Desired State = 2
Actual State = 5
Sau một khoảng thời gian, ArgoCD sẽ đưa hệ thống trở về:
2 replicas
Kiểm tra:
kubectl get deployment -n todo-dev
🧠 19. Điều gì vừa xảy ra?
Bạn vừa thấy một trong những điểm mạnh nhất của GitOps:
Git
│
Desired = 2
│
▼
ArgoCD
│
compare state
│
▼
Kubernetes
Actual = 5
│
│ drift
▼
Self-Heal
│
▼
Actual = 2
Điều này đặc biệt hữu ích trong production.
Nếu một người vô tình thay đổi production bằng:
kubectl edit
GitOps có thể phát hiện và sửa lại.
🔄 20. Test Rollback
Giả sử production đang chạy:
backend:v1.0.0
Bạn release:
backend:v1.1.0
Nhưng version mới có bug.
Git history:
commit A
backend:v1.0.0
commit B
backend:v1.1.0
Rollback rất đơn giản:
git revert <commit-B>
Sau đó:
git push
Flow:
Git
│
│ revert
▼
ArgoCD
│
│ Sync
▼
Kubernetes
│
▼
backend:v1.0.0
Đây là một cách rollback rất đẹp vì:
Rollback cũng được thực hiện thông qua Git.
🔐 21. GitOps Secrets
Một vấn đề bắt đầu xuất hiện:
Chúng ta có:
DATABASE_PASSWORD
JWT_SECRET
API_KEY
Không được commit:
password: my-secret-password
vào Git.
Trong production, bạn có thể sử dụng:
External Secrets
hoặc:
Sealed Secrets
hoặc secret manager như:
AWS Secrets Manager
HashiCorp Vault
Google Secret Manager
Azure Key Vault
Mô hình:
Git
│
│ reference
▼
Secret Manager
│
│ secret
▼
Kubernetes Secret
│
▼
Application
Điểm cần nhớ:
GitOps không có nghĩa là commit plaintext secrets vào Git.
⚙️ 22. Kết nối CI với GitOps
Bây giờ chúng ta hoàn thiện pipeline.
Developer sửa code:
src/
Push:
git push
GitHub Actions chạy:
Test
↓
Build
↓
Docker Image
↓
Push Registry
Ví dụ:
backend:v1.2.0
Sau đó CI cập nhật GitOps repository:
image: backend:v1.2.0
ArgoCD phát hiện Git thay đổi:
GitOps Repo
│
▼
ArgoCD
│
▼
Kubernetes
🔄 23. Full CI/CD + GitOps Flow
Đây là flow bạn nên nhớ sau Final Project:
Developer
│
│ git push
▼
┌──────────────┐
│ GitHub │
│ Application │
└──────┬───────┘
│
▼
┌──────────────────┐
│ GitHub Actions │
│ │
│ Test │
│ Build │
│ Docker Push │
└────────┬─────────┘
│
│ image:v1.2.0
▼
┌──────────────────┐
│ GitOps Repository│
│ │
│ image:v1.2.0 │
└────────┬─────────┘
│
│ Git change
▼
┌──────────────────┐
│ ArgoCD │
│ │
│ Detect Diff │
│ Sync │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Kubernetes │
│ │
│ backend:v1.2.0 │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Prometheus │
│ Grafana │
└──────────────────┘
📊 24. Monitoring Deployment
GitOps giúp deploy.
Nhưng deploy xong chưa có nghĩa là Application khỏe.
Ví dụ:
ArgoCD:
Healthy ✅
Application:
HTTP 500 ❌
Đây là lý do cần Monitoring.
Nếu bạn đã triển khai Prometheus + Grafana ở các Lab trước, hãy kiểm tra:
CPU
Memory
Request Rate
Request Latency
HTTP 5xx
Pod Restart
Một flow production hoàn chỉnh sẽ là:
Git
↓
ArgoCD
↓
Kubernetes
↓
Application
↓
Prometheus
↓
Grafana
🚨 25. Test Production Incident
Hãy mô phỏng một sự cố.
Ví dụ Backend bị crash:
kubectl delete pod \
-n todo-production \
-l app=todo-backend
Kubernetes sẽ tạo Pod mới.
Kiểm tra:
kubectl get pods -n todo-production
Bạn sẽ thấy:
old pod
↓
Terminating
new pod
↓
Running
ArgoCD vẫn giữ trạng thái:
Synced
Healthy
Điều này cho thấy:
Kubernetes chịu trách nhiệm duy trì Application runtime.
ArgoCD chịu trách nhiệm đảm bảo Kubernetes khớp với Git.
Prometheus/Grafana chịu trách nhiệm cho bạn biết hệ thống đang hoạt động thế nào.
Ba thành phần có vai trò khác nhau.
🏭 26. Production Environment
Bây giờ tạo:
overlays/production/
Production nên khác Dev.
Ví dụ:
replicas: 3
Trong khi Dev:
replicas: 1
Architecture:
base
│
┌─────────┴─────────┐
▼ ▼
dev production
replicas=1 replicas=3
Đây là lý do Kustomize rất hữu ích trong GitOps.
🛡️ 27. Production Safety Rule
Một nguyên tắc quan trọng:
Không nên cho mọi thay đổi vào production tự động ngay lập tức.
Có thể áp dụng:
Development
│
│ Auto Sync
▼
Production
│
│ Pull Request
│
▼
Code Review
│
│ Approve
▼
Merge
│
▼
ArgoCD
│
▼
Production
Ví dụ:
feature branch
↓
PR
↓
review
↓
merge main
↓
ArgoCD
↓
production
Điều này tạo ra một audit trail rõ ràng.
🧪 28. Final Exercise
Bây giờ hãy tự thực hiện toàn bộ flow mà không nhìn lại từng bước.
Exercise 1 — Application Deployment
- Tạo GitOps Repository.
- Tạo
base. - Tạo
dev. - Tạo
production. - Deploy bằng ArgoCD.
Kiểm tra:
kubectl get applications -n argocd
Exercise 2 — Automatic Deployment
Thay đổi:
replicas: 1
thành:
replicas: 2
Commit:
git commit -m "scale backend"
git push
Quan sát ArgoCD.
Exercise 3 — Self-Healing
Scale Kubernetes thủ công:
kubectl scale deployment backend \
-n todo-dev \
--replicas=5
Quan sát ArgoCD sửa lại về trạng thái Git.
Exercise 4 — Rollback
Deploy:
backend:v1.1.0
Sau đó rollback về:
backend:v1.0.0
Chỉ sử dụng Git.
Exercise 5 — Production
Thiết lập:
dev → replicas = 1
production → replicas = 3
Không copy toàn bộ Manifest.
Sử dụng:
base + overlays
Exercise 6 — Incident
Giả lập:
Pod Crash
Sau đó kiểm tra:
kubectl get pods
và:
kubectl get applications -n argocd
Trả lời:
Kubernetes xử lý vấn đề gì?
ArgoCD xử lý vấn đề gì?
Monitoring xử lý vấn đề gì?
🔍 29. Troubleshooting
❌ ArgoCD báo OutOfSync
Kiểm tra:
kubectl get application todo-dev -n argocd
Sau đó kiểm tra:
Git
↓
Manifest
↓
Kustomize
↓
Kubernetes
Đừng vội chạy:
kubectl apply
Vì như vậy bạn đang bypass GitOps.
❌ Application Degraded
Kiểm tra Pod:
kubectl get pods -n todo-dev
Sau đó:
kubectl describe pod <pod-name> -n todo-dev
và:
kubectl logs <pod-name> -n todo-dev
Nhớ:
ArgoCD báo trạng thái
↓
Kubernetes Events
↓
Pod Logs
ArgoCD không thay thế Kubernetes troubleshooting.
❌ ArgoCD không thấy Git change
Kiểm tra:
git log
và:
git status
Sau đó kiểm tra repository trong ArgoCD.
Các lỗi thường gặp:
Sai repoURL
Sai branch
Sai path
Git chưa push
Kustomize lỗi
💡 30. Production Tips
Tip 1 — Đừng dùng latest
Không nên:
image: backend:latest
Nên:
image: backend:v1.4.2
Hoặc tốt hơn nữa:
backend:git-abc123
Bạn luôn biết chính xác version đang chạy.
Tip 2 — Git là nơi thay đổi
Trong GitOps:
❌ kubectl edit
❌ kubectl set image
❌ sửa production trực tiếp
Thay vào đó:
Change Git
↓
Review
↓
Merge
↓
ArgoCD
↓
Kubernetes
Tip 3 — Không để Secret plaintext trong Git
Không commit:
password: production-password
Hãy sử dụng Secret Management.
Tip 4 — Production nên có Approval
Dev:
Git Push
↓
ArgoCD
↓
Deploy
Production:
Git Push
↓
Pull Request
↓
Review
↓
Merge
↓
ArgoCD
↓
Deploy
Tip 5 — Monitoring không phải phần phụ
Một deployment thành công không có nghĩa Application đang hoạt động tốt.
Luôn quan sát:
Deployment
↓
Health
↓
Metrics
↓
Logs
↓
Alerts
🧠 31. Bạn thực sự đã học được gì?
Đừng cố nhớ tất cả command.
Hãy nhớ 4 thành phần chính:
┌──────────────┐
│ GitHub │
│ Source Code │
└──────┬───────┘
│
▼
┌──────────────┐
│ CI │
│ Build Image │
└──────┬───────┘
│
▼
┌──────────────┐
│ GitOps Repo │
│ Desired State│
└──────┬───────┘
│
▼
┌──────────────┐
│ ArgoCD │
│ Deployment │
└──────┬───────┘
│
▼
┌──────────────┐
│ Kubernetes │
│ Runtime │
└──────────────┘
Có thể hiểu đơn giản:
CI tạo ra phần mềm.
GitOps mô tả phần mềm nên chạy như thế nào.
ArgoCD đảm bảo Kubernetes chạy đúng như Git.
Kubernetes chạy Application.
Monitoring cho biết Application có thực sự khỏe hay không.
🏆 32. Final Project — Definition of Done
Bạn hoàn thành Lab 21 khi có thể chứng minh được:
☑ GitHub Application Repository
☑ GitOps Repository
☑ Kustomize Base
☑ Dev Environment
☑ Production Environment
☑ ArgoCD Application
☑ Automated Sync
☑ Self-Healing
☑ Prune
☑ Git-based Rollback
☑ CI Build Docker Image
☑ Push Docker Registry
☑ Update GitOps Repository
☑ Kubernetes Deployment
☑ Prometheus Monitoring
☑ Grafana Dashboard
☑ Troubleshooting Flow
Và quan trọng nhất, bạn có thể tự giải thích flow:
Developer
│
▼
Git Push
│
▼
CI
│
▼
Docker Image
│
▼
GitOps Repository
│
▼
ArgoCD
│
▼
Kubernetes
│
▼
Application
│
▼
Monitoring
🎓 33. Kết thúc Phase GitOps + ArgoCD
Ở Lab đầu tiên, bạn có thể đã deploy Kubernetes bằng:
kubectl apply
Đến Lab cuối cùng, tư duy đã thay đổi:
BEFORE
Developer
│
▼
kubectl apply
│
▼
Kubernetes
thành:
AFTER
Developer
│
▼
Git
│
▼
CI/CD
│
▼
GitOps Repository
│
▼
ArgoCD
│
▼
Kubernetes
│
▼
Monitoring
Đây chính là bước chuyển từ:
"Biết deploy Kubernetes"
sang:
"Biết xây dựng một quy trình Kubernetes deployment có tính tự động, audit được và có khả năng self-healing."
Và đó là nền tảng rất quan trọng trước khi bước sang các chủ đề DevOps nâng cao hơn như Cloud, Terraform, CI/CD nâng cao, Security, Observability và Production Infrastructure.
All Rights Reserved