0

🚀 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ó:

image.png

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.

image.png

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:

image.png

Đ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. Các bước thực thi

① 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

② 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.


③ 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.


④ 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

⑤ 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.


⑥ 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.


⑦ Image Promotion

Một image sau khi build không nên ngay lập tức trở thành Production image.

Flow:

image.png

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

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.


⑧ 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ế:

image.png

Approval nằm ở đây:

Staging
   │
   ▼
[ Approval ]
   │
   ▼
Production

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.


⑨ 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:

image.png

Production không còn là:

docker compose up

mà trở thành một controlled release process.


⑩ 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?


⑪ 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.


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.


⑫ 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ó.


5. Architecture cuối Phase 4

Đây là architecture chúng ta muốn đạt được:

image.png


6. Release Flow hoàn chỉnh

Bây giờ một release đi qua:

image.png

Mỗi bước đều có một mục đích.

Không có technology nào xuất hiện chỉ để "cho đủ stack".


7. 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.


8. 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.


9. 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.


10. Senior Thinking

Ở Phase 4, bạn cần thay đổi cách suy nghĩ.

Senior hỏi:

"Tại sao organization cần Harbor?"

"Pipeline cần quyền gì và blast radius nếu credential bị lộ là bao nhiêu?"

"Security scan fail thì release process phải phản ứng thế nào?"

"Deployment nào cần approval và tại sao?"

"Artifact nào có thể xóa mà không phá rollback hoặc compliance?"


11. 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."

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

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

Viblo
Let's register a Viblo Account to get more interesting posts.