Lab 16 — App of Apps Pattern với ArgoCD
🎯 Mục tiêu
Sau Lab này, bạn sẽ:
- Hiểu App of Apps Pattern là gì và tại sao cần nó.
- Biết cách một ArgoCD Application có thể quản lý nhiều Application khác.
- Tổ chức GitOps Repository theo hướng dễ mở rộng.
- Deploy nhiều ứng dụng bằng một Application duy nhất.
- Hiểu cách Pattern này được sử dụng trong môi trường production.
🤔 1. Vấn đề thực tế
Ở các Lab trước, chúng ta đã dùng ArgoCD để deploy Application.
Ví dụ:
ArgoCD
│
└── Todo App
Ban đầu hệ thống chỉ có một ứng dụng nên mọi thứ khá đơn giản.
Nhưng production thường không chỉ có một Application.
Ví dụ:
Production Cluster
├── frontend
├── backend
├── postgres
├── redis
├── monitoring
├── ingress
└── logging
Nếu mỗi Application được tạo và quản lý riêng:
ArgoCD
├── frontend
├── backend
├── postgres
├── redis
├── monitoring
├── logging
└── ingress
Khi số lượng Application tăng lên hàng chục hoặc hàng trăm, việc quản lý chúng bắt đầu trở nên khó khăn.
Chúng ta muốn có một cách đơn giản hơn:
ArgoCD
│
▼
Root Application
│
├── frontend
├── backend
├── postgres
├── redis
├── monitoring
└── logging
Đây chính là ý tưởng của App of Apps Pattern.
Thay vì quản lý từng Application bằng tay, chúng ta tạo một Application "cha" để quản lý các Application "con".
🧠 2. Hiểu nhanh App of Apps
2.1. Application bình thường
Ở những Lab trước, bạn có thể có:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: todo-app
spec:
source:
repoURL: https://github.com/example/gitops.git
path: apps/todo
destination:
server: https://kubernetes.default.svc
namespace: todo-app
Application này có nhiệm vụ:
ArgoCD
│
▼
todo-app
│
▼
Kubernetes Resources
2.2. App of Apps
Với App of Apps, chúng ta tạo một Application đặc biệt:
ArgoCD
│
▼
┌─────────────┐
│ Root App │
└──────┬──────┘
│
┌─────────┼─────────┐
▼ ▼ ▼
Frontend Backend Redis
│ │ │
▼ ▼ ▼
Resources Resources Resources
Root Application không trực tiếp deploy tất cả Deployment, Service, ConfigMap...
Nó deploy các ArgoCD Application.
Các Application con sau đó chịu trách nhiệm deploy Application thực tế.
🏗️ 3. Architecture
Trong Lab này chúng ta xây dựng một hệ thống đơn giản:
GitHub
│
│ Git
▼
┌──────────────────┐
│ GitOps Repository │
│ │
│ apps/ │
│ ├── frontend │
│ ├── backend │
│ └── redis │
│ │
│ root/ │
│ └── applications │
└────────┬─────────┘
│
│ Watch
▼
┌──────────────┐
│ ArgoCD │
│ │
│ Root App │
└──────┬───────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
Frontend App Backend App Redis App
│ │ │
▼ ▼ ▼
Kubernetes Kubernetes Kubernetes
Điểm quan trọng nhất:
Root Application
│
├── Application: frontend
├── Application: backend
└── Application: redis
🛠️ 4. Chuẩn bị GitOps Repository
4.1. Tạo cấu trúc Repository
Giả sử repository của chúng ta là:
gitops/
├── root/
│ └── applications/
│ ├── frontend.yaml
│ ├── backend.yaml
│ └── redis.yaml
│
└── apps/
├── frontend/
│ ├── deployment.yaml
│ └── service.yaml
│
├── backend/
│ ├── deployment.yaml
│ └── service.yaml
│
└── redis/
├── deployment.yaml
└── service.yaml
Có hai phần quan trọng:
root/
│
└── ArgoCD Applications
apps/
│
└── Kubernetes manifests
Root sẽ quản lý Application.
Application sẽ quản lý Kubernetes resources.
🧪 5. Tạo Application cho Frontend
5.1. Tại sao?
Trước tiên chúng ta cần một Application con.
Application này chịu trách nhiệm deploy frontend.
Tạo:
root/applications/frontend.yaml
Nội dung:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: frontend
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/YOUR_USERNAME/gitops.git
targetRevision: HEAD
path: apps/frontend
destination:
server: https://kubernetes.default.svc
namespace: frontend
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Thay:
YOUR_USERNAME
bằng GitHub username của bạn.
5.2. Tạo Backend Application
Tạo:
root/applications/backend.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: backend
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/YOUR_USERNAME/gitops.git
targetRevision: HEAD
path: apps/backend
destination:
server: https://kubernetes.default.svc
namespace: backend
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
5.3. Tạo Redis Application
Tạo:
root/applications/redis.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: redis
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/YOUR_USERNAME/gitops.git
targetRevision: HEAD
path: apps/redis
destination:
server: https://kubernetes.default.svc
namespace: redis
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Bây giờ Git repository chứa:
root/applications/
├── frontend.yaml
├── backend.yaml
└── redis.yaml
Nhưng ArgoCD vẫn chưa biết rằng nó phải tạo ba Application này.
Đó là nhiệm vụ của Root Application.
🚀 6. Tạo Root Application
6.1. Tại sao?
Đây là phần quan trọng nhất của Lab.
Thay vì chạy:
kubectl apply -f frontend.yaml
kubectl apply -f backend.yaml
kubectl apply -f redis.yaml
chúng ta tạo một Application duy nhất.
Root Application sẽ theo dõi:
root/applications/
và tự động tạo các Application bên trong đó.
6.2. Tạo Root Application
Tạo:
root-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/YOUR_USERNAME/gitops.git
targetRevision: HEAD
path: root/applications
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
Apply:
kubectl apply -f root-app.yaml
👀 7. See Result
Kiểm tra:
kubectl get applications -n argocd
Bạn sẽ thấy:
NAME SYNC STATUS HEALTH STATUS
root-app Synced Healthy
frontend Synced Healthy
backend Synced Healthy
redis Synced Healthy
Kiểm tra Kubernetes:
kubectl get pods -A
Ví dụ:
NAMESPACE NAME
frontend frontend-xxxxx
backend backend-xxxxx
redis redis-xxxxx
🔍 8. Quan sát mối quan hệ Parent → Child
Đây là điều quan trọng nhất cần hiểu.
ArgoCD đang có:
root-app
│
├── frontend
│ └── Deployment
│
├── backend
│ └── Deployment
│
└── redis
└── Deployment
Có thể xem Application:
kubectl get application root-app -n argocd
Và:
kubectl get application frontend -n argocd
Điểm khác biệt:
root-app
│
│ quản lý
▼
ArgoCD Applications
frontend
backend
redis
Trong khi:
frontend
│
│ quản lý
▼
Kubernetes Resources
Deployment
Service
ConfigMap
...
🧪 9. Thử thêm một Application
Đây là lúc chúng ta thấy App of Apps thực sự hữu ích.
Giả sử cần thêm:
Prometheus
Không cần tạo một Root Application mới.
Chỉ cần thêm:
root/applications/prometheus.yaml
Ví dụ:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: prometheus
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/YOUR_USERNAME/gitops.git
targetRevision: HEAD
path: apps/prometheus
destination:
server: https://kubernetes.default.svc
namespace: monitoring
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Commit:
git add .
git commit -m "add prometheus application"
git push
ArgoCD phát hiện thay đổi:
Git
│
│ new prometheus.yaml
▼
Root App
│
▼
Prometheus App
│
▼
Prometheus Resources
Kiểm tra:
kubectl get applications -n argocd
Kết quả:
NAME SYNC STATUS HEALTH STATUS
root-app Synced Healthy
frontend Synced Healthy
backend Synced Healthy
redis Synced Healthy
prometheus Synced Healthy
🎉 Bạn vừa thêm một Application mới mà không cần tạo thêm ArgoCD Application thủ công.
🧠 10. Tại sao Pattern này mạnh?
Hãy tưởng tượng production có:
50 Applications
Nếu quản lý thủ công:
kubectl apply
kubectl apply
kubectl apply
...
Rất khó kiểm soát.
Với App of Apps:
Git Repository
│
▼
Root App
│
├── app-01
├── app-02
├── app-03
├── ...
└── app-50
Git trở thành nơi mô tả:
"Cluster này cần chạy những Application nào?"
ArgoCD chỉ việc biến trạng thái trong Git thành trạng thái thực tế của Kubernetes.
🏭 11. Production Pattern
Trong production, cấu trúc có thể lớn hơn:
gitops/
│
├── bootstrap/
│ └── root-app.yaml
│
├── applications/
│ ├── monitoring.yaml
│ ├── logging.yaml
│ ├── ingress.yaml
│ ├── frontend.yaml
│ ├── backend.yaml
│ └── database.yaml
│
└── apps/
├── monitoring/
├── logging/
├── ingress/
├── frontend/
├── backend/
└── database/
Flow:
Git Repository
│
▼
┌──────────┐
│ Root App │
└────┬─────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
Monitoring Backend Frontend
│ │ │
▼ ▼ ▼
Resources Resources Resources
Điều này giúp team có một nơi duy nhất để nhìn thấy:
Cluster đang chạy những gì?
⚠️ 12. Một số lưu ý Production
12.1. Đừng biến Root App thành "God Application"
App of Apps rất tiện nhưng không có nghĩa là mọi thứ phải nằm trong một Root App duy nhất.
Cluster lớn có thể chia:
Platform Root
├── Monitoring
├── Logging
└── Ingress
Application Root
├── Frontend
├── Backend
└── Worker
Giúp giảm mức độ phức tạp.
12.2. Cẩn thận với prune
Nếu bật:
prune: true
ArgoCD có thể xóa resource không còn tồn tại trong Git.
Đây là điều rất mạnh nhưng cũng rất nguy hiểm.
GitOps tốt không chỉ là "tự động", mà còn phải kiểm soát được những gì automation có quyền thay đổi.
12.3. Không commit Secret plaintext
Không nên:
gitops/
└── secret.yaml
password: my-production-password
Thay vào đó có thể sử dụng:
External Secrets
Sealed Secrets
Vault
Cloud Secret Manager
Chúng ta sẽ đi sâu hơn ở các Lab về Secrets.
🧪 13. Exercise
Exercise 1 — Thêm Application mới
Tạo:
apps/nginx/
và:
root/applications/nginx.yaml
Mục tiêu:
root-app
│
└── nginx
│
└── nginx Deployment
Kiểm tra:
kubectl get applications -n argocd
Exercise 2 — Xóa Application
Xóa:
root/applications/nginx.yaml
Commit và push:
git add .
git commit -m "remove nginx application"
git push
Quan sát ArgoCD.
Câu hỏi:
Điều gì xảy ra với Application
nginx?
Exercise 3 — Self-Healing
Xóa thủ công một Pod:
kubectl delete pod -n frontend <pod-name>
Quan sát:
kubectl get pods -n frontend -w
Bạn sẽ thấy Kubernetes tạo Pod mới.
Điều này giúp phân biệt:
Kubernetes Self-Healing
vs
ArgoCD Self-Healing
Kubernetes tự phục hồi Pod dựa trên desired state của Deployment.
ArgoCD đảm bảo Kubernetes configuration quay lại trạng thái được định nghĩa trong Git.
🧩 14. Hiểu bản chất trong 30 giây
Nếu chỉ nhớ một diagram của Lab này, hãy nhớ:
Git
│
▼
┌─────────┐
│ Root App│
└────┬────┘
│
creates/manages
│
┌───────────┼───────────┐
▼ ▼ ▼
Frontend Backend Redis
App App App
│ │ │
▼ ▼ ▼
Kubernetes Kubernetes Kubernetes
Resources Resources Resources
Root App không phải Application chính của business.
Nó là Application dùng để quản lý các Application khác.
Đó chính là:
App of Apps Pattern.
🎯 15. Kết luận
Trong các Lab trước, chúng ta học cách ArgoCD deploy một Application.
Trong Lab này, chúng ta nâng cấp cách quản lý:
1 Application
↓
Many Applications
↓
App of Apps
Từ đây, Git repository không chỉ mô tả:
"Application này chạy như thế nào?"
mà còn mô tả:
"Cluster này cần chạy những Application nào?"
Đó là bước chuyển rất quan trọng từ deploy bằng ArgoCD sang quản lý cả Kubernetes platform bằng GitOps.
🔑 Những gì cần nhớ
- Application → quản lý Kubernetes resources.
- Root Application → quản lý các ArgoCD Applications.
- App of Apps → dùng một Application để quản lý nhiều Application.
- Git → Source of Truth.
- Thêm Application → thêm manifest vào Git.
- Xóa Application → xóa manifest khỏi Git.
- ArgoCD → liên tục đưa cluster về trạng thái được định nghĩa trong Git.
Ở Lab tiếp theo, chúng ta sẽ đi thêm một bước với ApplicationSet — thay vì phải tạo từng Application manifest, ArgoCD có thể tự động generate hàng loạt Application dựa trên template và danh sách environment/cluster.
All Rights Reserved