🚀 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ó:
Developer
↓
GitHub
↓
Azure DevOps
↓
Build / Test / Scan
↓
Harbor
↓
Approval
↓
Production
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:
┌──────────────────┐
│ Developer │
└────────┬─────────┘
│
GitHub
│
▼
┌──────────────────┐
│ Azure DevOps │
│ │
│ Build │
│ Test │
│ Scan │
│ Docker Build │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Harbor │
│ Container Image │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Kubernetes │
└──────────────────┘
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:
Developer
↓
GitHub
↓
Azure DevOps
↓
Build / Test / Scan
↓
Harbor
↓
GitOps Repository
↓
ArgoCD
↓
Kubernetes
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:
┌───────────────┐
│ Developer │
└───────┬───────┘
│
▼
┌─────────┐
│ GitHub │
└────┬────┘
│
▼
┌────────────────────┐
│ Azure DevOps │
│ │
│ Build │
│ Test │
│ Security Scan │
│ Docker Build │
└─────────┬──────────┘
│
▼
┌────────────┐
│ Harbor │
└─────┬──────┘
│
Image v1.8.3
│
▼
┌────────────────────┐
│ GitOps Repo │
│ │
│ dev/ │
│ staging/ │
│ production/ │
└─────────┬──────────┘
│
▼
┌─────────┐
│ ArgoCD │
└────┬────┘
│
▼
┌──────────────────┐
│ Kubernetes │
│ │
│ Dev │
│ Staging │
│ Production │
└──────────────────┘
Đâ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:
Application Repo
│
│ Source Code
▼
Azure DevOps
│
│ Docker Image
▼
Harbor
│
│ Image Version
▼
GitOps Repo
│
│ Desired State
▼
ArgoCD
│
▼
Kubernetes
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:
Code
↓
Build
↓
Test
↓
Security Scan
↓
Docker Build
↓
Push Harbor
CI tạo ra:
checkout:v1.8.3-a81f32c
CD
ArgoCD chịu trách nhiệm:
GitOps Repo
↓
Desired State
↓
ArgoCD
↓
Kubernetes
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:
Developer
↓
CI
↓
Harbor
↓
Dev
↓
Staging
↓
Approval
↓
Production
Đ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":
Create Service
↓
Use Standard Template
↓
CI Pipeline
↓
Security Scan
↓
Harbor
↓
GitOps
↓
ArgoCD
↓
Kubernetes
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:
Developer
│
▼
GitHub
│
▼
┌─────────────────────────┐
│ Azure DevOps │
│ │
│ Build │
│ Test │
│ Lint │
│ Security Scan │
│ Docker Build │
└────────────┬────────────┘
│
▼
┌───────────┐
│ Harbor │
│ │
│ Image │
└─────┬─────┘
│
│ Image Version
▼
┌─────────────────────────┐
│ GitOps Repo │
│ │
│ Dev │
│ Staging │
│ Production │
└────────────┬────────────┘
│
▼
┌─────────┐
│ ArgoCD │
│ │
│ Sync │
│ Drift │
│ Heal │
└────┬────┘
│
▼
┌─────────────────────────┐
│ Kubernetes │
│ │
│ Dev │
│ Staging │
│ Production │
└─────────────────────────┘
22. Hãy nhìn lại toàn bộ hành trình
ShopNow đã tiến hóa:
Phase 1 — Startup
Git
↓
SSH
↓
Docker Compose
Vấn đề:
Manual
Phase 2 — Automation
Git
↓
Azure DevOps
↓
Build/Test
↓
Deploy
Vấn đề:
Pipeline duplication
Artifact management
Phase 3 — Platform
Reusable CI/CD Templates
↓
Standardized Delivery
Vấn đề:
Artifact Security
Registry Governance
Phase 4 — Production
Azure DevOps
↓
Harbor
↓
Approval
↓
Production
Vấn đề:
VM + Docker Compose
không còn đủ khả năng scale
Phase 5 — Platform + GitOps
Azure DevOps
↓
Harbor
↓
GitOps Repo
↓
ArgoCD
↓
Kubernetes
Bây giờ ShopNow đã có một Internal Developer Platform tương đối hoàn chỉnh.
23. 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
24. 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
Kubernetes
↓
Observability
↓
Metrics
↓
Logs
↓
Tracing
↓
Alerting
↓
Incident Response
↓
SLO / SLA
↓
Reliability
Platform giúp Developer deploy dễ dàng.
Reliability giúp công ty sống sót sau khi deploy.
All rights reserved