Meta description: Helm là package manager cho Kubernetes, giúp triển khai ứng dụng dễ hơn raw YAML. Bài viết này giải thích Helm là gì, core concepts, so sánh với Kustomize và demo lab thực tế.
Trong serie này, mình bắt đầu từ một câu hỏi rất thực tế: nếu Kubernetes đã có YAML rồi, tại sao chúng ta vẫn cần Helm?
Câu trả lời ngắn gọn là Kubernetes giỏi ở chuyện chạy workload, còn Helm giỏi ở chuyện đóng gói, tái sử dụng, nâng cấp và quản lý vòng đời của workload đó.
Bài đầu tiên này đi từ pain point khi làm việc với raw YAML, sau đó nhìn vào lab thực tế để thấy Helm giải quyết bài toán ra sao. Nếu bạn đang dựng môi trường học trên VPS, có thể xem thêm hướng dẫn thuê VPS hoặc dùng luôn Pro VPS để làm lab.
Lab dùng trong bài viết
Trong xuyên suốt serie hướng dẫn Helm này, các hướng dẫn được thực hiện trên các phiên bản sau:
- Helm
v4.1.3 - kubectl
v1.35.3 - Kind
v0.31.0 - Kubernetes cluster local
v1.35.0 - Chart demo:
bitnami/nginx
kind create cluster --name helm-lab --wait 120s
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install web-demo bitnami/nginx \
--namespace demo --create-namespace \
--set service.type=ClusterIP \
--set replicaCount=2
helm upgrade web-demo bitnami/nginx \
--namespace demo \
--set service.type=ClusterIP \
--set replicaCount=3



