0

Lab 6 — Multiple Environments với Helm

🎯 Mục tiêu

Sau Lab này, bạn sẽ:

  • Hiểu tại sao một application cần nhiều Environment.
  • Biết cách dùng Helm để quản lý dev, staging, production.
  • Hiểu vai trò của values.yaml và các file values-*.yaml.
  • Biết cách tránh copy cả Helm Chart cho từng environment.
  • Biết cách review configuration giữa các environment.
  • Hiểu một số nguyên tắc production khi quản lý nhiều environment.

Mục tiêu của Lab này không phải học thuộc cách override Values.

Chỉ cần nhớ một mental model:

1 Chart
   +
Nhiều Values
   ↓
Nhiều Environment

1. 🤔 Vấn đề thực tế

Hãy tưởng tượng bạn có một Todo API.

Trong quá trình phát triển, application chạy ở:

Dev
Staging
Production

Nhưng mỗi môi trường có configuration khác nhau.

Ví dụ:

Configuration Dev Staging Production
Replicas 1 2 3
Image dev rc-1 1.0.0
Ingress
Resources Nhỏ Vừa Lớn
Log level DEBUG INFO WARN

Nếu không dùng Helm, bạn có thể bắt đầu copy:

kubernetes/
├── dev/
├── staging/
└── production/

Sau một thời gian:

dev/deployment.yaml
staging/deployment.yaml
production/deployment.yaml

Ba file gần như giống nhau.

Nhưng một ngày bạn sửa:

readinessProbe:

Bạn phải nhớ sửa cả 3 nơi.

Rất dễ xảy ra:

Dev       → đúng
Staging   → đúng
Production → quên sửa

Đây chính là vấn đề configuration drift — các environment dần trở nên khác nhau ngoài những khác biệt mà chúng ta thực sự mong muốn.


2. 🧠 Helm giải quyết thế nào?

Thay vì:

3 Environment
   ↓
3 Chart

chúng ta dùng:

                 Helm Chart
                     │
          ┌──────────┼──────────┐
          │          │          │
         Dev      Staging      Prod
          │          │          │
          ▼          ▼          ▼
      values-dev  values-stg  values-prod

Structure:

todo-app/
├── Chart.yaml
├── values.yaml
├── values-dev.yaml
├── values-staging.yaml
├── values-prod.yaml
└── templates/
    ├── deployment.yaml
    ├── service.yaml
    ├── configmap.yaml
    └── ingress.yaml

Template giữ logic chung.

Values chứa khác biệt giữa các environment.


3. 🏗️ Architecture

Có thể hình dung:

                       Helm Chart
                           │
                  ┌────────┴────────┐
                  │                 │
             templates/          Values
                  │                 │
                  │        ┌────────┼────────┐
                  │        │        │        │
                  │       Dev    Staging    Prod
                  │        │        │        │
                  └────────┼────────┼────────┘
                           │
                           ▼
                    Kubernetes Cluster

Trong một hệ thống lớn, các environment có thể nằm trên:

Dev        → Cluster Dev
Staging    → Cluster Staging
Production → Cluster Production

hoặc cùng một cluster nhưng khác namespace:

Cluster
├── todo-dev
├── todo-staging
└── todo-prod

Helm không bắt buộc architecture nào.

Nó chỉ giúp quản lý configuration và release.


4. 🧠 Base Values và Environment Values

Thông thường Chart có:

values.yaml

Đây là default configuration.

Ví dụ:

replicaCount: 1

image:
  repository: todo-api
  tag: latest

service:
  port: 8080

ingress:
  enabled: false

Sau đó:

values-dev.yaml
values-staging.yaml
values-prod.yaml

chỉ override những gì khác.

Ví dụ Production:

replicaCount: 3

image:
  tag: "1.0.0"

ingress:
  enabled: true
  host: todo.example.com

Mental model:

values.yaml
   │
   │ Default
   ▼
values-prod.yaml
   │
   │ Override
   ▼
Final Configuration

5. 🧪 Chuẩn bị Lab

Tạo Chart:

helm create todo-app
cd todo-app

Tạo:

touch values-dev.yaml
touch values-staging.yaml
touch values-prod.yaml

Structure:

todo-app/
├── Chart.yaml
├── values.yaml
├── values-dev.yaml
├── values-staging.yaml
├── values-prod.yaml
└── templates/

6. 🧪 Thiết lập Base Configuration

Mở values.yaml:

replicaCount: 1

image:
  repository: nginx
  tag: "1.27"

