Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 24 — Helm — Package Manager cho Kubernetes

Đã đọc 0/15 mục · còn khoảng 11 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn là DevOps engineer tại một công ty fintech ở TP.HCM. Hệ thống của bạn có khoảng 20 microservice: payment, auth, wallet, notification, ledger... Mỗi service khi triển khai lên Kubernetes cần một mớ file YAML: Deployment, Service, ConfigMap, Ingress, HorizontalPodAutoscaler, đôi khi thêm PersistentVolumeClaim và ServiceAccount. Trung bình mỗi service khoảng 8–10 file. Bạn lại có 3 môi trường: dev, staging, production.

Làm phép nhân nhanh: 20 service × 10 file × 3 môi trường = 600 file YAML phải quản lý bằng tay. Và đây mới là con số "đẹp". Thực tế mỗi khi đổi image tag để deploy phiên bản mới, bạn phải sửa YAML ở đúng môi trường, không được nhầm; khi dev khác production ở số replica hay biến môi trường, bạn phải copy-paste rồi sửa từng chỗ. Chỉ cần một lần copy nhầm giá trị DATABASE_URL của staging vào production là có sự cố nghiêm trọng.

Đây chính xác là vấn đề mà Helm ra đời để giải quyết. Helm là "package manager cho Kubernetes" — nói nôm na, nó với Kubernetes cũng giống như apt với Ubuntu hay npm với Node.js. Thay vì quản lý hàng trăm file YAML rời rạc, bạn đóng gói chúng thành một chart có thể tham số hóa, cài đặt bằng một câu lệnh, nâng cấp và rollback dễ dàng. Bài này sẽ giúp bạn hiểu Helm giải quyết bài toán "YAML sprawl" (YAML tràn lan) như thế nào, và cách dùng nó chuẩn mực trong công việc thực tế.

Khái niệm cốt lõi

Helm là gì và giải quyết vấn đề gì

Helm đóng gói mọi tài nguyên Kubernetes cần thiết cho một ứng dụng vào một đơn vị gọi là chart. Chart cho phép:

  • Templating (mẫu hóa): viết YAML một lần với các "ô trống", rồi điền giá trị khác nhau cho từng môi trường.
  • Release management (quản lý bản phát hành): mỗi lần bạn cài một chart, Helm tạo ra một release có tên và số phiên bản. Bạn có thể nâng cấp, xem lịch sử, và rollback về bất kỳ phiên bản cũ nào.
  • Chia sẻ và tái sử dụng: chart có thể được đóng gói, đẩy lên repository và cài lại ở nơi khác — giống như bạn npm install một package.

Cấu trúc một chart

Khi chạy helm create myapp, bạn nhận được thư mục có cấu trúc điển hình sau:

myapp/
  Chart.yaml          # Metadata: tên chart, phiên bản, mô tả
  values.yaml         # Giá trị mặc định cho các biến
  templates/          # Các file YAML dạng template
    deployment.yaml
    service.yaml
    ingress.yaml
    _helpers.tpl      # Các hàm/template dùng lại
  charts/             # Sub-charts (dependency)

Ba thành phần quan trọng nhất:

  • Chart.yaml: khai báo name, version (phiên bản của chart) và appVersion (phiên bản ứng dụng bên trong). Đây là "chứng minh thư" của chart.
  • values.yaml: nơi chứa tất cả giá trị có thể thay đổi — số replica, image tag, resource limit, biến môi trường. Đây là "bảng điều khiển" của chart.
  • templates/: các file YAML nhưng có chèn cú pháp template Go. Ví dụ:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-web
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
        - name: web
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

Ở đây {{ .Values.replicaCount }} sẽ được thay bằng giá trị replicaCount trong values.yaml, còn {{ .Release.Name }} là tên release bạn đặt khi cài. Nhờ vậy, cùng một template có thể sinh ra cấu hình khác nhau cho dev và production.

Values — trái tim của việc tham số hóa

values.yaml chứa giá trị mặc định:

replicaCount: 2
image:
  repository: registry.example.com/web
  tag: "1.4.0"
resources:
  requests:
    cpu: 100m
    memory: 128Mi

Điều tuyệt vời là bạn có thể override (ghi đè) giá trị này theo môi trường. Thay vì 3 bản copy toàn bộ YAML, bạn chỉ cần các file nhỏ values-dev.yaml, values-prod.yaml chứa đúng những thứ khác biệt:

# values-prod.yaml
replicaCount: 6
resources:
  requests:
    cpu: 500m
    memory: 512Mi

Khi cài, bạn chỉ định file này: helm install web ./myapp -f values-prod.yaml. Mọi giá trị không khai báo trong values-prod.yaml sẽ lấy mặc định từ values.yaml. Nguyên tắc DRY (Don't Repeat Yourself) được tôn trọng triệt để.

Release và Revision

Mỗi lần cài chart, Helm tạo một release. Mỗi lần bạn upgrade, số revision tăng lên (1, 2, 3...). Helm lưu lịch sử này (mặc định trong Kubernetes Secret) nên bạn luôn có thể xem helm history và helm rollback về phiên bản trước chỉ trong vài giây. Đây là điểm khác biệt lớn so với kubectl apply thuần túy — vốn không có khái niệm "bản phát hành" hay "quay lui".

Helm Repository và chart công khai

Ngoài việc tự viết chart, bạn có thể dùng chart do cộng đồng/nhà cung cấp làm sẵn. Ví dụ, thay vì tự viết mấy trăm dòng YAML cho PostgreSQL, bạn chỉ cần:

helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-db bitnami/postgresql

Đây là lý do Helm được ví như apt: có cả một "kho phần mềm" các chart chất lượng cao cho Prometheus, Grafana, ingress-nginx, Redis, Kafka...

Tình huống thực tế

Tình huống 1 — Startup fintech ở TP.HCM thoát khỏi "địa ngục YAML"

Một startup ví điện tử (gọi là "PayViet") có 18 microservice. Ban đầu team dùng kubectl apply với các file YAML thuần, tổ chức theo thư mục k8s/dev, k8s/staging, k8s/prod. Mỗi lần release, bạn Nam — DevOps duy nhất của team — phải sửa image tag trong 3 nơi. Một tối thứ Sáu, Nam vô tình deploy image tag của staging (2.3.0-rc) lên production thay vì bản đã QA (2.2.8). Kết quả: cổng thanh toán lỗi 40 phút, khoảng 1.200 giao dịch thất bại.

Sau sự cố, team chuyển sang Helm. Họ tạo một chart chung service-template dùng cho mọi microservice, và mỗi service chỉ cần một values.yaml riêng. Image tag giờ nằm ở đúng một chỗ trong values-prod.yaml, được sinh tự động từ CI theo git tag. Số file YAML phải sửa tay khi release giảm từ hàng chục xuống con số 0 (CI tự chèn tag). Quan trọng hơn, việc "nhầm môi trường" gần như không thể xảy ra vì mỗi môi trường có file values tách biệt, được review qua pull request.

Bài học: Helm không chỉ giảm số lượng file, mà còn loại bỏ cả một lớp lỗi con người nhờ tách biệt template và giá trị.

Tình huống 2 — Công ty thương mại điện tử tận dụng chart Bitnami

Một sàn TMĐT tại Hà Nội cần dựng nhanh môi trường staging gồm Redis, PostgreSQL và RabbitMQ để test tính năng flash-sale. Nếu tự viết YAML cho ba hệ này (kèm StatefulSet, Service, ConfigMap, cấu hình replication...) sẽ mất vài ngày và dễ sai. Team dùng chart Bitnami:

helm install cache bitnami/redis -f redis-staging.yaml
helm install db bitnami/postgresql -f pg-staging.yaml
helm install queue bitnami/rabbitmq -f mq-staging.yaml

Chỉ trong một buổi chiều, môi trường staging hoàn chỉnh chạy được. Khi test xong, họ gỡ sạch bằng helm uninstall cache db queue, không để lại tài nguyên rác. Chi phí cluster staging giảm vì họ dựng-hủy theo nhu cầu.

Bài học: Helm biến những thành phần hạ tầng phức tạp thành "cài một lệnh, gỡ một lệnh". Đừng phát minh lại bánh xe khi đã có chart chất lượng.

Tình huống 3 — Rollback cứu một đêm on-call

Một công ty logistics ở Singapore triển khai bản cập nhật service định tuyến đơn hàng lúc 23h qua helm upgrade. Sau 10 phút, tỷ lệ lỗi tăng vọt vì một thay đổi cấu hình timeout. Kỹ sư on-call không cần tìm lại YAML cũ hay debug vội trong đêm — chỉ gõ:

helm rollback order-router 7

Hệ thống quay về revision 7 (bản ổn định trước đó) trong khoảng 15 giây. Sáng hôm sau team mới bình tĩnh điều tra nguyên nhân.

Bài học: Khả năng rollback nguyên tử theo revision là "phao cứu sinh" cho vận hành. Đây là thứ mà quản lý YAML thủ công rất khó làm sạch sẽ.

Hướng dẫn từng bước

Ta sẽ đóng gói một web service đơn giản thành chart và triển khai qua các môi trường.

Bước 1 — Cài Helm và tạo chart khởi tạo

brew install helm        # macOS; Linux dùng script get-helm-3
helm create web

Lệnh helm create sinh sẵn một chart mẫu hoàn chỉnh trong thư mục web/. Hãy đọc qua templates/deployment.yaml để thấy cách các biến {{ .Values.* }} được dùng.

Bước 2 — Chỉnh values.yaml cho phù hợp ứng dụng

Sửa image.repository, image.tag, service.port, replicaCount cho đúng service của bạn. Đây là giá trị mặc định — coi như cấu hình cho dev.

Bước 3 — Kiểm tra template trước khi cài (rất quan trọng)

helm lint web
helm template web ./web

helm lint bắt lỗi cú pháp chart. helm template render ra YAML cuối cùng mà không cài đặt gì — bạn xem trước chính xác cái gì sẽ được gửi lên cluster. Luôn làm bước này trước khi đụng vào cluster thật.

Bước 4 — Cài đặt (install) lần đầu

helm install web ./web -n dev --create-namespace

Ở đây web là tên release, -n dev là namespace. Kiểm tra bằng helm list -n dev và kubectl get pods -n dev.

Bước 5 — Tạo file values riêng cho production

# values-prod.yaml
replicaCount: 6
image:
  tag: "1.4.0"
resources:
  requests:
    cpu: 500m
    memory: 512Mi

Cài lên production với override:

helm install web ./web -n prod --create-namespace -f values-prod.yaml

Bước 6 — Nâng cấp và xem lịch sử

Khi có phiên bản mới, đổi tag rồi:

helm upgrade web ./web -n prod -f values-prod.yaml --set image.tag=1.4.1
helm history web -n prod

--set cho phép ghi đè nhanh một giá trị ngay trên dòng lệnh — rất tiện cho CI truyền image tag vào.

Bước 7 — Rollback khi cần

helm rollback web 3 -n prod

Xong. Bạn đã có một quy trình đóng gói, triển khai đa môi trường và rollback hoàn chỉnh.

Lỗi thường gặp & mẹo

Nhồi hết logic vào template khiến chart khó đọc. Người mới thường viết những khối if/else, range lồng nhau chằng chịt trong template. Hãy tách phần lặp lại vào _helpers.tpl và giữ template càng phẳng càng tốt. Chart dễ đọc quan trọng hơn chart "thông minh".

Không phân biệt helm template với helm install. helm template chỉ render phía client, không kiểm tra với API server và không tạo release. Nó tốt để xem trước, nhưng đừng nhầm rằng render thành công là cài được. Dùng helm install --dry-run --debug khi muốn Helm kiểm tra thêm với cluster.

Để giá trị nhạy cảm trong values.yaml rồi commit lên Git. Mật khẩu, token không nên nằm trần trong values. Hãy dùng --set từ CI, hoặc kết hợp với công cụ quản lý secret (chủ đề này thuộc bài về Secret Management). Ít nhất, đừng bao giờ commit values chứa credential production.

Quên helm lint và review file render trước khi lên production. Một dấu cách sai trong YAML template có thể sinh ra manifest hỏng. Đưa helm lint và helm template vào bước CI để chặn lỗi từ sớm.

Lạm dụng --set cho quá nhiều giá trị. Nếu bạn phải truyền 15 cái --set trên dòng lệnh, đó là dấu hiệu bạn nên dùng file values. --set hợp cho 1–2 giá trị động (như image tag); phần còn lại nên nằm trong file để dễ review.

Mẹo — mỗi môi trường một file values, cùng một chart. Đây là pattern chuẩn: một chart duy nhất, nhiều values-<env>.yaml. Đừng bao giờ fork chart cho từng môi trường.

Mẹo — pin phiên bản chart khi dùng repo bên thứ ba. Khi cài chart công khai, luôn ghi rõ --version để build có tính tái lặp (reproducible), tránh việc chart tự nâng cấp ngầm và gây bất ngờ.

Bài tập thực hành

  • Tạo chart đầu tiên: Chạy helm create myapp, đọc và hiểu vai trò của Chart.yaml, values.yaml và một file trong templates/. Sửa replicaCount thành 3 và image.tag thành phiên bản bạn chọn.
  • Xem trước bằng template: Chạy helm template myapp ./myapp và tìm trong output đúng chỗ mà replicaCount và image tag của bạn xuất hiện. Xác nhận bạn hiểu biến nào ánh xạ tới đâu.
  • Đa môi trường: Tạo values-dev.yaml (replica 2) và values-prod.yaml (replica 6, resource cao hơn). Render cả hai bằng helm template myapp ./myapp -f values-prod.yaml và so sánh với bản dev. Giải thích vì sao cùng chart lại cho hai kết quả khác nhau.
  • Vòng đời release: Nếu có cluster (minikube/kind cũng được), thực hiện trọn vẹn install → upgrade --set image.tag=... → history → rollback. Ghi lại số revision ở mỗi bước.
  • Dùng chart cộng đồng: Thêm repo Bitnami, cài Redis bằng helm install, kiểm tra pod chạy, rồi helm uninstall. Quan sát Helm dọn dẹp tài nguyên gọn gàng thế nào.

Tóm tắt

Helm là package manager cho Kubernetes, sinh ra để giải quyết bài toán "YAML tràn lan" khi số service và số môi trường tăng lên. Thay vì quản lý hàng trăm file rời rạc, bạn đóng gói tài nguyên vào một chart gồm ba trụ cột: Chart.yaml (metadata), values.yaml (giá trị tham số hóa) và templates/ (YAML mẫu hóa bằng cú pháp Go). Nhờ tách biệt template khỏi giá trị, bạn dùng đúng một chart cho mọi môi trường và chỉ cần các file values-<env>.yaml nhỏ ghi đè phần khác biệt — vừa DRY, vừa loại bỏ cả một lớp lỗi "nhầm môi trường".

Điểm mạnh vận hành lớn nhất của Helm là quản lý release theo revision: mỗi lần cài/nâng cấp là một phiên bản có lịch sử, cho phép rollback nguyên tử trong vài giây — như tình huống on-call ở Singapore đã cho thấy. Cộng thêm hệ sinh thái chart công khai (Bitnami, ingress-nginx, Prometheus...), Helm giúp bạn dựng những thành phần hạ tầng phức tạp chỉ bằng một câu lệnh. Hãy nhớ các nguyên tắc chuẩn: một chart nhiều values, helm lint và helm template trước khi lên production, không commit secret vào values, và pin phiên bản khi dùng chart bên thứ ba. Nắm vững Helm, bạn đã có công cụ nền tảng để đóng gói và vận hành ứng dụng trên Kubernetes một cách chuyên nghiệp.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi