ข้ามไปยังเนื้อหา

Helm และ Package Management

Helm คือ package manager ของ Kubernetes ทำหน้าที่แปลง directory ของ manifest ที่ template ไว้ให้กลายเป็น Chart ที่ parameterize และ version ได้ แล้วติดตั้งในฐานะ Release ที่ถูก track

Deployment, Service, ConfigMap YAML ไม่กี่ไฟล์ทำงานได้ดีถ้ามีแค่ environment เดียว แต่พอมีมากกว่าหนึ่ง environment ปัญหาก็เริ่ม dev, staging, prod ต้องการ replica count, resource limit, image tag และ hostname ต่างกัน ทั้งที่โครงสร้างของ manifest เหมือนกันเป๊ะ การ copy-paste YAML สามชุดแล้วแก้แต่ละชุดด้วยมือหมายความว่าทุกครั้งที่เปลี่ยนอะไรก็ต้องไปแก้สามที่ให้ตรงกัน นอกจากนี้ยังไม่มีแนวคิดว่า “manifest 12 ไฟล์นี้คือหน่วยเดียวที่ version ร่วมกัน” มาให้เลย kubectl apply มองแต่ละไฟล์แยกจากกัน ไม่มีประวัติร่วม และไม่มีวิธีง่าย ๆ ที่จะ package ทั้งชุดให้คนอื่นเอาไปติดตั้งต่อ

Helm แก้ทั้งสองปัญหานี้พร้อมกัน ด้วยการ package manifest ที่เกี่ยวข้องกันให้เป็นหน่วยเดียวเรียกว่า Chart แทนที่ค่า hardcode ด้วย template placeholder แล้ว track การติดตั้งแต่ละครั้งของ Chart นั้นในฐานะ Release ที่มีประวัติ version ของตัวเอง

Chart คือ directory ที่มีสามส่วนหลัก

mychart/
├── Chart.yaml # name, version, and other chart metadata
├── values.yaml # default configuration values
└── templates/
├── deployment.yaml
├── service.yaml
└── configmap.yaml

Chart.yaml เก็บ metadata (name, version, description) values.yaml เก็บค่า default ส่วนทุกอย่างใต้ templates/ คือ manifest ของ Kubernetes ที่เขียนด้วย Go template syntax ซึ่ง {{ .Values.xxx }} จะดึงค่าจาก values.yaml มาใส่ตอน render

# templates/deployment.yaml (excerpt)
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 }}'
values.yaml
replicaCount: 2
image:
repository: myregistry/web
tag: '1.4.0'

helm template (render อย่างเดียว ไม่ได้ติดตั้งจริง) หรือ helm install จะเติมค่าลงใน placeholder เหล่านั้นแล้วได้ Kubernetes YAML ธรรมดาออกมา Helm ไม่ได้คิดกลไก deploy ใหม่ขึ้นมาเอง แค่ generate manifest ที่ kubectl เอาไป apply ได้เหมือนเดิม

Chart เดียวกัน deploy ไปยัง dev, staging และ prod ได้ด้วยการ override values.yaml ตอนติดตั้ง จะใช้ override file แยกต่างหากหรือ flag --set ทีละค่าก็ได้

Terminal window
# Render the manifests without installing, to sanity-check the output
helm template myapp ./mychart -f values-prod.yaml
# Install into prod using a prod-specific values file
helm install myapp ./mychart -f values-prod.yaml
# Override a single value on the command line instead
helm install myapp ./mychart --set replicaCount=5
values-prod.yaml
replicaCount: 5
image:
tag: '1.4.0'

Template ของ Chart ไม่เปลี่ยนเลยไม่ว่าจะ deploy ไป environment ไหน เปลี่ยนแค่ค่าที่ป้อนเข้าไปเท่านั้น

ทุกครั้งที่ helm install จะสร้าง Release หนึ่งตัวคือ instance ที่ตั้งชื่อไว้และถูก track ของ Chart ที่รันอยู่ใน cluster Helm เก็บประวัติ revision ของแต่ละ Release ไว้ ดังนั้นการ upgrade กับ rollback จะทำงานกับทรัพยากรทั้งชุดที่ Chart จัดการ ไม่ใช่ทีละ Deployment แนวคิดเดียวกับ kubectl rollout history ของ Deployment ตัวเดียว เพียงแต่ scope กว้างขึ้นครอบคลุมทุกอย่างที่ Chart ติดตั้งไว้ด้วยกัน

Terminal window
# Upgrade an existing Release to a new chart version or new values
helm upgrade myapp ./mychart -f values-prod.yaml
# Roll an entire Release back to a previous revision
helm rollback myapp 2
# See the revision history for a Release
helm history myapp
# Remove a Release and the resources it created
helm uninstall myapp
flowchart LR
  values["values.yaml (defaults)"] --> render["helm install / helm template"]
  overrides["values-prod.yaml or --set"] --> render
  templates["templates/ (Go-templated manifests)"] --> render
  render --> manifests["Rendered Kubernetes manifests"]
  manifests --> cluster["Applied to cluster as Release myapp, revision N"]
values และ templates ของ Chart render ออกมาเป็น manifest แล้วถูก apply เข้า cluster ในฐานะ Release ที่ track ไว้
ความต่างระหว่าง Helm Chart กับ Helm Release คืออะไร
ปกติแล้ว configuration เฉพาะแต่ละ environment ถูกส่งเข้า Chart ยังไง
helm upgrade กับ helm rollback สัมพันธ์กับ kubectl rollout ของ Deployment ตัวเดียวยังไง
helm template ต่างจาก helm install ตรงไหน