service:
  type: ClusterIP
  port: 80

resources:
  requests:
    cpu: 100m
    memory: 128Mi

  limits:
    cpu: 300m
    memory: 256Mi

ingress:
  enabled: false

Đây là configuration chung.


7. 🧪 Dev Environment

Tạo values-dev.yaml:

replicaCount: 1

image:
  tag: "dev"

resources:
  requests:
    cpu: 50m
    memory: 64Mi

  limits:
    cpu: 200m
    memory: 128Mi

ingress:
  enabled: false

Dev có thể dùng:

1 replica
Resource nhỏ
Không cần public Ingress

8. 🧪 Staging Environment

values-staging.yaml:

replicaCount: 2

image:
  tag: "rc-1"

resources:
  requests:
    cpu: 100m
    memory: 128Mi

  limits:
    cpu: 300m
    memory: 256Mi

ingress:
  enabled: true
  host: todo-staging.example.com

Staging gần production hơn:

2 replicas
Resources lớn hơn
Có Ingress

9. 🧪 Production Environment

values-prod.yaml:

replicaCount: 3

image:
  tag: "1.0.0"

resources:
  requests:
    cpu: 200m
    memory: 256Mi

  limits:
    cpu: 500m
    memory: 512Mi

ingress:
  enabled: true
  host: todo.example.com

Production:

3 replicas
Resource lớn hơn
Image version cố định
Public Ingress

10. 🔍 Render từng Environment

Đây là bước quan trọng nhất.

Dev

helm template todo-dev . \
  -f values-dev.yaml

Kiểm tra:

replicas: 1

Staging

helm template todo-staging . \
  -f values-staging.yaml

Kiểm tra:

replicas: 2

Production

helm template todo-prod . \
  -f values-prod.yaml

Kiểm tra:

replicas: 3

11. 🧠 Điều gì thực sự xảy ra?

Khi chạy:

helm template todo-prod . \
  -f values-prod.yaml

Helm không tạo một Chart mới.

Nó làm:

                    values.yaml
                         │
                         ▼
                   Default Values
                         │
                         │ override
                         ▼
                  values-prod.yaml
                         │
                         ▼
                 Final Values
                         │
                         ▼
                    templates/
                         │
                         ▼
                  Rendered YAML

Đây là mental model quan trọng nhất của Lab.


12. 🚀 Deploy Dev

Nếu bạn có Kubernetes cluster:

helm upgrade --install todo-dev . \
  -f values-dev.yaml \
  -n todo-dev \
  --create-namespace

Kiểm tra:

helm list -n todo-dev

và:

kubectl get pods -n todo-dev

13. 🚀 Deploy Staging

helm upgrade --install todo-staging . \
  -f values-staging.yaml \
  -n todo-staging \
  --create-namespace

Kiểm tra:

helm list -n todo-staging

14. 🚀 Deploy Production

helm upgrade --install todo-prod . \
  -f values-prod.yaml \
  -n todo-prod \
  --create-namespace

Kiểm tra:

helm list -n todo-prod

Bây giờ:

Kubernetes Cluster
│
├── todo-dev
│    └── todo-dev
│
├── todo-staging
│    └── todo-staging
│
└── todo-prod
     └── todo-prod

Một Chart.

Ba Release.

Ba Environment.


15. 🧠 Chart ≠ Release ≠ Environment

Đây là một điểm rất dễ nhầm.

Chart

Là package/template:

todo-app/

Release

Là một instance của Chart được Helm quản lý.

todo-dev
todo-staging
todo-prod

Environment

Là nơi application đang chạy với một bộ configuration và infrastructure cụ thể.

Ví dụ:

Dev Environment
   ↓
Release: todo-dev
   ↓
values-dev.yaml
Production Environment
   ↓
Release: todo-prod
   ↓
values-prod.yaml

Mental model:

Chart
  │
  ├── Release Dev
  │      └── values-dev
  │
  ├── Release Staging
  │      └── values-staging
  │
  └── Release Production
         └── values-prod

16. 🔍 So sánh các Environment

Một trong những việc DevOps thường làm là:

"Production khác Staging ở đâu?"

Bạn có thể render cả hai:

helm template todo-staging . \
  -f values-staging.yaml \
  > staging.yaml
helm template todo-prod . \
  -f values-prod.yaml \
  > prod.yaml

Sau đó:

diff staging.yaml prod.yaml

Điều này rất hữu ích khi review.

Ví dụ bạn phát hiện:

