🚀 Chapter 5 — Platform: Từ Kubernetes đến GitOps Platform
ShopNow đã có CI/CD, Harbor và release governance. Nhưng khi hệ thống chuyển sang Kubernetes, một câu hỏi mới xuất hiện:
- Ai sẽ chịu trách nhiệm đảm bảo Kubernetes luôn chạy đúng với phiên bản mà công ty muốn?
1. Vấn đề mới: Kubernetes đã lớn hơn Docker Compose
Ở Phase 4, ShopNow đang có:

Application chạy trên Cloud VM bằng Docker Compose.
Nhưng hệ thống ngày càng lớn:
- nhiều microservices
- nhiều VM
- traffic tăng
- cần autoscaling
- container có thể chết
- cần rolling update
- cần service discovery
- cần load balancing
- cần self-healing
Docker Compose bắt đầu không còn phù hợp.
ShopNow quyết định chuyển Production sang Kubernetes.
2. Vì sao Kubernetes?
Điểm quan trọng không phải:
"Kubernetes đang phổ biến nên phải học Kubernetes."
Mà là:
Production đã có đủ complexity để cần một hệ thống scheduler/orchestrator.
Kubernetes giúp giải quyết:
Container chết
↓
Kubernetes restart
Traffic tăng
↓
Kubernetes scale
Node chết
↓
Kubernetes reschedule
Deploy version mới
↓
Rolling Update
Service thay đổi IP
↓
Service Discovery
Kiến trúc bắt đầu trở thành:

Nhưng ở đây lại xuất hiện một vấn đề.
3. Deploy Kubernetes bằng CI có thực sự tốt?
Cách đơn giản nhất là:
Azure DevOps
│
│ kubectl apply
▼
Kubernetes
Ví dụ pipeline:
- script: |
kubectl apply -f deployment.yaml
Ban đầu cách này rất tiện.
Nhưng sau một thời gian, vấn đề xuất hiện.
Ai thay đổi Production?
Developer:
kubectl edit deployment checkout
DevOps:
kubectl apply -f deployment.yaml
Pipeline:
kubectl set image deployment/checkout ...
Bây giờ Kubernetes có thể khác với Git.
Git
└── checkout:v1.4
Kubernetes
└── checkout:v1.5
Ta có:
Configuration Drift
Và câu hỏi quan trọng hơn:
Production hiện tại có đúng với version mà công ty mong muốn hay không?
4. Từ Deployment đến Desired State
Đây chính là lúc tư duy GitOps xuất hiện.
Thay vì:
CI
↓
kubectl apply
↓
Kubernetes
ShopNow chuyển sang:

Git trở thành nơi lưu:
Desired State
Ví dụ:
image:
repository: harbor.shopnow.io/ecommerce/checkout
tag: v1.8.3-a81f32c
Git nói:
"Production phải chạy image này."
ArgoCD liên tục kiểm tra:
Desired State
↓
Git
↓
ArgoCD
↓
Actual State
↓
Kubernetes
Nếu hai trạng thái khác nhau:
Desired ≠ Actual
ArgoCD sẽ phát hiện.
5. Kiến trúc Platform mới
Sau khi áp dụng GitOps:

Đây chính là Platform Architecture của ShopNow.
6. GitOps Repository — Source of Truth
Application repository và deployment repository nên được tách biệt.
Ví dụ:
checkout-service/
├── src/
├── Dockerfile
└── tests/
GitOps:
shopnow-gitops/
│
├── apps/
│ ├── checkout/
│ ├── payment/
│ └── frontend/
│
├── environments/
│ ├── dev/
│ ├── staging/
│ └── production/
│
└── clusters/
├── dev/
├── staging/
└── production/
Ý tưởng:

Hai repository có hai trách nhiệm khác nhau.
| Repository | Responsibility |
|---|---|
| Application Repo | Source code |
| GitOps Repo | Deployment state |
7. CI và CD bây giờ tách hoàn toàn
Đây là một thay đổi rất quan trọng.
CI
Azure DevOps chịu trách nhiệm:

CI tạo ra:
checkout:v1.8.3-a81f32c
CD
ArgoCD chịu trách nhiệm:

CD không cần build lại image.
Đây chính là:
Build Once, Deploy Many
Cùng một image:
Harbor
│
checkout:v1.8.3
│
┌────────────┼────────────┐
▼ ▼ ▼
Dev Staging Prod
Không có chuyện:
Dev → build image A
Staging → build image B
Prod → build image C
Điều đó phá vỡ tính nhất quán của artifact.
8. Deploy bằng Helm/Kustomize
Khi số lượng service tăng, viết Kubernetes YAML trực tiếp sẽ nhanh chóng trở thành vấn đề.
Ví dụ:
deployment.yaml
service.yaml
configmap.yaml
ingress.yaml
hpa.yaml
100 services sẽ tạo ra rất nhiều YAML.
Platform Team bắt đầu chuẩn hóa.
Có thể sử dụng:
Helm
hoặc:
Kustomize
Điều quan trọng không phải học thuộc syntax.
Hãy hiểu vai trò:
Raw Kubernetes YAML
↓
Template / Overlay
↓
Reusable Deployment Model
Ví dụ Helm:
checkout-chart/
├── Chart.yaml
├── values.yaml
└── templates/
Environment chỉ cần thay đổi:
image:
tag: v1.8.3
hoặc:
replicas: 5
9. ArgoCD — Kubernetes có "người canh"
ArgoCD là GitOps controller.
Nó liên tục quan sát:
Git
↓
Desired State
và:
Kubernetes
↓
Actual State
Sau đó so sánh:
Desired State
│
▼
ArgoCD
▲
│
Actual State
Nếu:
Desired = Actual
thì:
Synced
Nếu:
Desired ≠ Actual
thì:
OutOfSync
10. Self-Healing
Đây là một trong những giá trị lớn nhất của GitOps.
Giả sử Git nói:
checkout replicas = 5
Nhưng ai đó vào Kubernetes:
kubectl scale deployment checkout --replicas=2
Actual State:
replicas = 2
Desired State:
replicas = 5
ArgoCD phát hiện:
5 ≠ 2
và có thể tự động reconcile:
2
↓
5
Production quay lại trạng thái mong muốn.
Đây chính là:
Reconciliation
Không phải:
"Deploy một lần rồi thôi."
Mà là:
Liên tục đảm bảo hệ thống hội tụ về Desired State.
11. Nhưng có nên bật Auto-Sync mọi nơi?
Không nhất thiết.
Ví dụ:
Development
↓
Auto Sync
Có thể rất phù hợp.
Nhưng Production:
Production
↓
Approval
↓
Sync
có thể phù hợp hơn với hệ thống cần governance cao.
Do đó:
Dev
└── Auto Sync
Staging
└── Auto Sync / Controlled
Production
└── Approval → Sync
Đây là quyết định kiến trúc, không phải quyết định syntax.
12. Environment Management
ShopNow có:
Dev
Staging
Production
Nhưng không nên copy toàn bộ YAML ba lần.
Ví dụ:
base/
└── checkout/
overlays/
├── dev/
├── staging/
└── production/
Concept:
Base
│
┌──────┼──────┐
▼ ▼ ▼
Dev Staging Prod
Environment chỉ override những gì khác nhau.
Ví dụ:
Dev
replicas = 1
Staging
replicas = 2
Production
replicas = 5
13. Production Promotion
Một release đi qua:

Điều quan trọng:
Không build lại image khi promotion.
Ví dụ:
Harbor
checkout:v1.8.3
Sau khi test:
Dev
↓
Staging
↓
Production
vẫn là:
checkout:v1.8.3
Chỉ thay đổi:
Deployment Target
không thay đổi:
Artifact
14. Rollback trở nên đơn giản hơn
Trong mô hình cũ:
Production
↓
kubectl
↓
Rollback
Có thể không rõ:
- rollback version nào?
- ai rollback?
- rollback bằng command nào?
- trạng thái sau rollback có được lưu lại không?
GitOps:
Git
v1.8.3
↓
v1.8.2
Rollback có thể đơn giản là:
Revert Git commit
Sau đó:
Git
↓
ArgoCD
↓
Kubernetes
Kubernetes quay về:
checkout:v1.8.2
Rollback trở thành một Git operation.
15. Audit Trail
Đây là một lợi ích rất lớn đối với Production.
Ví dụ Git:
Commit: a81f32c
Change:
checkout v1.8.2 → v1.8.3
Author:
developer@example.com
Time:
10:42
Ta có thể biết:
Who?
What?
When?
Why?
Thay vì:
ssh production
kubectl apply
rồi vài tháng sau không ai biết ai đã thay đổi.
16. Security — Không để CI có quyền quá lớn
Một sai lầm phổ biến:
Azure DevOps
│
│ cluster-admin
▼
Kubernetes
Nếu CI bị compromise:
CI compromised
↓
cluster-admin
↓
Entire Cluster
Platform Team nên áp dụng:
Least Privilege
Ví dụ:
Azure DevOps
↓
Harbor push permission
ArgoCD
↓
Kubernetes deployment permission
Developer
↓
Git repository permission
Mỗi thành phần chỉ có quyền cần thiết.
17. Secrets
GitOps đặt ra một câu hỏi khó:
Nếu Git là Source of Truth thì có nên commit password vào Git không?
➠ Không
Ví dụ:
password: my-production-password
là một anti-pattern.
Có thể sử dụng:
External Secrets
Secret Manager
Vault
Sealed Secrets
Tùy kiến trúc công ty.
Điều quan trọng cần nhớ:
GitOps không có nghĩa là tất cả dữ liệu đều phải plaintext trong Git.
Git lưu desired configuration.
Secrets cần có cơ chế bảo vệ riêng.
18. Platform Team bắt đầu xuất hiện
Đến đây ShopNow không chỉ có:
Dev Team
DevOps
mà bắt đầu hình thành:
Platform Team
│
┌──────────────┼──────────────┐
│ │ │
Kubernetes ArgoCD Harbor
│ │ │
└──────────────┼──────────────┘
│
Developer Teams
Platform Team cung cấp:
Kubernetes Platform
CI/CD Templates
GitOps Templates
Helm Charts
Observability
Security Policies
Deployment Standards
Developer không cần biết mọi thứ phía dưới.
Họ chỉ cần:
git push
và platform đảm nhiệm phần còn lại.
19. Platform tốt không có nghĩa là nhiều tool
Đây là điểm rất quan trọng.
Platform Team không nên nghĩ:
"Công ty có Kubernetes rồi, thêm ArgoCD, Helm, Vault, Prometheus, Grafana, Istio, Backstage..."
Platform càng nhiều tool:
Developer Cognitive Load
↑
│
│
❌
Platform tốt phải làm ngược lại:
Infrastructure Complexity
↓
Platform Team
↓
Developer Experience
↑
│
Simple
Developer chỉ cần hiểu:
Code
↓
Pull Request
↓
Merge
↓
Pipeline
↓
Deployment
20. Paved Road
Platform Team tạo ra một "con đường chuẩn":

Developer có thể đi theo paved road.
Không cần tự thiết kế:
CI
CD
Docker
Registry
Kubernetes
GitOps
Security
cho từng service.
21. Platform Architecture hoàn chỉnh
Sau Phase 5, kiến trúc ShopNow trở thành:

22. Nhưng vẫn chưa xong
Đây là điểm mà một Senior DevOps Engineer cần nhìn thấy.
Kubernetes + ArgoCD giải quyết:
Deployment
Scaling
Self-Healing
Desired State
Drift
Rollback
Nhưng Production vẫn có thể xảy ra:
Pod Crash
CPU tăng
Memory Leak
Network Error
Database chậm
Request latency tăng
Deployment lỗi
Node chết
Service unavailable
Kubernetes có thể tự restart Pod.
Nhưng:
Kubernetes không tự giải thích tại sao hệ thống đang chậm.
ArgoCD có thể nói:
Application Synced
nhưng điều đó không có nghĩa:
Application Healthy
Đây là sự khác biệt cực kỳ quan trọng:
Configuration Health
≠
Application Health
23. Câu hỏi mở sang Phase 6
ShopNow bây giờ có:
CI/CD
+
Harbor
+
Kubernetes
+
GitOps
+
ArgoCD
Nhưng Production Team bắt đầu hỏi:
"Website đang chậm, tại sao?"
"Service nào gây latency?"
"Pod nào đang crash?"
"Release nào gây ra incident?"
"Có thể rollback tự động không?"
"Làm sao biết Production đang khỏe?"
Vấn đề tiếp theo không còn là:
Deploy được hay không?
Mà là:
Sau khi deploy, hệ thống có thực sự khỏe và đáng tin cậy không?
Và đó chính là bước chuyển sang:
Phase 6 — Production Reality
Platform giúp Developer deploy dễ dàng.
Reliability giúp công ty sống sót sau khi deploy.
All rights reserved