Lab 4 — Kubernetes Configuration với Helm
🎯 Mục tiêu
Sau Lab này, bạn sẽ:
- Hiểu Helm dùng Values để customize Kubernetes resources như thế nào.
- Biết cách cấu hình các thành phần thường gặp: Deployment, Service, ConfigMap, Secret và Ingress.
- Hiểu cách một application Chart gom các configuration vào
values.yaml. - Biết cách review một Chart để tìm configuration quan trọng.
- Hiểu một số lỗi production thường gặp khi configuration Helm không khớp với Kubernetes.
Mục tiêu của Lab này không phải học syntax của từng Kubernetes resource.
Bạn đã học Kubernetes ở các Lab trước. Ở đây chúng ta tập trung vào câu hỏi:
"Nếu đã có Kubernetes resource, Helm giúp chúng ta configure nó như thế nào?"
1. 🤔 Vấn đề thực tế
Giả sử bạn có Todo API chạy trên Kubernetes.
Application cần:
Todo API
│
├── Deployment
├── Service
├── ConfigMap
├── Secret
└── Ingress
Nếu viết YAML trực tiếp, bạn có thể phải sửa:
deployment.yaml
service.yaml
configmap.yaml
secret.yaml
ingress.yaml
khi muốn thay đổi:
replica
image
port
environment
domain
resource
Vấn đề xuất hiện khi có nhiều environment:
Dev
└── todo.example-dev.com
Staging
└── todo.example-staging.com
Production
└── todo.example.com
Bạn không muốn copy toàn bộ Kubernetes YAML cho từng environment.
Helm cho phép chúng ta tách:
Kubernetes Structure
│
│ Template
▼
Helm Chart
▲
│ Values
│
┌───────────┼───────────┐
│ │ │
Dev Staging Prod
Template giữ cấu trúc.
Values chứa phần cần thay đổi.
2. 🧠 Hiểu nhanh
Một application Chart thường có:
my-app/
├── values.yaml
└── templates/
├── deployment.yaml
├── service.yaml
├── configmap.yaml
├── secret.yaml
└── ingress.yaml
Có thể hiểu:
values.yaml
│
├── image
├── replicaCount
├── resources
├── service
├── ingress
└── config
│
▼
templates/
│
├── Deployment
├── Service
├── ConfigMap
├── Secret
└── Ingress
3. 🏗️ Architecture
Một application thực tế có thể có flow:
User
│
▼
Ingress
│
▼
Service
│
▼
Deployment
│
┌─────┴─────┐
▼ ▼
Pod Pod
│
┌────────┴────────┐
│ │
ConfigMap Secret
│ │
└────────┬────────┘
▼
Application
Helm đứng bên ngoài để tạo và configure toàn bộ:
Helm Chart
│
┌──────────┴──────────┐
│ │
values.yaml templates/
│ │
└──────────┬──────────┘
▼
Kubernetes Resources
4. 🧪 Chuẩn bị Lab
Tạo Chart:
helm create todo-app
cd todo-app
Để bài học dễ hiểu, chúng ta sẽ tập trung vào các resource chính.
Bạn có thể xóa bớt các template mặc định nếu muốn:
rm -f templates/tests/test-connection.yaml
Các file chính:
templates/
├── deployment.yaml
├── service.yaml
├── configmap.yaml
├── secret.yaml
└── ingress.yaml
5. 🚀 Deployment — Cấu hình Application
Tại sao cần?
Deployment quyết định application chạy như thế nào:
image
replicas
resources
probes
environment
Ví dụ configuration:
replicaCount: 3
image:
repository: todo-api
tag: "1.0.0"
Template:
spec:
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: todo-api
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
Helm render:
spec:
replicas: 3
template:
spec:
containers:
- name: todo-api
image: "todo-api:1.0.0"
Mental Model
values.yaml
│
├── replicaCount
└── image
│
▼
deployment.yaml
│
▼
Kubernetes Deployment
6. 🧪 Thực hành — Customize Image
Trong values.yaml:
image:
repository: nginx
tag: "1.27"
Render:
helm template todo-app .
Tìm:
image:
Bạn sẽ thấy:
image: nginx:1.27
Thử:
helm template todo-app . \
--set image.tag=1.28
Kết quả:
image: nginx:1.28
Understand
Bạn vừa thay đổi image của application mà không sửa:
templates/deployment.yaml
7. 📈 Resource Requests & Limits
Trong production, đây là configuration rất quan trọng.
Nếu Pod không có resource request/limit, Kubernetes khó biết nên phân bổ CPU và Memory như thế nào.
Values:
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
Template:
resources:
{{- toYaml .Values.resources | nindent 12 }}
Bạn không cần học thuộc toYaml hay nindent.
Chỉ cần hiểu:
values.resources
│
▼
Deployment.resources
Render:
helm template todo-app .
Kết quả:
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
8. ❤️ Health Check
Application production nên có:
Liveness Probe
Readiness Probe
Ví dụ Values:
probes:
enabled: true
Template có thể condition:
if probes.enabled
│
├── true → render probes
│
└── false → không render
Ví dụ:
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
Tại sao Helm cần phần này?
Dev có thể:
probe.enabled = false
Production:
probe.enabled = true
hoặc thay đổi endpoint:
probes:
path: /health
mà không sửa template.
9. 🌐 Service — Cho Pod một địa chỉ ổn định
Pod có thể bị tạo lại.
Vì vậy application không nên phụ thuộc trực tiếp vào IP của Pod.
Service cung cấp một endpoint ổn định:
Client
│
▼
Service
│
├── Pod
├── Pod
└── Pod
Values:
service:
type: ClusterIP
port: 80
targetPort: 8080
Template:
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.service.targetPort }}
Helm render:
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
10. ⚠️ Một lỗi production rất hay gặp
Ví dụ:
Service
port: 80
targetPort: 8080
Application thực tế lại chạy:
port: 8081
Kết quả:
Ingress
↓
Service :80
↓
Pod :8080
X
Application :8081
Request sẽ fail.
Khi debug Helm application, đừng chỉ nhìn:
helm status
Hãy kiểm tra cả:
kubectl get svc
kubectl describe svc <service>
kubectl get pods
và đặc biệt:
kubectl get endpoints
Mental model:
Service.targetPort
│
▼
Container.port
│
▼
Application listening port
Ba thứ này phải khớp về mặt logic.
11. 📋 ConfigMap — Configuration không nhạy cảm
Application thường cần configuration:
LOG_LEVEL=info
SPRING_PROFILES_ACTIVE=production
API_URL=https://api.example.com
Không nên hard-code trực tiếp trong Deployment template.
Dùng ConfigMap:
config:
LOG_LEVEL: info
ENVIRONMENT: production
Helm có thể render:
apiVersion: v1
kind: ConfigMap
metadata:
name: todo-app-config
data:
LOG_LEVEL: info
ENVIRONMENT: production
Application Pod sử dụng ConfigMap:
ConfigMap
│
│ environment variables
▼
Pod
│
▼
Application
12. 🧪 Thực hành — ConfigMap
Thêm vào values.yaml:
config:
LOG_LEVEL: info
ENVIRONMENT: dev
Template:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "todo-app.fullname" . }}
data:
LOG_LEVEL: {{ .Values.config.LOG_LEVEL | quote }}
ENVIRONMENT: {{ .Values.config.ENVIRONMENT | quote }}
Render:
helm template todo-app .
Kết quả:
data:
LOG_LEVEL: "info"
ENVIRONMENT: "dev"
Thử:
helm template todo-app . \
--set config.ENVIRONMENT=production
Kết quả:
ENVIRONMENT: "production"
13. 🔐 Secret — Configuration nhạy cảm
Một số configuration không nên để trong ConfigMap:
Database password
API key
Token
Credential
Ví dụ:
database:
username: app
password: secret
Về mặt Helm, bạn có thể render thành Kubernetes Secret.
Nhưng:
Không có nghĩa đặt password trực tiếp trong
values.yamlrồi commit Git là an toàn.
Đây là lỗi production rất phổ biến.
Có thể dùng:
External Secrets
SOPS
Sealed Secrets
Cloud Secret Manager
Vault
Tùy architecture.
Ở Lab này, bạn chỉ cần hiểu:
ConfigMap
↓
Non-sensitive configuration
Secret
↓
Sensitive configuration
Các phương pháp quản lý Secret thực tế sẽ được học sâu hơn sau.
14. 🌍 Ingress — Expose Application ra bên ngoài
Nếu application cần truy cập từ Internet:
Internet
│
▼
Ingress
│
▼
Service
│
▼
Pod
Values:
ingress:
enabled: true
host: todo.example.com
path: /
Template sử dụng:
.Values.ingress.enabled
.Values.ingress.host
.Values.ingress.path
Nếu:
enabled: false
Ingress không được render.
Nếu:
enabled: true
Ingress được tạo.
15. 🧪 Thực hành — Dev vs Production
Tạo:
values-dev.yaml
values-prod.yaml
Dev
replicaCount: 1
image:
tag: dev
ingress:
enabled: false
config:
ENVIRONMENT: dev
Production
replicaCount: 3
image:
tag: "1.0.0"
ingress:
enabled: true
host: todo.example.com
config:
ENVIRONMENT: production
Render Dev:
helm template todo-dev . \
-f values-dev.yaml
Render Production:
helm template todo-prod . \
-f values-prod.yaml
Bây giờ cùng một Chart tạo ra hai cấu hình khác nhau:
todo-app Chart
│
┌────────┴────────┐
│ │
values-dev.yaml values-prod.yaml
│ │
▼ ▼
Dev YAML Prod YAML
│ │
▼ ▼
Kubernetes Kubernetes
16. 🔍 Review một Helm Chart
Khi nhận một Helm Chart từ đồng nghiệp hoặc AI, bạn không cần đọc từng dòng.
Hãy đi theo thứ tự:
1. Đọc values.yaml
Hỏi:
Application có thể customize những gì?
Tìm:
image
replica
resources
service
config
secret
ingress
autoscaling
2. Đọc templates/deployment.yaml
Hỏi:
Values nào được sử dụng?
Kiểm tra:
image
resources
env
probes
ports
3. Đọc service.yaml
Kiểm tra:
port
targetPort
selector
4. Đọc ingress.yaml
Kiểm tra:
host
path
service
TLS
5. Render
Cuối cùng:
helm template todo-app . \
-f values-prod.yaml
Đừng chỉ review template.
Review output cũng rất quan trọng.
17. 🧠 Một Helm Chart tốt trông như thế nào?
Một Chart tốt nên cho phép developer configure application thông qua:
values.yaml
thay vì sửa:
templates/
Ví dụ:
image:
repository: todo-api
tag: "1.5.0"
replicaCount: 3
resources:
requests:
cpu: 200m
memory: 256Mi
service:
port: 8080
ingress:
enabled: true
host: todo.example.com
Developer chỉ cần thay values.
Không cần biết sâu về:
deployment.yaml
service.yaml
ingress.yaml
Đây chính là một dấu hiệu của Reusable Chart.
18. ⚠️ Production Tips
1. Đừng expose mọi thứ thành Value
Không phải configuration nào cũng cần:
foo:
bar:
baz:
Nếu một configuration không có lý do để customize, có thể giữ trực tiếp trong template.
Mục tiêu:
Enough flexibility
+
Simple interface
Không phải:
Maximum flexibility
2. Cẩn thận với replicaCount và HPA
Nếu:
replicaCount: 3
và:
autoscaling:
enabled: true
thì HPA có thể quản lý số replica.
Do đó Chart cần thiết kế rõ:
Manual scaling
OR
HPA scaling
Không nên để người dùng không biết:
"Ai đang quyết định số replica?"
3. Resource requests rất quan trọng
Production nên có:
resources:
requests:
cpu: ...
memory: ...
limits:
cpu: ...
memory: ...
Nếu AI tạo Chart mà bỏ hoàn toàn resources, hãy đặt câu hỏi:
Application này sẽ chạy production với resource configuration nào?
4. Đừng nhầm Helm configuration với Kubernetes behavior
Ví dụ:
replicaCount: 3
là Helm value.
Nhưng:
replicas: 3
là Kubernetes Deployment configuration.
Flow là:
Helm Value
│
▼
Template
│
▼
Kubernetes Field
Helm chỉ là lớp tạo configuration.
19. 🧪 Bài tập thực hành
Exercise 1 — Application Configuration
Tạo các values:
image:
repository: nginx
tag: "1.27"
replicaCount: 3
service:
port: 80
Render Chart và kiểm tra:
Deployment
Service
Exercise 2 — ConfigMap
Tạo:
config:
APP_ENV: production
LOG_LEVEL: info
Render và kiểm tra ConfigMap.
Exercise 3 — Ingress
Tạo:
ingress:
enabled: true
host: todo.example.com
Render.
Sau đó:
ingress:
enabled: false
Render lại.
Quan sát sự khác biệt.
Exercise 4 — Production Values
Tạo:
values-prod.yaml
với:
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
Render:
helm template todo-prod . \
-f values-prod.yaml
Sau đó kiểm tra output.
20. 🎯 Tổng kết
Trong Lab này, bạn đã thấy cách Helm biến một Kubernetes application thành một configuration-driven deployment.
Mental model:
values.yaml
│
┌─────────────┼─────────────┐
│ │ │
Image Replicas Ingress
│ │ │
└─────────────┼─────────────┘
│
▼
templates/
│
┌───────────────┼───────────────┐
▼ ▼ ▼
Deployment Service Ingress
│ │ │
└───────────────┼───────────────┘
▼
Kubernetes
🧠 Những gì cần nhớ
values.yaml
↓
Configuration
templates/
↓
Kubernetes resources
Deployment
↓
Chạy application
Service
↓
Địa chỉ ổn định cho Pod
ConfigMap
↓
Non-sensitive configuration
Secret
↓
Sensitive configuration
Ingress
↓
Expose application ra bên ngoài
Và khi review một Helm Chart, hãy luôn hỏi:
"Value này cuối cùng được render vào Kubernetes resource nào?"
Ví dụ:
.Values.replicaCount
↓
Deployment.spec.replicas
.Values.image.tag
↓
Deployment.container.image
.Values.service.port
↓
Service.spec.ports
.Values.ingress.host
↓
Ingress.spec.rules
Nếu bạn đọc một Chart và trace được các value theo cách này, bạn đã hiểu phần quan trọng của Helm Configuration mà không cần thuộc syntax.
Ở Lab tiếp theo, chúng ta sẽ tập trung vào Helm Debugging & Troubleshooting — cách tìm ra vấn đề khi Chart render sai, Kubernetes resource sai hoặc Release upgrade thất bại.
All rights reserved