Staging:
replicas: 2

Production:
replicas: 3

Đây là khác biệt có chủ đích.

Nhưng nếu phát hiện:

Staging:
readinessProbe: enabled

Production:
readinessProbe: missing

thì có thể là bug configuration.


17. ⚠️ Configuration Drift

Một trong những lý do dùng Helm là giảm configuration drift.

Ví dụ:

Dev
 ├── Deployment
 ├── Service
 └── ConfigMap

Prod
 ├── Deployment
 ├── Service
 └── ConfigMap

Nếu copy YAML:

Developer sửa Dev
       ↓
Staging quên sửa
       ↓
Production khác hoàn toàn

Với Helm:

              Same Templates
                    │
         ┌──────────┼──────────┐
         ▼          ▼          ▼
       Dev        Staging      Prod

Khi sửa:

templates/deployment.yaml

logic chung được thay đổi cho tất cả environment.


18. ⚠️ Nhưng đừng cố làm mọi thứ giống nhau

Một lỗi khác là cố ép:

Dev = Production

Không cần thiết.

Dev có thể:

1 replica
CPU nhỏ
Ingress disabled
Debug logging

Production:

3+ replicas
CPU lớn hơn
Ingress enabled
Production logging

Mục tiêu không phải:

Mọi environment giống hệt nhau.

Mà là:

Chúng khác nhau có chủ đích.


19. 🔐 Secrets giữa các Environment

Đây là vấn đề rất quan trọng.

Bạn có thể nghĩ:

values-dev.yaml
values-staging.yaml
values-prod.yaml

và đặt:

database:
  password: my-password

Nhưng không nên commit production password vào Git.

Thay vào đó có thể dùng:

External Secrets
SOPS
Sealed Secrets
Vault
Cloud Secret Manager

Ví dụ mental model:

Git
 │
 ├── Helm Chart
 ├── values-dev.yaml
 └── values-prod.yaml
          │
          │ no plaintext password
          ▼
     Secret Manager
          │
          ▼
     Kubernetes Secret

Trong thực tế:

ConfigurationSecret nên được quản lý theo hai cách khác nhau.


20. 🧠 Một câu hỏi quan trọng: Có nên có values-prod.yaml?

Có.

Nhưng file này nên chứa:

Non-sensitive configuration

Ví dụ:

replicaCount: 3

image:
  tag: "1.0.0"

resources:
  ...

ingress:
  ...

Không nên chứa:

password
private key
API secret
database credential

21. 🧪 Environment Variables từ CI/CD

Trong production, bạn thường không deploy thủ công:

helm upgrade ...

CI/CD pipeline sẽ làm.

Ví dụ:

Git Push
    │
    ▼
CI/CD
    │
    ├── Build Image
    │
    ├── Test
    │
    └── Helm Upgrade
             │
             ▼
       Kubernetes

Pipeline có thể chọn:

dev branch
    ↓
values-dev.yaml

hoặc:

release
    ↓
values-prod.yaml

22. 🚨 Một lỗi production rất nguy hiểm

Giả sử bạn đang deploy:

Production

nhưng vô tình chạy:

helm upgrade --install todo-prod . \
  -f values-dev.yaml \
  -n todo-prod

Helm vẫn có thể deploy thành công.

Nhưng production sẽ nhận:

1 replica
dev image
small resources

😱

Đây là lý do CI/CD production cần kiểm soát rõ:

Environment
      ↓
Values file
      ↓
Kubernetes namespace / cluster

Không nên dựa hoàn toàn vào trí nhớ của người deploy.


23. 🛡️ Production Best Practices

1. Environment phải explicit

Thay vì:

helm upgrade todo-app .

production nên rõ ràng:

helm upgrade --install todo-prod . \
  -f values-prod.yaml \
  -n todo-prod

Nhìn command là biết:

Release
Values
Namespace

2. Production không nên dùng latest

Không nên:

image:
  tag: latest

Nên:

image:
  tag: "1.5.2"

hoặc tốt hơn:

image:
  digest: "sha256:..."

Mục tiêu là deployment có tính deterministic — cùng configuration thì biết chính xác image nào được chạy.


3. Không copy Chart

Không nên:

todo-app-dev/
todo-app-staging/
todo-app-prod/

Nếu 3 Chart gần như giống nhau.

Nên:

todo-app/
├── templates/
├── values.yaml
├── values-dev.yaml
├── values-staging.yaml
└── values-prod.yaml

4. Values file nên dễ đọc

Một DevOps Engineer mở:

values-prod.yaml

nên nhanh chóng hiểu:

Image
Replicas
Resources
Network
Application config

Không nên biến nó thành một file khổng lồ với hàng trăm option mà không có structure rõ ràng.


24. 🧪 Exercise 1 — Tạo 3 Environment

Tạo:

values-dev.yaml
values-staging.yaml
values-prod.yaml

Cấu hình:

Dev
  replicas = 1

Staging
  replicas = 2

Production
  replicas = 3

Render cả 3.

Kiểm tra:

Deployment.spec.replicas

25. 🧪 Exercise 2 — Environment-specific Image

Dev:

image:
  tag: dev

Staging:

image:
  tag: rc-1

Production:

image:
  tag: "1.0.0"

Render:

helm template todo-dev . -f values-dev.yaml
helm template todo-staging . -f values-staging.yaml
helm template todo-prod . -f values-prod.yaml

Xác nhận image khác nhau.


26. 🧪 Exercise 3 — Ingress

Yêu cầu:

Dev
  Ingress disabled

Staging
  Ingress enabled
  todo-staging.example.com

Production
  Ingress enabled
  todo.example.com

Render và kiểm tra:

Dev
  → Không có Ingress

Staging
  → Có Ingress

Production
  → Có Ingress

27. 🧪 Exercise 4 — Tìm Configuration Drift

Render:

helm template todo-staging . \
  -f values-staging.yaml \
  > staging.yaml
helm template todo-prod . \
  -f values-prod.yaml \
  > prod.yaml

Sau đó:

diff staging.yaml prod.yaml

Liệt kê:

3 differences có chủ đích
3 differences bất ngờ

Đây là bài tập rất gần với công việc thực tế.


28. 🧪 Exercise 5 — Production Deployment Review

Giả sử bạn nhận được:

values-prod.yaml

Hãy review và trả lời:

□ Image có fixed version không?

□ Replica có hợp lý không?

□ Resources đã có chưa?

□ Ingress có đúng domain không?

□ Probe có được bật không?

□ Secret có bị commit trực tiếp không?

□ Configuration nào khác Staging?

□ Những khác biệt đó có chủ đích không?

Đây chính là kỹ năng bạn sẽ sử dụng khi review Helm Chart do AI tạo.


29. 🧠 Mental Model cần nhớ

Đừng cố nhớ:

-f
--set
merge precedence

theo kiểu học thuộc syntax.

Hãy nhớ:

                    ONE CHART
                        │
            ┌───────────┼───────────┐
            │           │           │
          DEV         STAGING       PROD
            │           │           │
            ▼           ▼           ▼
        Values Dev  Values Stg  Values Prod
            │           │           │
            └───────────┼───────────┘
                        ▼
                  Final Config
                        │
                        ▼
                  Kubernetes

Một Chart = logic chung.

Values = sự khác biệt giữa environment.


30. 🎯 Tổng kết

Sau Lab này, bạn chỉ cần nhớ 5 ý:

1. Không copy Chart cho từng Environment

❌ Chart Dev
❌ Chart Staging
❌ Chart Prod

✅ Một Chart

2. Mỗi Environment có Values riêng

values-dev.yaml
values-staging.yaml
values-prod.yaml

3. Template chứa logic chung

templates/

không nên chứa configuration riêng của từng environment.

4. Render trước khi deploy

helm template ...

Đặc biệt với Production.

5. Khác biệt phải có chủ đích

Dev ≠ Staging ≠ Production

không phải vấn đề.

Vấn đề là:

Dev ≠ Staging ≠ Production
          ↑
   Không biết tại sao

🧠 Một câu cuối cùng

Nếu sau này bạn được giao:

"Maintain Helm charts for multiple environments."

Bạn nên nghĩ ngay:

                 Helm Chart
                      │
              ┌───────┼───────┐
              │       │       │
             Dev   Staging   Prod
              │       │       │
           Values   Values   Values
              │       │       │
              └───────┼───────┘
                      ▼
                 Kubernetes

Đó mới là bản chất của Multiple Environments với Helm.

Bạn không cần thuộc hàng loạt syntax Helm. Bạn cần nhìn vào một Chart và trả lời được:

"Logic nào dùng chung, configuration nào khác nhau, và sự khác nhau đó có thực sự có chủ đích hay không?"

Đó là mức kiến thức rất thực tế để review, maintain và debug Helm Chart, đặc biệt trong workflow mà AI hỗ trợ viết phần lớn YAML/template.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí