0

Lab 12 — Final Project: Production-Ready Helm Chart

🎯 Mục tiêu

Đây là Lab tổng kết Phase Helm.

Sau Lab này, bạn sẽ tự xây dựng một Helm Chart hoàn chỉnh cho một ứng dụng Kubernetes và có khả năng:

  • Thiết kế một Helm Chart có cấu trúc rõ ràng, reusable.
  • Quản lý cấu hình bằng values.yaml cho nhiều environment.
  • Sử dụng ConfigMap, Secret, Deployment, Service và Ingress.
  • Kiểm tra và debug Chart trước khi deploy.
  • Package và publish Chart lên OCI Registry.
  • Xây dựng flow CI/CD cơ bản cho Helm.
  • Quan trọng nhất: đọc, review và sửa một Helm Chart do người khác hoặc AI viết.

Đây không phải bài học thêm syntax.

Đây là bài kiểm tra xem bạn có thể kết hợp những gì đã học thành một workflow thực tế hay chưa.


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

Hãy tưởng tượng team của bạn có một application:

Todo Application

Application cần chạy trên:

Development
Staging
Production

Mỗi environment có cấu hình khác nhau:

Dev
├── replicas: 1
├── image: todo-app:dev
└── resources: nhỏ

Staging
├── replicas: 2
├── image: todo-app:1.2.0
└── resources: trung bình

Production
├── replicas: 3
├── image: todo-app:1.2.0
└── resources: lớn

Nếu viết Kubernetes YAML riêng:

kubernetes/
├── dev/
│   ├── deployment.yaml
│   ├── service.yaml
│   └── ingress.yaml
│
├── staging/
│   ├── deployment.yaml
│   ├── service.yaml
│   └── ingress.yaml
│
└── production/
    ├── deployment.yaml
    ├── service.yaml
    └── ingress.yaml

rất dễ xảy ra:

Dev YAML       ≠ Staging YAML
Staging YAML   ≠ Production YAML

Và khi sửa một thứ:

Deployment

có thể phải sửa ở 3 nơi.

Helm giải quyết vấn đề này bằng cách tách:

Application Structure
        +
Environment Configuration

2. 🧠 Hiểu nhanh

Final Project sẽ kết hợp toàn bộ mental model của Phase:

                    Helm Chart
                        │
          ┌─────────────┼─────────────┐
          │             │             │
       Templates       Values       Helpers
          │             │
          │       ┌─────┼─────┐
          │       │     │     │
          │      Dev  Stage  Prod
          │
          ▼
 Kubernetes Manifests
          │
          ▼
      Validation
          │
          ▼
       Package
          │
          ▼
    OCI Registry
          │
          ▼
        Deploy

Bạn không cần nhớ từng syntax.

Chỉ cần hiểu:

Chart = application template

Values = configuration

Templates = Kubernetes manifests được sinh ra

OCI Registry = nơi lưu Chart artifact


3. 🏗️ Architecture

Project cuối sẽ có kiến trúc:

                         Git Repository
                               │
                               │
                        Helm Chart Source
                               │
                               ▼
                    ┌─────────────────────┐
                    │     Helm Chart      │
                    │                     │
                    │ Chart.yaml          │
                    │ values.yaml         │
                    │ values-dev.yaml     │
                    │ values-prod.yaml    │
                    │ templates/          │
                    └──────────┬──────────┘
                               │
                               ▼
                         Helm CI
                               │
                    ┌──────────┼──────────┐
                    │          │          │
                   Lint      Render     Test
                    │          │          │
                    └──────────┼──────────┘
                               │
                             PASS
                               │
                               ▼
                         helm package
                               │
                               ▼
                        OCI Registry
                               │
              ┌────────────────┼────────────────┐
              ▼                ▼                ▼
             Dev            Staging          Production

4. 📁 Project Structure

Tạo project:

mkdir helm-final-project
cd helm-final-project

helm create todo-app

Sau đó tổ chức lại:

helm-final-project/
│
├── todo-app/
│   │
│   ├── Chart.yaml
│   ├── values.yaml
│   ├── values-dev.yaml
│   ├── values-staging.yaml
│   ├── values-prod.yaml
│   │
│   ├── charts/
│   │
│   └── templates/
│       ├── _helpers.tpl
│       ├── deployment.yaml
│       ├── service.yaml
│       ├── ingress.yaml
│       ├── configmap.yaml
│       ├── secret.yaml
│       └── tests/
│
└── .github/
    └── workflows/
        └── helm-ci.yaml

Không nhất thiết phải giữ mọi file mà helm create sinh ra.

Giữ những gì application thực sự cần.

Một Chart production tốt thường không phải Chart có nhiều file nhất.


5. 🧠 Exercise 1 — Thiết kế Chart

Application cần:

Todo API

Các Kubernetes resources:

Deployment
Service
ConfigMap
Secret
Ingress

Architecture:

                    Internet
                       │
                       ▼
                    Ingress
                       │
                       ▼
                    Service
                       │
             ┌─────────┼─────────┐
             ▼         ▼         ▼
            Pod       Pod       Pod
             │         │         │
             └─────────┼─────────┘
                       │
                ┌──────┴──────┐
                │             │
           ConfigMap        Secret

6. 🧠 Exercise 2 — Thiết kế values.yaml

Thay vì hard-code:

replicas: 3

trong template:

replicas: {{ .Values.replicaCount }}

để configuration nằm trong:

replicaCount: 3

Mental model:

values.yaml
     │
     ▼
Templates
     │
     ▼
Kubernetes YAML

Một values.yaml cơ bản:

replicaCount: 2

image:
  repository: todo-app
  tag: "1.0.0"

service:
  port: 8080

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 512Mi

7. 🌍 Exercise 3 — Multiple Environments

Tạo:

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

values-dev.yaml

replicaCount: 1

image:
  tag: dev

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

values-staging.yaml

replicaCount: 2

image:
  tag: "1.0.0"

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

values-prod.yaml

replicaCount: 3

image:
  tag: "1.0.0"

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

Điểm quan trọng:

                 Same Chart
                     │
          ┌──────────┼──────────┐
          ▼          ▼          ▼
         Dev       Staging     Prod
          │          │          │
       values-dev  values-     values-
                  staging      prod

Không tạo 3 Chart khác nhau.


8. 🚀 Exercise 4 — Deploy Dev

Render trước:

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

Nếu kết quả đúng:

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

Kiểm tra:

helm list -n todo-dev

và:

kubectl get all -n todo-dev

9. 🧪 Exercise 5 — Deploy Staging

Render:

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

Deploy:

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

Kiểm tra:

kubectl get all -n todo-staging

Bây giờ bạn có:

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

Cùng một Chart.

Khác configuration.


10. 🧪 Exercise 6 — Production

Trước khi deploy Production:

helm lint ./todo-app

Render:

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

Kiểm tra kỹ:

replicas
image
resources
service
ingress
config
secret

Sau đó mới deploy:

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

11. 🔐 Exercise 7 — ConfigMap và Secret

Application thường cần configuration:

DATABASE_HOST
DATABASE_PORT
LOG_LEVEL

và secret:

DATABASE_USERNAME
DATABASE_PASSWORD

Không nên viết trực tiếp vào Deployment:

env:
  - name: DATABASE_PASSWORD
    value: "123456"

Thay vào đó:

Deployment
    │
    ├── ConfigMap
    │
    └── Secret

Ví dụ:

envFrom:
  - configMapRef:
      name: {{ include "todo-app.fullname" . }}
  - secretRef:
      name: {{ include "todo-app.fullname" . }}

Mental model quan trọng:

Helm
 │
 ├── Application configuration
 │
 └── Kubernetes Secret reference

Helm không phải là secret manager.

Trong production, secret thực tế có thể được quản lý bởi Vault, External Secrets, cloud secret manager, v.v.


12. 🌐 Exercise 8 — Ingress

Application cần expose ra ngoài:

Internet
    │
    ▼
Ingress
    │
    ▼
Service
    │
    ▼
Pods

Values:

ingress:
  enabled: true

  host: todo.example.com

Template:

values
  │
  ▼
Ingress Template
  │
  ▼
Kubernetes Ingress

Test:

kubectl get ingress -n todo-prod

13. 🧪 Exercise 9 — Testing & Validation

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

Không nên:

Write Chart
   ↓
Deploy Production

Flow tốt hơn:

Write Chart
   ↓
helm lint
   ↓
helm template
   ↓
helm test
   ↓
Package
   ↓
Publish

Lint

helm lint ./todo-app

Render

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

Test

helm test todo-app -n todo-prod

14. 🐛 Exercise 10 — Debugging Challenge

Bây giờ cố tình tạo một lỗi.

Ví dụ:

image:
  repository: todo-app-invalid

Deploy:

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

Kiểm tra:

kubectl get pods -n todo-dev

Bạn có thể thấy:

ImagePullBackOff

Debug:

kubectl describe pod <pod-name> -n todo-dev

và:

kubectl logs <pod-name> -n todo-dev

Sau đó sửa lại:

image:
  repository: todo-app

Upgrade:

helm upgrade todo-app ./todo-app \
  -f ./todo-app/values-dev.yaml \
  -n todo-dev

15. 🧠 Điều cần học từ Debugging

Khi Helm deploy lỗi, không phải lúc nào Helm là nguyên nhân.

Hãy chia vấn đề thành:

Helm
 │
 ├── Template lỗi?
 │
 └── Values sai?
         │
         ▼
    Kubernetes Manifest
         │
         ├── Deployment?
         ├── Service?
         ├── Ingress?
         └── Config?
                │
                ▼
             Pod
                │
                ├── Image?
                ├── Config?
                ├── Secret?
                └── Application?

Mental model:

Helm chỉ tạo Kubernetes resources. Sau đó Kubernetes và application vẫn có thể lỗi.


16. 📦 Exercise 11 — Package Chart

Sau khi mọi thứ hoạt động:

helm package ./todo-app

Bạn sẽ có:

todo-app-1.0.0.tgz

Kiểm tra:

helm show chart todo-app-1.0.0.tgz

17. 🚀 Exercise 12 — Publish OCI

Đăng nhập Registry:

helm registry login <registry>

Sau đó:

helm push todo-app-1.0.0.tgz \
  oci://<registry>/helm

Architecture:

Git
 │
 ▼
Helm Chart
 │
 ▼
helm package
 │
 ▼
todo-app-1.0.0.tgz
 │
 ▼
OCI Registry

18. 🧪 Exercise 13 — Install từ OCI

Không deploy trực tiếp từ source nữa.

Deploy từ artifact:

helm upgrade --install todo-app \
  oci://<registry>/helm/todo-app \
  --version 1.0.0 \
  -f values-prod.yaml \
  -n todo-prod

Đây là flow gần production hơn:

Developer
    │
    ▼
Git
    │
    ▼
CI
    │
    ▼
Helm Chart
    │
    ▼
OCI Registry
    │
    ▼
CD
    │
    ▼
Kubernetes

19. 🤖 Exercise 14 — CI/CD

Tạo:

.github/
└── workflows/
    └── helm-ci.yaml

Pipeline tối thiểu:

Pull Request
     │
     ▼
helm lint
     │
     ▼
helm template
     │
     ▼
Test
     │
     ▼
PASS

Khi merge:

main
 │
 ▼
helm package
 │
 ▼
helm push
 │
 ▼
OCI Registry

Sau đó:

OCI Registry
     │
     ▼
     Dev
     │
     ▼
   Staging
     │
     ▼
Production

Bạn đã hoàn thành vòng đời Helm cơ bản.


20. 🚨 Production Review

Trước khi coi Chart là "production-ready", hãy tự kiểm tra:

Structure

□ Chart.yaml rõ ràng
□ templates được tổ chức tốt
□ _helpers.tpl được sử dụng hợp lý
□ Không có file thừa

Configuration

□ Không hard-code configuration
□ Có values mặc định hợp lý
□ Có values cho environment
□ Production values được review

Kubernetes

□ Resources có requests/limits
□ Health checks có cấu hình
□ Deployment strategy phù hợp
□ Service đúng
□ Ingress đúng

Security

□ Không hard-code password
□ Không commit secret
□ Image version được pin
□ RBAC không cấp quyền dư thừa

Release

□ helm lint
□ helm template
□ helm test
□ helm package
□ OCI Registry
□ Version rõ ràng
□ Có rollback strategy

21. 🎯 Final Challenge

Bây giờ hãy xóa Chart cũ và thử tự xây lại từ đầu.

Yêu cầu:

Application

todo-app

Kubernetes Resources

Deployment
Service
ConfigMap
Secret
Ingress

Environments

dev
staging
production

Configuration

replicas
image
resources
service
ingress
environment variables

Release

Helm lint
     ↓
Helm template
     ↓
Helm test
     ↓
Package
     ↓
OCI Registry

Deployment

OCI Registry
     │
     ├── Dev
     ├── Staging
     └── Production

22. 🏆 Definition of Done

Bạn có thể coi Phase Helm hoàn thành khi:

✅ Có thể đọc một Helm Chart

✅ Hiểu Chart.yaml / values.yaml / templates

✅ Hiểu values → templates → Kubernetes YAML

✅ Biết cách override values

✅ Biết quản lý nhiều environment

✅ Biết sử dụng ConfigMap / Secret / Ingress

✅ Biết dùng dependencies

✅ Biết lint / template / test

✅ Biết debug Helm deployment

✅ Biết package Chart

✅ Biết OCI Registry

✅ Hiểu Helm trong CI/CD

✅ Biết rollback

✅ Có thể review Chart do AI tạo

🧠 Mental Model — Toàn bộ Phase Helm

Bạn chỉ cần nhớ bức tranh này:

                 Helm Chart
                     │
          ┌──────────┴──────────┐
          │                     │
      Templates              Values
          │                     │
          └──────────┬──────────┘
                     ▼
             Kubernetes YAML
                     │
                     ▼
                Validation
                     │
                     ▼
                  Package
                     │
                     ▼
               OCI Registry
                     │
             ┌───────┼───────┐
             ▼       ▼       ▼
            Dev   Staging   Prod

Và nếu phải nhớ một câu duy nhất:

Helm không phải thứ bạn cần học thuộc syntax; Helm là cách biến Kubernetes manifests thành một package có thể cấu hình, tái sử dụng, version hóa và tự động hóa việc release.

Đây cũng là mức kiến thức khá phù hợp với mục tiêu của bạn: đủ hiểu bản chất để review AI-generated Helm Chart, phát hiện thiết kế sai, debug khi deployment lỗi và kết hợp Helm vào CI/CD, thay vì dành quá nhiều thời gian học thuộc template syntax.


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í