Helm และ Package Management
ไอเดียในหนึ่งประโยค
หัวข้อที่มีชื่อว่า “ไอเดียในหนึ่งประโยค”Helm คือ package manager ของ Kubernetes ทำหน้าที่แปลง directory ของ manifest ที่ template ไว้ให้กลายเป็น Chart ที่ parameterize และ version ได้ แล้วติดตั้งในฐานะ Release ที่ถูก track
ปัญหา: raw YAML ไม่ parameterize หรือ version ได้ดี
หัวข้อที่มีชื่อว่า “ปัญหา: raw YAML ไม่ parameterize หรือ version ได้ดี”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
หัวข้อที่มีชื่อว่า “โครงสร้างของ Chart”Chart คือ directory ที่มีสามส่วนหลัก
mychart/├── Chart.yaml # name, version, and other chart metadata├── values.yaml # default configuration values└── templates/ ├── deployment.yaml ├── service.yaml └── configmap.yamlChart.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/v1kind: Deploymentmetadata: name: {{ .Release.Name }}-webspec: replicas: {{ .Values.replicaCount }} template: spec: containers: - name: web image: '{{ .Values.image.repository }}:{{ .Values.image.tag }}'replicaCount: 2image: repository: myregistry/web tag: '1.4.0'helm template (render อย่างเดียว ไม่ได้ติดตั้งจริง) หรือ helm install จะเติมค่าลงใน placeholder เหล่านั้นแล้วได้ Kubernetes YAML ธรรมดาออกมา Helm ไม่ได้คิดกลไก deploy ใหม่ขึ้นมาเอง แค่ generate manifest ที่ kubectl เอาไป apply ได้เหมือนเดิม
การส่งค่า configuration เฉพาะแต่ละ environment
หัวข้อที่มีชื่อว่า “การส่งค่า configuration เฉพาะแต่ละ environment”Chart เดียวกัน deploy ไปยัง dev, staging และ prod ได้ด้วยการ override values.yaml ตอนติดตั้ง จะใช้ override file แยกต่างหากหรือ flag --set ทีละค่าก็ได้
# Render the manifests without installing, to sanity-check the outputhelm template myapp ./mychart -f values-prod.yaml
# Install into prod using a prod-specific values filehelm install myapp ./mychart -f values-prod.yaml
# Override a single value on the command line insteadhelm install myapp ./mychart --set replicaCount=5replicaCount: 5image: tag: '1.4.0'Template ของ Chart ไม่เปลี่ยนเลยไม่ว่าจะ deploy ไป environment ไหน เปลี่ยนแค่ค่าที่ป้อนเข้าไปเท่านั้น
Release กับคำสั่งจัดการ lifecycle
หัวข้อที่มีชื่อว่า “Release กับคำสั่งจัดการ lifecycle”ทุกครั้งที่ helm install จะสร้าง Release หนึ่งตัวคือ instance ที่ตั้งชื่อไว้และถูก track ของ Chart ที่รันอยู่ใน cluster Helm เก็บประวัติ revision ของแต่ละ Release ไว้ ดังนั้นการ upgrade กับ rollback จะทำงานกับทรัพยากรทั้งชุดที่ Chart จัดการ ไม่ใช่ทีละ Deployment แนวคิดเดียวกับ kubectl rollout history ของ Deployment ตัวเดียว เพียงแต่ scope กว้างขึ้นครอบคลุมทุกอย่างที่ Chart ติดตั้งไว้ด้วยกัน
# Upgrade an existing Release to a new chart version or new valueshelm upgrade myapp ./mychart -f values-prod.yaml
# Roll an entire Release back to a previous revisionhelm rollback myapp 2
# See the revision history for a Releasehelm history myapp
# Remove a Release and the resources it createdhelm uninstall myappflowchart 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"]