🚀 Chapter 4 — Production: Artifact, Security & Release Governance
Bối cảnh: ShopNow đã có CI/CD Platform phục vụ hàng chục team và hàng trăm service. Pipeline đã tự động Build → Test → Package → Deploy. Nhưng Production ngày càng quan trọng, và công ty không thể tiếp tục để Docker Image được lưu trữ, truy cập và release một cách thiếu kiểm soát.
Mục tiêu: Xây dựng một Production Delivery Flow với Harbor làm Container Registry, kiểm soát quyền truy cập, scan image, quản lý lifecycle và thiết lập cơ chế Approval trước Production.
1. Production đã thay đổi
Ở Phase 3, chúng ta có:
Developer
│
▼
GitHub
│
▼
Azure DevOps
│
├── Build
├── Test
├── Scan
└── Package
│
▼
Docker Image
Nhưng Docker Image đang được quản lý thế nào?
Giả sử có:
100 services
20 teams
10 images/service/month
Ta nhanh chóng có hàng nghìn images.
Và bắt đầu xuất hiện những câu hỏi:
Image nằm ở đâu?
Ai được push?
Ai được pull?
Image có vulnerability không?
Image nào đang chạy Production?
Image nào có thể deploy?
Image cũ bao giờ xóa?
Ai đã push image?
CI/CD đã giải quyết:
How to build and deploy?
Bây giờ Production cần giải quyết:
Can we trust what we deploy?
2. Container Registry xuất hiện
Chúng ta cần một hệ thống trung tâm để quản lý Docker Images.
Azure DevOps
│
Docker Build
│
▼
┌──────────────┐
│ Harbor │
│ │
│ Docker │
│ Registry │
└──────┬───────┘
│
┌──────────┼──────────┐
▼ ▼ ▼
Dev Staging Prod
Harbor trở thành nguồn lưu trữ artifact trung tâm.
Nhưng Harbor không chỉ đơn giản là:
docker push
docker pull
Nó cho chúng ta khả năng quản lý:
Registry
Projects
RBAC
Robot Accounts
Vulnerability Scanning
Image Retention
Replication
Audit
Artifact Governance
3. Tư duy quan trọng: Image là Artifact
Một developer push code:
commit a81f32c
CI build:
Docker Image
shopnow/checkout:a81f32c
Sau đó image được lưu vào Harbor:
Harbor
└── shopnow
└── checkout
├── a81f32c
├── b91a24e
└── c82d11f
Ta có một chain:
Git Commit
│
▼
CI Build
│
▼
Docker Image
│
▼
Harbor
│
▼
Environment
Điều này tạo ra một nguyên tắc:
Build artifact một lần, sau đó promote artifact đó qua các environment.
Không build lại mỗi lần deploy.
4. Step 1 — Thiết kế Harbor Projects
Không nên để tất cả image vào một project duy nhất:
harbor.shopnow.io/
└── everything/
Thay vào đó:
Harbor
│
├── ecommerce
│ ├── frontend
│ ├── checkout
│ ├── cart
│ └── payment
│
├── platform
│ ├── monitoring
│ └── gateway
│
└── internal
├── admin
└── tools
Project trở thành boundary để quản lý:
Access
RBAC
Quota
Scanning
Retention
5. Step 2 — Thiết kế RBAC
Không phải developer nào cũng được push image vào mọi project.
Ví dụ:
Harbor
│
┌───────────┼───────────┐
▼ ▼ ▼
ecommerce platform internal
│
┌─────┼─────┐
▼ ▼ ▼
Dev QA Release
Ví dụ permission:
Developer
├── Pull ✓
└── Push ✓
│
└── ecommerce only
Security Team
├── Scan
└── Audit
Release Team
├── Pull
└── Promote
Admin
└── Full Access
Nguyên tắc:
Least Privilege
Không cấp:
Developer → Harbor Admin
chỉ vì developer cần push image.
6. Step 3 — Robot Account
Có một vấn đề khác.
Azure DevOps Pipeline cũng cần push image.
Nhưng pipeline không phải con người.
Không nên dùng:
developer-account
cho pipeline.
Thay vào đó:
Azure DevOps
│
│ credentials
▼
Robot Account
│
▼
Harbor
Robot Account có quyền giới hạn.
Ví dụ:
robot-shopnow-ci
Permissions:
ecommerce:
Push ✓
Pull ✓
platform:
Push ✗
Nếu credential bị lộ, blast radius cũng nhỏ hơn.
7. Step 4 — Azure DevOps → Harbor
Pipeline Phase 3:
Build
↓
Test
↓
Docker Build
↓
Artifact
Bây giờ:
Build
↓
Test
↓
Docker Build
↓
Security Scan
↓
Push Harbor
Ví dụ concept:
docker build \
-t harbor.shopnow.io/ecommerce/checkout:$IMAGE_TAG .
docker push \
harbor.shopnow.io/ecommerce/checkout:$IMAGE_TAG
Sau đó Harbor chứa:
harbor.shopnow.io/ecommerce/checkout:a81f32c
8. Step 5 — Không sử dụng latest cho Production
Đây là một nguyên tắc cần đặc biệt nhớ.
Tránh:
checkout:latest
Production nên sử dụng immutable version:
checkout:a81f32c
hoặc:
checkout:v1.8.3
Tốt hơn nữa là kết hợp:
Version
+
Git SHA
Ví dụ:
checkout:v1.8.3-a81f32c
Bây giờ khi nhìn Production:
Production
│
▼
checkout:v1.8.3-a81f32c
ta biết chính xác application đang chạy version nào.
9. Step 6 — Image Security
Docker Image có thể chứa vulnerability.
Ví dụ:
checkout image
│
▼
┌────────────────────┐
│ Vulnerability Scan │
└─────────┬──────────┘
│
┌────┴─────┐
▼ ▼
PASS FAIL
│ │
▼ ▼
Continue STOP
Ví dụ scan phát hiện:
CRITICAL 2
HIGH 7
MEDIUM 15
LOW 20
Chúng ta cần policy.
Ví dụ:
CRITICAL > 0
↓
Block Release
Hoặc:
CRITICAL = 0
HIGH <= 5
↓
Allow Release
Điểm quan trọng:
Security scan chỉ có giá trị khi kết quả của nó ảnh hưởng đến release decision.
Nếu scan:
Scan → FAIL
nhưng pipeline vẫn:
Deploy Production
thì scan gần như chỉ mang tính hình thức.
10. Step 7 — Image Promotion
Một image sau khi build không nên ngay lập tức trở thành Production image.
Flow:
Harbor
│
▼
Image Built
│
▼
Scan
│
PASS
│
▼
DEV
│
Testing
│
▼
STAGING
│
Approval
│
▼
PRODUCTION
Ví dụ:
checkout:a81f32c
│
▼
Dev
│
▼
Staging
│
▼
Production
Cùng một image.
Không:
Build Dev Image
↓
Build Staging Image
↓
Build Production Image
Mà:
Build ONE
↓
Promote MANY
11. Tại sao Promotion quan trọng?
Giả sử Dev chạy:
checkout:a81f32c
Staging cũng chạy:
checkout:a81f32c
Production cũng chạy:
checkout:a81f32c
Ta biết:
Dev == Staging == Production
về mặt application artifact.
Nếu Production có bug, ta có thể trace:
Production
│
▼
Image a81f32c
│
▼
Git Commit a81f32c
│
▼
Developer Change
Đây là traceability.
12. Step 8 — Release Governance
Đến đây, Production bắt đầu quan trọng hơn.
Không phải mọi commit đều được phép đi thẳng vào Production.
Ta thiết kế:
Git Push
│
▼
CI
│
├── Build ✓
├── Test ✓
└── Scan ✓
│
▼
Dev
│
▼
Staging
│
Automated Tests
│
▼
Approval
│
▼
Production
Approval nằm ở đây:
Staging
│
▼
[ Approval ]
│
▼
Production
13. Approval không phải Manual Deployment
Đây là distinction rất quan trọng.
Phase 1:
Human
│
├── SSH
├── git pull
├── build
└── deploy
Con người làm việc.
Phase 4:
Pipeline
│
▼
Staging
│
▼
Approval
│
▼
Pipeline
│
▼
Production
Con người chỉ:
Approve
Pipeline vẫn:
Deploy
Đây là:
Human-in-the-loop, not Human-driven deployment.
14. Step 9 — Production Environment Protection
Production cần có policy.
Ví dụ:
Production
│
├── Only approved pipeline
├── Required approval
├── Security scan must pass
├── Specific service connection
└── Audit deployment
Architecture:
Azure DevOps
│
▼
CD Pipeline
│
▼
Staging
│
┌─────┴─────┐
│ │
Tests Security
│ │
└─────┬─────┘
▼
Approval
│
┌────┴────┐
│ │
Reject Approve
│ │
▼ ▼
STOP Production
Production không còn là:
docker compose up
mà trở thành một controlled release process.
15. Step 10 — Image Lifecycle
Harbor sẽ dần chứa rất nhiều image.
Ví dụ:
checkout
├── 001
├── 002
├── 003
├── ...
├── 998
├── 999
└── 1000
Nếu giữ tất cả:
Storage
↑
│
│
│
└────────── tăng liên tục
Vì vậy cần retention policy.
Ví dụ:
Keep latest 30 versions
hoặc:
Delete images older than 90 days
nhưng phải cẩn thận:
DO NOT DELETE
│
├── Production image
├── Release image
└── Compliance-required artifact
Lifecycle policy phải hiểu:
Artifact nào đang được sử dụng?
16. Step 11 — Immutable Artifact
Một Production artifact không nên bị thay đổi sau khi release.
Ví dụ:
checkout:v1.8.3
đã được Production sử dụng.
Không nên build lại rồi overwrite:
checkout:v1.8.3
với nội dung khác.
Nếu:
v1.8.3
đã tồn tại:
v1.8.3
│
└── immutable
Muốn release mới:
v1.8.4
Điều này làm rollback đáng tin cậy hơn.
17. Rollback bây giờ trở nên đơn giản hơn
Production:
Current:
checkout:a81f32c
Bug xuất hiện.
Image trước đó:
checkout:91bc721
Rollback:
Production
│
▼
checkout:91bc721
Không cần:
git checkout
docker build
lại.
Chúng ta chỉ deploy artifact đã tồn tại.
Đây là một trong những lợi ích lớn nhất của artifact management.
18. Step 12 — Audit
Production cần biết:
Who?
What?
When?
Where?
Why?
Ví dụ:
Who:
Release Manager
What:
checkout:a81f32c
When:
2026-09-04 10:30
Environment:
Production
Result:
Success
Khi xảy ra incident:
Production broke
│
▼
What changed?
│
▼
Which image?
│
▼
Which commit?
│
▼
Who approved?
Nếu không có audit trail, incident investigation sẽ rất khó.
19. Architecture cuối Phase 4
Đây là architecture chúng ta muốn đạt được:
Developer
│
│ git push
▼
┌─────────┐
│ GitHub │
└────┬────┘
│
▼
┌───────────────────┐
│ Azure DevOps │
│ │
│ CI │
│ │
│ Build │
│ Test │
│ Security Scan │
│ Docker Build │
└────────┬──────────┘
│
│ Push
▼
┌───────────────────┐
│ Harbor │
│ │
│ Registry │
│ RBAC │
│ Robot Accounts │
│ Scan │
│ Retention │
└────────┬──────────┘
│
Immutable Image
│
┌───────────┼───────────┐
▼ ▼ ▼
DEV STAGING PROD
│
Approval
│
▼
Production
20. Release Flow hoàn chỉnh
Bây giờ một release đi qua:
Code
│
▼
Git Push
│
▼
CI
│
├── Build
├── Test
├── Lint
└── Security Scan
│
▼
Docker Image
│
▼
Harbor
│
▼
Dev
│
▼
Integration Test
│
▼
Staging
│
▼
Approval
│
▼
Production
Mỗi bước đều có một mục đích.
Không có technology nào xuất hiện chỉ để "cho đủ stack".
21. Production Policy
Bây giờ chúng ta có thể định nghĩa policy rõ ràng:
Policy 1
Every production deployment
must come from CI/CD.
Không SSH deploy trực tiếp.
Policy 2
Production image must come from Harbor.
Không pull image tùy ý từ Internet.
Policy 3
Production image must pass security policy.
Policy 4
Production deployment requires approval.
Policy 5
Production artifact must be immutable.
Policy 6
Every deployment must be auditable.
Đây chính là Release Governance.
22. Từ DevOps đến Platform Governance
Hãy nhìn sự tiến hóa:
Phase 1
────────────
"Deploy được"
Phase 2
────────────
"Deploy tự động"
Phase 3
────────────
"100 service deploy
theo cùng một standard"
Phase 4
────────────
"Chỉ artifact đáng tin cậy
mới được vào Production"
Đây là một bước trưởng thành rất lớn.
23. Nhưng Production vẫn còn một vấn đề
Hãy tưởng tượng công ty tiếp tục phát triển.
Chúng ta có:
100 services
500 developers
10 environments
50 deployments/day
Cloud VM + Docker Compose bắt đầu trở thành vấn đề.
Một VM không thể mãi chạy:
Container 1
Container 2
Container 3
...
Container 100
Chúng ta cần:
Auto Scaling
Service Discovery
Self Healing
Rolling Deployment
Load Balancing
Resource Scheduling
Và lúc này:
Docker Compose
↓
???
Không thể giải quyết tốt nữa.
24. Kubernetes xuất hiện vì Production cần nó
Architecture tiếp theo:
Harbor
│
▼
Docker Images
│
▼
┌─────────────────┐
│ Kubernetes │
│ │
│ Deployment │
│ Service │
│ Ingress │
│ HPA │
│ │
└─────────────────┘
Nhưng Kubernetes lại tạo ra một vấn đề mới:
Ai sẽ quản lý hàng trăm Kubernetes manifests và deployment state?
Nếu tiếp tục:
Azure DevOps
│
▼
kubectl apply
│
▼
Kubernetes
thì chúng ta lại có một vấn đề:
Pipeline
│
▼
Imperative Deployment
Khi số lượng environment và service tăng, việc quản lý deployment bằng pipeline sẽ trở nên khó kiểm soát.
Đây chính là lúc GitOps + ArgoCD xuất hiện.
25. Architecture Evolution
Toàn bộ journey bây giờ đã trở nên rất rõ:
PHASE 1 — STARTUP
────────────────────────
Cloud VM
Docker Compose
Problem:
Manual deployment
↓
PHASE 2 — AUTOMATION
────────────────────────
Azure DevOps
Build → Test → Deploy
Problem:
Many pipelines
↓
PHASE 3 — PLATFORM
────────────────────────
Reusable CI/CD
Templates
Self-Service
Problem:
Artifact Governance
↓
PHASE 4 — PRODUCTION
────────────────────────
Harbor
RBAC
Robot Accounts
Security Scan
Retention
Approval
Audit
Problem:
Container orchestration
and deployment state
↓
PHASE 5 — PLATFORM SCALE
────────────────────────
Kubernetes
GitOps
ArgoCD
Problem:
Production reliability
and operational complexity
26. Senior Thinking
Ở Phase 4, bạn cần thay đổi cách suy nghĩ.
Junior thường hỏi:
"Harbor dùng lệnh nào?"
Senior hỏi:
"Tại sao organization cần Harbor?"
Junior hỏi:
"Robot Account tạo thế nào?"
Senior hỏi:
"Pipeline cần quyền gì và blast radius nếu credential bị lộ là bao nhiêu?"
Junior hỏi:
"Scan image như thế nào?"
Senior hỏi:
"Security scan fail thì release process phải phản ứng thế nào?"
Junior hỏi:
"Approval Gate cấu hình ở đâu?"
Senior hỏi:
"Deployment nào cần approval và tại sao?"
Junior hỏi:
"Xóa image cũ thế nào?"
Senior hỏi:
"Artifact nào có thể xóa mà không phá rollback hoặc compliance?"
Đó chính là sự khác biệt giữa:
Tool Knowledge
và:
Engineering Judgment
27. 7 nguyên tắc cần nhớ
① Build Once
Source
↓
Build
↓
Artifact
Một artifact.
② Promote, Don't Rebuild
Dev
↓
Staging
↓
Production
Cùng artifact.
③ Immutable Artifact
v1.5 = v1.5
Không overwrite.
④ Least Privilege
Pipeline
↓
Only required permissions
⑤ Security as a Gate
Scan FAIL
↓
STOP
Không phải scan để "cho có".
⑥ Production Requires Governance
Staging
↓
Approval
↓
Production
⑦ Everything Must Be Traceable
Production
↓
Image
↓
Git Commit
↓
Pipeline
↓
Deployment
Key Takeaways
Phase 4 biến hệ thống từ:
"Chúng ta có thể deploy"
thành:
"Chúng ta biết chính xác
cái gì được deploy,
ai được deploy,
artifact có an toàn không,
và tại sao nó được phép
vào Production."
Architecture cuối cùng:
Developer
↓
GitHub
↓
Azure DevOps
│
├── Build
├── Test
├── Scan
└── Package
↓
Harbor
│
│ Immutable Artifact
▼
Dev
↓
Staging
↓
[Approval]
↓
Production
Nhưng đến đây, chúng ta gặp một giới hạn mới:
Docker Compose + Cloud VM không còn đủ khả năng quản lý Production ở quy mô lớn.
Chúng ta cần một hệ thống có khả năng:
Schedule
Scale
Self-Heal
Load Balance
Rolling Update
Service Discovery
Và quan trọng hơn:
Deployment state phải được quản lý theo một cách có thể audit, review và tự động reconcile.
Đó là lý do Phase tiếp theo sẽ chuyển sang một bước thay đổi kiến trúc rất lớn:
Phase 5 — GitOps Platform: Kubernetes + ArgoCD
Từ đây, chúng ta sẽ không còn nói:
"Pipeline SSH vào server và deploy."
mà chuyển sang:
Git
↓
Desired State
↓
ArgoCD
↓
Kubernetes
↓
Actual State
Và câu hỏi trung tâm của Phase 5 sẽ là:
"Làm thế nào để Production luôn tự động hội tụ về trạng thái mà chúng ta định nghĩa trong Git?"
All Rights Reserved