Vấn đề bắt đầu từ raw Kubernetes YAML
Ai làm Kubernetes một thời gian rồi cũng gặp đoạn này: ban đầu chỉ có vài file YAML nên mọi thứ còn khá dễ chịu. Nhưng khi có nhiều môi trường như dev, staging, production, hoặc nhiều ứng dụng dùng cùng một pattern, raw YAML bắt đầu lộ điểm yếu.
- YAML bị lặp lại rất nhiều
- Khó tái sử dụng giữa nhiều môi trường
- Khó theo dõi version và rollback ở cấp ứng dụng
- Dễ phát sinh copy-paste manifest rồi sửa tay
Ví dụ một ứng dụng đơn giản thường đã cần ít nhất Deployment và Service. Nếu public ra ngoài thì thêm Ingress, nếu có cấu hình thì thêm ConfigMap hoặc Secret. Chừng đó chưa đáng sợ. Cái mệt nằm ở chỗ cùng pattern đó lặp đi lặp lại.
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
namespace: demo-plain
spec:
replicas: 2
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: app
image: nginx:1.27
ports:
- containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: demo-app
namespace: demo-plain
spec:
selector:
app: demo-app
ports:
- port: 80
targetPort: 80
Nếu bạn đã quen với Docker Compose trong thực tế, cảm giác này khá giống lúc một file compose đơn giản dần phình ra thành nhiều biến thể cho từng môi trường. Kubernetes mạnh hơn nhiều, nhưng manifest cũng phức tạp hơn tương ứng.
Bản chất YAML không sai. Nó chỉ bắt đầu đuối khi bạn cần quản lý ứng dụng như một package có cấu hình, version và lifecycle rõ ràng.
Helm là gì?
Helm là package manager cho Kubernetes. Nếu từng dùng apt, dnf, brew hay composer, bạn có thể hình dung Helm cũng làm chuyện tương tự nhưng ở tầng Kubernetes.
- đóng gói manifest thành một đơn vị có thể tái sử dụng
- cho phép truyền cấu hình khi cài đặt
- quản lý version của package
- hỗ trợ upgrade, rollback, uninstall
- lấy package từ repository
Điểm cần nhớ là Helm không thay Kubernetes. Helm vẫn render ra YAML rồi gửi manifest đó cho Kubernetes API. Nói gọn lại, Kubernetes là nơi chạy workload, còn Helm là lớp quản lý gói triển khai bên trên.
Demo thực tế: từ chart có sẵn đến release đang chạy
Bước 1: thêm repository chart
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm search repo bitnami/nginx
Trong lab này, chart bitnami/nginx tại thời điểm test có version 22.6.10 và app version 1.29.7.
Bước 2: xem values của chart
helm show values bitnami/nginx | head -n 40
Chỗ này rất đáng giá. Thay vì đọc một rừng YAML rồi tự đoán nên sửa ở đâu, chart thường gom cấu hình vào values.yaml. Bạn chỉ override đúng phần cần đổi.
Bước 3: cài ứng dụng bằng Helm
helm install web-demo bitnami/nginx \
--namespace demo --create-namespace \
--set service.type=ClusterIP \
--set replicaCount=2
kubectl get all -n demo
helm list -A
Sau khi cài xong, Helm tạo một release tên web-demo trong namespace demo. Thay vì tự viết toàn bộ manifest cho NGINX, mình chỉ chọn chart và truyền cấu hình phù hợp.
Bước 4: nâng cấp release
helm upgrade web-demo bitnami/nginx \
--namespace demo \
--set service.type=ClusterIP \
--set replicaCount=3
helm history web-demo -n demo
helm get values web-demo -n demo
- revision 1: install complete
- revision 2: upgrade complete
- values đang dùng:
replicaCount: 3,service.type: ClusterIP
Đây là điểm raw YAML thường không làm gọn bằng Helm. Với Helm, bạn có lịch sử revision rõ ràng ở cấp release, không chỉ ở từng Deployment riêng lẻ.
Các khái niệm cốt lõi trong Helm
1. Chart
Chart là gói triển khai của Helm. Một chart thường có Chart.yaml, values.yaml và thư mục templates/ chứa template manifest.
helm create webapp
Khi chạy lệnh trên, Helm sinh sẵn các file như templates/deployment.yaml, templates/service.yaml, templates/ingress.yaml và vài thành phần phụ trợ khác. Nó không phải ma thuật, chỉ là một chuẩn tổ chức manifest để tái sử dụng.
2. Release
Release là một instance của chart đã được cài vào cluster. Trong lab này, chart là bitnami/nginx, còn release là web-demo.
3. Values
Values là tập biến cấu hình dùng để render template. Bạn có thể truyền bằng --set, file values riêng cho từng môi trường, hoặc ghép nhiều file values với nhau.
4. Repository
Repository là nơi lưu chart. Ví dụ helm repo add bitnami https://charts.bitnami.com/bitnami. Team nội bộ cũng có thể tự dựng repository riêng để chuẩn hóa cách deploy app trong công ty.
Helm hoạt động như thế nào phía sau?
Về bản chất, Helm làm 3 việc: đọc chart, ghép template với values để render YAML hoàn chỉnh, rồi gửi manifest đó cho Kubernetes API.
helm template webapp ./webapp --set replicaCount=3 --namespace demo-helm
Ở lab này, lệnh render ra đủ các object như ServiceAccount, Service, Deployment và test hook. Nên nếu nhìn từ góc vận hành, Helm là một lớp quản lý manifest, không phải công cụ thay thế Kubernetes.
So sánh Helm với plain YAML và Kustomize
1. Plain YAML
Ưu điểm là đơn giản, dễ hiểu, không cần thêm tool. Nhược điểm là dễ lặp file, khó tái sử dụng, khó chuẩn hóa thành package và không có lifecycle management rõ như Helm.
2. Kustomize
kubectl kustomize temp/helm-article-lab/kustomize/overlays/prod
Kustomize mạnh ở chuyện overlay và patch manifest, giữ YAML gốc khá sạch, lại tích hợp sẵn trong kubectl. Nhưng nó không phải package manager đúng nghĩa, cũng không có release history như Helm.
3. Helm
Helm mạnh ở hệ sinh thái chart, khả năng đóng gói ứng dụng, values linh hoạt và release history rõ ràng. Điểm đổi lại là bạn phải hiểu template syntax, và chart viết kém thì đọc cũng khá mệt.
- Plain YAML: tốt để hiểu gốc
- Kustomize: mạnh về overlay
- Helm: mạnh về package và lifecycle
Khi nào nên dùng Helm trong thực tế?
- Khi cài các thành phần phổ biến trong cluster như ingress controller, cert-manager, monitoring stack
- Khi ứng dụng nội bộ có nhiều môi trường với replica, image tag, hostname hoặc resource limits khác nhau
- Khi cần chuẩn hóa deploy cho nhiều dự án cùng pattern
- Khi cần rollback hoặc audit thay đổi nhanh
- Khi cần dựng lab, POC hoặc demo nhanh
Nếu bạn cần một môi trường riêng để test chart, build cluster nhỏ hoặc chạy thêm vài dịch vụ phụ trợ, Pro VPS là mức khá hợp lý để bắt đầu. Còn nếu mới tìm hiểu hạ tầng trước khi đi vào Kubernetes, bài thuê VPS từ A-Z cũng đáng đọc.
Helm có phải lúc nào cũng cần không?
Không hẳn. Nếu bạn chỉ có một hai manifest đơn giản, không cần tái sử dụng, không có nhiều môi trường và cũng không cần release history, cấu hình với YAML hoặc Kustomize là đủ.
Helm phát huy giá trị khi độ phức tạp vận hành bắt đầu tăng. Nói cách khác, Helm không sinh ra để thay mọi YAML, mà để giải quyết bài toán quản lý triển khai ở quy mô lớn hơn mức copy-paste thủ công.
Những gì bạn sẽ học trong serie Helm này
- cài đặt Helm và các lệnh CLI quan trọng
- đọc chart, hiểu
values.yamlvà override cấu hình - tự tạo chart đầu tiên với
helm create - template trong Helm: biến, điều kiện, vòng lặp, helper
- tách values cho dev, staging, production
- debug chart bằng
helm lint,helm template, dry-run - deploy một ứng dụng thực tế bằng Helm
Kết luận
Helm không tồn tại vì Kubernetes thiếu khả năng deploy. Helm tồn tại vì deploy được và quản lý triển khai tốt là hai chuyện khác nhau.
Khi mới bắt đầu, raw YAML giúp bạn hiểu Kubernetes vận hành ra sao. Nhưng khi hệ thống có nhiều môi trường, nhiều ứng dụng, nhiều lần nâng cấp và nhiều người cùng vận hành, bạn sẽ cần một lớp tổ chức tốt hơn cho manifest.
Hiểu đơn giản: Kubernetes cho bạn nơi để chạy ứng dụng, còn Helm cho bạn cách đóng gói và quản lý ứng dụng đó gọn gàng hơn.
Ở bài tiếp theo, mình sẽ đi vào phần cài đặt Helm, các lệnh CLI quan trọng và cách đọc một chart thực tế mà không bị ngợp.
Tham khảo thêm các giải pháp hạ tầng tại AZDIGI nếu bạn muốn tự dựng lab thực hành Kubernetes và Helm.
Có thể bạn cần xem thêm
- Cài đặt Helm và dựng lab Kubernetes local với kind/OrbStack (Phần 2/11)
- Cấu trúc Helm Chart: Chart.yaml, values.yaml, templates và thành phần quan trọng (Phần 3/11)
- Deploy ứng dụng từ public repository: Bitnami, Artifact Hub và best practices (Phần 5/11)
- NodeJS Full-Stack trong Helm phần 1: Kiến trúc chart cho React/Next.js + Express (Phần 7/11)
- Templates, Values, Functions và Debugging: Làm chủ Go templating trong Helm (Phần 4/11)
- Tự đóng gói ứng dụng Node.js cơ bản thành Helm chart (Phần 6/11)
Về tác giả
Trần Thắng
Chuyên gia tại AZDIGI với nhiều năm kinh nghiệm trong lĩnh vực web hosting và quản trị hệ thống.