Giao diện
Mastering Helm Charts: Stop Copy-Pasting YAML
🛠️ Góc nhìn Senior DevOps Tooling Engineer - HPN
Module này được viết với triết lý "Don't Repeat Yourself". Mục tiêu: Loại bỏ việc copy-paste YAML vô tận và quản lý Kubernetes resources một cách thông minh.
🔥 Vấn Đề: "YAML Hell"
Tình huống thực tế
Bạn có 3 môi trường: Dev, Staging, Production. Chúng gần như 99% giống nhau, chỉ khác:
| Môi trường | replicas | imageTag | resources.limits.memory |
|---|---|---|---|
| Dev | 1 | latest | 256Mi |
| Staging | 2 | v1.2.3 | 512Mi |
| Production | 5 | v1.2.3 | 1Gi |
text
❌ ANTI-PATTERN: Copy-Paste Nightmare
k8s/
├── dev/
│ ├── deployment.yaml # 👈 99% giống staging
│ ├── service.yaml
│ └── configmap.yaml
├── staging/
│ ├── deployment.yaml # 👈 Copy từ dev, sửa vài dòng
│ ├── service.yaml
│ └── configmap.yaml
└── production/
├── deployment.yaml # 👈 Copy từ staging, sửa vài dòng
├── service.yaml
└── configmap.yaml
Vấn đề:
- Sửa 1 chỗ → phải sửa 3 file
- Dễ quên sync → Drift between environments
- Review code kiểu gì? Diff 3 file 99% giống nhau?💀 HẬU QUẢ THỰC TẾ
bash
# Dev team sửa port trong dev/deployment.yaml
# Quên sửa ở staging và production
# 3 tuần sau: "Tại sao Production vẫn dùng port cũ?"🍪 Giải Pháp: Helm Templates
Helm là gì?
Helm = Package Manager for Kubernetes (như apt cho Ubuntu, npm cho Node.js)
💡 PHÉP SO SÁNH: KHUÔN BÁNH (Cookie Cutter)
- Template (
.tplfiles) = Khuôn bánh - Định nghĩa hình dạng - Values (
values.yaml) = Bột bánh - Thay đổi theo ý muốn - Chart = Bộ khuôn hoàn chỉnh - Template + giá trị mặc định
Cùng 1 khuôn, thay đổi bột (values) → ra bánh khác nhau!
Một file, nhiều môi trường
yaml
# ✅ HELM WAY: 1 Template, 3 Values files
charts/myapp/
├── Chart.yaml # ID Card của chart
├── values.yaml # Default values
├── values-dev.yaml # Override cho Dev
├── values-staging.yaml # Override cho Staging
├── values-prod.yaml # Override cho Production
└── templates/
├── deployment.yaml # Template với {{ .Values.xxx }}
└── service.yaml📦 Core Components
1. Chart.yaml - The ID Card
yaml
# Chart.yaml - Metadata của chart
apiVersion: v2
name: myapp
description: Backend API service cho HPN Platform
type: application
version: 1.2.0 # Version của CHART (thay đổi khi sửa chart)
appVersion: "3.5.1" # Version của APPLICATION (image tag)
# Dependencies (optional)
dependencies:
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"| Field | Ý nghĩa |
|---|---|
name | Tên chart (dùng trong helm install) |
version | Version của chart structure |
appVersion | Version của ứng dụng bên trong |
dependencies | Charts khác mà chart này cần |
2. values.yaml - The Configuration
yaml
# values.yaml - Default configuration
# ĐÂY LÀ FILE DUY NHẤT DEVS CẦN QUAN TÂM
replicaCount: 2
image:
repository: gcr.io/hpn/myapp
tag: "latest"
pullPolicy: IfNotPresent
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
service:
type: ClusterIP
port: 8080
# Feature flags
features:
enableCache: true
debugMode: false3. templates/ - The Logic Engine
yaml
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
labels:
app: {{ .Chart.Name }}
version: {{ .Chart.AppVersion }}
spec:
replicas: {{ .Values.replicaCount }} # 👈 Từ values.yaml
selector:
matchLabels:
app: {{ .Chart.Name }}
template:
metadata:
labels:
app: {{ .Chart.Name }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: {{ .Values.service.port }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- if .Values.features.debugMode }}
env:
- name: DEBUG
value: "true"
{{- end }}🔧 Template Syntax Essentials
Variables & Objects
yaml
# Truy cập values
{{ .Values.replicaCount }} # → 2
{{ .Values.image.repository }} # → gcr.io/hpn/myapp
# Built-in objects
{{ .Release.Name }} # → tên release (helm install NAME)
{{ .Release.Namespace }} # → namespace được deploy
{{ .Chart.Name }} # → tên chart từ Chart.yaml
{{ .Chart.AppVersion }} # → appVersion từ Chart.yamlConditionals: if
yaml
# Chỉ thêm resources nếu được định nghĩa
{{- if .Values.resources }}
resources:
{{- toYaml .Values.resources | nindent 2 }}
{{- end }}
# If-else
{{- if eq .Values.environment "production" }}
replicas: 5
{{- else }}
replicas: 1
{{- end }}Loops: range
yaml
# values.yaml
env:
- name: DB_HOST
value: localhost
- name: CACHE_TTL
value: "300"
# template
env:
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}Scope: with
yaml
# Thay vì lặp lại .Values.image nhiều lần
{{- with .Values.image }}
image: "{{ .repository }}:{{ .tag }}"
imagePullPolicy: {{ .pullPolicy }}
{{- end }}🚀 Essential Commands
Install, Upgrade, Rollback
bash
# 🆕 Install chart lần đầu
helm install myapp ./charts/myapp \
--namespace production \
--values values-prod.yaml
# 🔄 Upgrade (thay đổi values hoặc chart)
helm upgrade myapp ./charts/myapp \
--namespace production \
--values values-prod.yaml
# ⏪ Rollback về revision trước
helm rollback myapp 1 --namespace production
# 📜 Xem history
helm history myapp --namespace production⏰ HELM = TIME MACHINE CHO APPS
text
Revision 1: v1.0.0 (deployed 3 days ago)
Revision 2: v1.1.0 (deployed 2 days ago) ← Bug!
Revision 3: v1.0.0 (rollback, deployed now) ✅
helm rollback myapp 1 → Quay về Revision 1 trong 5 giâyDebug & Dry-run
bash
# 🔍 Xem YAML sẽ được generate (không apply)
helm template myapp ./charts/myapp \
--values values-prod.yaml
# 🧪 Dry-run với cluster validation
helm install myapp ./charts/myapp \
--dry-run --debug \
--values values-prod.yaml
# ✅ Validate chart syntax
helm lint ./charts/myappManaging Releases
bash
# Liệt kê releases
helm list --all-namespaces
# Xem values đang được sử dụng
helm get values myapp --namespace production
# Xóa release
helm uninstall myapp --namespace production🏁 Quick Start: helm create
⚠️ LỜI KHUYÊN TỪ PRODUCTION
"Đừng viết chart từ đầu. Dùng helm create rồi dọn dẹp."
bash
# Tạo chart scaffold
helm create myapp
# Kết quả:
myapp/
├── Chart.yaml
├── values.yaml
├── charts/ # Dependencies
├── templates/
│ ├── NOTES.txt # Post-install message
│ ├── _helpers.tpl # Template helpers
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ └── serviceaccount.yaml
└── .helmignoreQuy trình làm việc
📊 Tổng Kết
| Component | Vai trò | Ai quản lý? |
|---|---|---|
Chart.yaml | Metadata (name, version) | DevOps Engineer |
values.yaml | Default config | DevOps Engineer |
values-{env}.yaml | Environment overrides | Dev Team / DevOps |
templates/ | YAML templates | DevOps Engineer |
Essential Commands Cheatsheet
| Command | Mục đích |
|---|---|
helm create <name> | Tạo chart skeleton |
helm install <release> <chart> | Deploy chart lần đầu |
helm upgrade <release> <chart> | Cập nhật deployment |
helm rollback <release> <rev> | Quay về revision cũ |
helm template <chart> | Preview YAML output |
helm lint <chart> | Validate chart |
helm list -A | Liệt kê tất cả releases |
⚠️ QUY TẮC VÀNG TẠI HPN
- Values là thứ duy nhất Devs cần sửa - Templates là "black box" do Platform team quản lý
- Không bao giờ hardcode - Mọi thứ có thể thay đổi cần đưa vào values
- Luôn dùng
helm difftrước khi upgrade (plugin:helm-diff) - Version control cả Chart - Chart cũng là code, cần review như code
🔗 Liên kết
- Trước đó: Module 11: Prometheus & Grafana
- Tiếp theo: Module 13: GitOps & ArgoCD