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 myappHelm 4 เทียบกับ Helm 3 — เปลี่ยนอะไรจริง ๆ
หัวข้อที่มีชื่อว่า “Helm 4 เทียบกับ Helm 3 — เปลี่ยนอะไรจริง ๆ”คอร์สนี้เขียนอิง Helm 4.3.0 GitHub release ของ v4.0.0 เองระบุ scope ชัดเจนว่า “Helm v4 is a major version with backward incompatible changes including to the flags and output of the Helm CLI and to the SDK” แต่บอกเพิ่มว่า “the changes are not as extensive as those from Helm v2 to v3, with the goal that the majority of workflows remain compatible between Helm v3 and v4” chart apiVersion v2 ที่มีอยู่เดิม — ส่วนใหญ่ที่ใช้กันจริง — “will continue to be supported in Helm v4” ไม่ต้องเขียนใหม่ release notes ยังพูดถึง plugin system ที่ออกแบบใหม่ (รองรับ WebAssembly-based plugin), post-renderer ที่ทำเป็น plugin, server-side apply แบบ first-class, การเฝ้าดู resource-readiness ด้วย kstatus, และ local content-based chart caching
ความต่างของ CLI สองจุดที่ course หรือ AI assistant ที่ train มาจาก Helm 3 เป็นหลักจะผิดแน่ ๆ พิสูจน์ตรง ๆ กับ binary v4.3.0 ที่ติดตั้งจริง
$ helm install --help | grep -A1 "server-side" --server-side object updates run in the server instead of the client (default true)
$ helm upgrade --help | grep -A1 "take-ownership" --take-ownership if set, upgrade will ignore the check for helm annotations and take ownership of the existing resourcesserver-side apply เป็น default ใน Helm 4 (--server-side ของ helm install default เป็น true; helm upgrade รับค่าแบบ tri-state --server-side auto|true|false) — กลไกเดียวกันเป๊ะกับ Server-Side Apply ที่คอร์สนี้พูดถึงไปแล้วสำหรับ kubectl apply --server-side มี managedFields/field-manager แบบเดียวกัน และมี --force-conflicts เป็นทางออกแบบเดียวกัน (flag ของ Helm ก็สะกดว่า --force-conflicts เหมือนกัน) --take-ownership เป็นของใหม่ใน Helm 4 ให้ helm install/helm upgrade adopt resource ที่มีอยู่แล้วใน cluster โดยไม่ต้องมี annotation meta.helm.sh/release-name ที่ Helm ปกติต้องมีก่อนถึงจะแตะ object นั้นได้ — มีประโยชน์ตอน import manifest ที่ apply มือไว้เข้ามาเป็น Release แต่อันตรายถ้าชี้ไปผิด object
การเปลี่ยนแปลงจุดที่สามคือของจริงที่ทำให้ pipeline เดิมพังได้ พิสูจน์ด้วยการรันคำสั่งตรง ๆ
$ helm upgrade --help | grep -A1 -- "--atomic"Error: unknown flag: --atomicFlag --atomic has been deprecated, use --rollback-on-failure instead--atomic ยัง parse ได้ (ยอมรับพร้อม deprecation warning) แต่ตัวแทนของมันคือ --rollback-on-failure เป็น flag ที่ Helm 4 เอกสารบอกให้ใช้ต่อไป — AI assistant ที่ train มาจาก Helm 3 แล้วไปหยิบ --atomic มาใช้ใน pipeline code ใหม่ไม่ได้ผิด แค่ตามหลัง
helm template เทียบ helm install —dry-run=server: diff จริง พิสูจน์ได้
หัวข้อที่มีชื่อว่า “helm template เทียบ helm install —dry-run=server: diff จริง พิสูจน์ได้”helm template ไม่เคยคุยกับ cluster เลย — เป็นแค่ client-side Go-template render ล้วน ๆ helm install --dry-run=server render manifest ชุดเดียวกันแต่ส่งไปที่ API server จริงด้วย dry-run=server ดังนั้น schema validation, admission plugin, และ defaulting ทำงานจริงหมด เหมือนกับ kubectl apply --dry-run=server ที่อื่นในคอร์สนี้ รันติดกันกับ Chart และ values ชุดเดียวกันเป๊ะ
$ helm template orders ./orders-api---apiVersion: v1kind: Service...---# Source: orders-api/templates/deployment.yamlapiVersion: apps/v1kind: Deployment...---# Source: orders-api/templates/tests/test-connection.yamlapiVersion: v1kind: Podmetadata: name: "orders-orders-api-test-connection" annotations: "helm.sh/hook": test...
$ helm install orders ./orders-api --dry-run=serverNAME: ordersLAST DEPLOYED: Sat Sep 26 18:15:10 2026NAMESPACE: defaultSTATUS: pending-installREVISION: 1DESCRIPTION: Dry run completeHOOKS:---# Source: orders-api/templates/tests/test-connection.yamlapiVersion: v1kind: Podmetadata: name: "orders-orders-api-test-connection" annotations: "helm.sh/hook": test...
MANIFEST:---# Source: orders-api/templates/service.yaml...---# Source: orders-api/templates/deployment.yaml...helm template เท manifest ที่ render แล้วทุกอันออกมาเป็น stream แบนเดียว — รวม Pod ที่มี helm.sh/hook: test ด้วย — โดยไม่มีแนวคิดเรื่อง Release state เลย helm install --dry-run=server แยก HOOKS ออกจาก MANIFEST (hook ไม่ใช่ส่วนหนึ่งของ manifest ของ Release ที่ track ไว้ มันรันเฉพาะตอนสั่งผ่าน helm test เท่านั้น) และรายงาน metadata NAME/STATUS/REVISION ตรงกับที่ install จริงจะได้ เพราะมัน round-trip ผ่าน API server จริง ๆ ไม่ใช่แค่เติมค่าลง template
Values precedence พิสูจน์ด้วย chart จริง
หัวข้อที่มีชื่อว่า “Values precedence พิสูจน์ด้วย chart จริง”Helm merge values จากลำดับความสำคัญต่ำไปสูง คือ values.yaml ของ chart เอง แล้วตามด้วยไฟล์ -f/--values ตามลำดับที่ระบุ (ไฟล์หลังชนะถ้า key ซ้ำกัน) แล้ว --set/--set-string/--set-file มาทีหลังสุด พิสูจน์ด้วย chart ที่ values.yaml ตั้ง replicaCount: 2 กับ image.tag: 1.27-alpine, override file ตั้ง replicaCount: 3 กับ image.tag: "1.27", และ --set flag override tag อีกที
$ cat values-prod.yamlreplicaCount: 3image: tag: "1.27"
$ helm upgrade --install orders ./orders-api -f values-prod.yaml --set image.tag=1.27-alpine --rollback-on-failure --waitRelease "orders" has been upgraded. Happy Helming!NAME: orders...REVISION: 6
$ helm get values ordersUSER-SUPPLIED VALUES:image: tag: 1.27-alpinereplicaCount: 3
$ helm get values orders -aCOMPUTED VALUES:image: repository: nginx tag: 1.27-alpinereplicaCount: 3resources: requests: cpu: 100m memory: 64MireplicaCount จบที่ 3 (ไฟล์ -f ชนะ default ของ chart ที่ 2 และไม่มี --set ไปแตะมันเลย) ส่วน image.tag จบที่ 1.27-alpine (--set flag ชนะไฟล์ -f ที่เป็น "1.27" ซึ่งชนะ default ของ chart ไปแล้ว) — ตรงกับลำดับที่ document ไว้เป๊ะ คือ values.yaml → -f (ตามลำดับ) → --set ไม่ใช่การเดา
helm rollback กับประวัติ revision จริงที่ยุ่งเหยิง
หัวข้อที่มีชื่อว่า “helm rollback กับประวัติ revision จริงที่ยุ่งเหยิง”helm upgrade --install --rollback-on-failure --wait (ชื่อใหม่ของ --atomic ใน Helm 4) rollback upgrade ที่ล้มเหลวให้อัตโนมัติ — พิสูจน์ตรงนี้ด้วย upgrade ที่ล้มเหลวจริงสองครั้งติดกันบน Release เดียวกันเป๊ะ (ครั้งแรกเพราะ worker node ยังไม่ Ready ครั้งที่สองเพราะ image tag ที่ไม่มีอยู่จริงทำให้ ImagePullBackOff)
$ helm history ordersREVISION UPDATED STATUS CHART APP VERSION DESCRIPTION1 Sat Sep 26 18:15:18 2026 superseded orders-api-0.1.0 1.0.0 Install complete2 Sat Sep 26 18:15:25 2026 failed orders-api-0.1.0 1.0.0 Upgrade "orders" failed: resource Deployment/default/orders-orders-api not ready...3 Sat Sep 26 18:16:55 2026 superseded orders-api-0.1.0 1.0.0 Rollback to 14 Sat Sep 26 18:17:08 2026 failed orders-api-0.1.0 1.0.0 Upgrade "orders" failed: resource Deployment/default/orders-orders-api not ready...5 Sat Sep 26 18:20:08 2026 superseded orders-api-0.1.0 1.0.0 Rollback to 36 Sat Sep 26 18:20:28 2026 deployed orders-api-0.1.0 1.0.0 Upgrade completeupgrade ที่ล้มเหลวทุกครั้ง (revision 2 กับ 4) สร้าง rollback revision ของตัวเองอัตโนมัติ (3 กับ 5) โดยไม่ต้องมี operator เข้าไปแตะเลย — --rollback-on-failure ปกป้อง Release จากการถูกปล่อยค้างครึ่ง ๆ กลาง ๆ ได้จริง แต่ไม่ใช่ตัวแทนของการแก้ต้นเหตุ upgrade ที่ image tag พิมพ์ผิดจนไม่มีอยู่จริงจะวนซ้ำ fail-then-rollback แบบนี้ไปเรื่อย ๆ ถ้า CI pipeline retry มันแบบไม่คิดอะไร เพราะ rollback คืนสถานะ เดิมที่ทำงานได้ ไม่ใช่สถานะ ใหม่ที่ตั้งใจไว้ การรัน helm rollback orders <revision> ด้วยมือก็ทำแบบเดียวกันได้ตามต้องการ โดยไม่ต้องรอความล้มเหลวมา trigger
helm lint กับ helm test
หัวข้อที่มีชื่อว่า “helm lint กับ helm test”helm lint เช็คโครงสร้างและ template ของ chart แบบ static ก่อนที่จะ render อะไรเข้า cluster เลย
$ helm lint ./orders-api==> Linting orders-api[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failedchart ยังใส่ Pod ที่มี helm.sh/hook: test ของตัวเองใต้ templates/tests/ ได้ด้วย — helm test รันมันกับ Release ที่ติดตั้งอยู่แล้วและรายงานผ่าน/ไม่ผ่าน ซึ่งเป็น smoke test ของ Service จริงที่รันอยู่ ไม่ใช่แค่ lint template source
$ helm test ordersNAME: orders...TEST SUITE: orders-orders-api-test-connectionLast Started: Sat Sep 26 18:23:09 2026Last Completed: Sat Sep 26 18:23:16 2026Phase: Succeededhelm diff: เห็นการเปลี่ยนแปลงก่อนจะทำจริง
หัวข้อที่มีชื่อว่า “helm diff: เห็นการเปลี่ยนแปลงก่อนจะทำจริง”helm upgrade เองก็แสดงว่าจะเกิดอะไรขึ้นผ่าน --dry-run ได้อยู่แล้ว แต่ plugin ของ community ชื่อ helm-diff render unified diff ที่ถูกต้องเทียบกับ Release ที่รันอยู่จริง มันไม่ได้ bundle มาให้ — การติดตั้งใน Helm 4 เจอ step ตรวจ signature ใหม่ของ plugin system ตรง ๆ เลย
$ helm plugin install https://github.com/databus23/helm-diffError: plugin source does not support verification. Use --verify=false to skip verification
$ helm plugin install https://github.com/databus23/helm-diff --verify=falseWARNING: Skipping plugin signature verificationDownloading https://github.com/databus23/helm-diff/releases/download/v3.15.15/helm-diff-macos-arm64.tgzInstalled plugin: diff
$ helm diff upgrade orders ./orders-api -f values-prod.yaml --set image.tag=1.27-alpine --set replicaCount=4default, orders-orders-api, Deployment (apps) has changed: spec:- replicas: 3+ replicas: 4 ...Helm 4 ตรวจ signature ของ plugin เป็น default และปฏิเสธ source ที่ไม่ได้ sign ไปเลย ไม่ได้เชื่อแบบเงียบ ๆ — --verify=false คือ opt-out ที่ต้องระบุตรง ๆ และ audit ได้ ไม่ใช่ default ที่หลุดเข้าไปเอง
OCI registry: Chart ในฐานะ OCI artifact
หัวข้อที่มีชื่อว่า “OCI registry: Chart ในฐานะ OCI artifact”Helm สมัยใหม่กระจาย chart แบบเดียวกับที่กระจาย container image — เป็น OCI artifact ที่ระบุด้วย oci:// แทนที่ chart-repository index แบบเดิม พิสูจน์ end-to-end กับ registry ในเครื่องแบบใช้แล้วทิ้ง
$ helm package ./orders-api -d .Successfully packaged chart and saved it to: orders-api-0.1.0.tgz
$ helm push orders-api-0.1.0.tgz oci://localhost:5050/charts --plain-httpPushed: localhost:5050/charts/orders-api:0.1.0Digest: sha256:23c5fd204fbcc25d18e0111a2b1846d6335a2657e98c7644635fb3213b1a95cb
$ helm pull oci://localhost:5050/charts/orders-api --version 0.1.0 -d ./pulled --plain-httpPulled: localhost:5050/charts/orders-api:0.1.0Digest: sha256:23c5fd204fbcc25d18e0111a2b1846d6335a2657e98c7644635fb3213b1a95cb
$ helm show chart oci://localhost:5050/charts/orders-api --version 0.1.0 --plain-httpapiVersion: v2appVersion: 1.0.0name: orders-apiversion: 0.1.0--plain-http ต้องใส่ตรงนี้เพราะ registry demo ไม่มี TLS certificate — registry จริง (ghcr.io, ECR, Artifact Registry, Harbor ส่วนตัว) ระบุแบบเดียวกันผ่าน HTTPS โดยไม่ต้องมี flag เพิ่ม และ helm install/helm upgrade รับ oci:// reference ได้เหมือนกับ repo/chart แบบเดิมเป๊ะ
Chart เล็ก ๆ หนึ่งอัน, library chart หนึ่งอัน, และทำไม template เองถึงเป็น excerpt
หัวข้อที่มีชื่อว่า “Chart เล็ก ๆ หนึ่งอัน, library chart หนึ่งอัน, และทำไม template เองถึงเป็น excerpt”Chart ที่พิสูจน์ตลอดบทนี้จริง ๆ แล้วคือสอง chart คือ orders-api (application chart) ที่ประกาศ dependencies: ไปยัง chart ตัวที่สองชื่อ common ที่ Chart.yaml ตั้ง type: library library chart ไม่มี template ที่ติดตั้งได้ของตัวเองเลย — มีแต่ helper ที่ define ไว้ให้ chart อื่น include ไปใช้
# charts/common/templates/_helpers.tpl — excerpt, not a standalone manifest{{- define "common.fullname" -}}{{ .Release.Name }}-{{ .Chart.Name }}{{- end -}}
{{- define "common.labels" -}}app.kubernetes.io/name: {{ .Chart.Name }}app.kubernetes.io/instance: {{ .Release.Name }}{{- end -}}templates/deployment.yaml ของ orders-api เรียก {{ include "common.fullname" . }} กับ {{- include "common.labels" . | nindent 4 }} — ไฟล์ helper .tpl ทุกไฟล์ และ chart template ทุกไฟล์ที่มี {{ }} Go-template syntax คือ excerpt ที่ตั้งใจไว้ในบทนี้ ไม่ใช่ manifest ที่สมบูรณ์ในตัวเอง — harness ของคอร์สนี้ที่ตรวจ fence # k8s/... กับ API server จริงข้าม fence พวกนี้ไปโดยตั้งใจ เพราะ {{ .Release.Name }} ไม่ใช่ YAML ที่ถูกต้องจนกว่า Helm จะ render มันก่อน หลักฐานว่า template ถูกต้องคือ output จริงของ helm template/helm install --dry-run=server ด้านบน ไม่ใช่การ apply template source ตรง ๆ
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"]
Mental Model
หัวข้อที่มีชื่อว่า “Mental Model”Helm คือ template renderer บวก revision tracker ไม่มีอะไรลึกลับไปกว่านั้น values.yaml (กับ override ของมัน) เป็น input เดียวที่เปลี่ยน templates/ คือ Go-template source ที่ตายตัว และทุก helm install/upgrade/rollback จริง ๆ คือ “render แล้วปล่อยให้ API server reconcile ผลลัพธ์” พิสูจน์แล้วด้านบนด้วย helm install --dry-run=server ที่ round-trip ผ่าน API จริง ๆ Helm 4 เปลี่ยน ความรอบคอบ ของการ reconcile นั้น (server-side apply เป็น default, plugin system ที่ตรวจ signature, --rollback-on-failure แทน --atomic) แต่ไม่ได้เปลี่ยน model พื้นฐาน — ประวัติ revision ของ Release คือ kubectl rollout history ที่ scope ไปทุกอย่างที่ Chart จัดการเป๊ะ ไม่ใช่แนวคิดแยกต่างหาก
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ทางเลือก | ข้อดี | ต้นทุน |
|---|---|---|
helm template | เร็ว ไม่ต้องมี cluster ปลอดภัยที่จะรันที่ไหนก็ได้ | ไม่เคยจับ rejection จริงจาก API server ได้เลย — พิสูจน์แล้วด้านบน มีแค่ --dry-run=server เท่านั้นที่ทำได้ |
helm install/upgrade --dry-run=server | พิสูจน์แล้วด้านบน: schema validation จริง และ preview NAME/STATUS/REVISION จริง | ต้องมี cluster access จริง ช้ากว่า render ด้วย template ล้วน ๆ |
--rollback-on-failure (ชื่อใหม่ของ --atomic ใน Helm 4) | พิสูจน์แล้วด้านบน: undo upgrade ที่ล้มเหลวอัตโนมัติ ไม่มี Release ค้างครึ่ง ๆ | พิสูจน์แล้วด้านบน: image tag ผิดวนซ้ำ fail→rollback ไปเรื่อย ๆ ถ้า retry แบบไม่คิด — มันปกป้อง state ไม่ได้ diagnose ต้นเหตุ |
plugin helm-diff | พิสูจน์แล้วด้านบน: unified diff จริงเทียบกับ Release ที่รันอยู่ ก่อนจะ upgrade | เป็นของ third-party ไม่ sign เป็น default — พิสูจน์แล้วด้านบน Helm 4 ต้องระบุ --verify=false ตรง ๆ ถึงจะติดตั้งได้ |
Library chart (type: library) สำหรับ helper ที่แชร์กัน | _helpers.tpl ไฟล์เดียว ใช้ซ้ำได้ทุก chart ที่พึ่งพา ไม่ต้อง copy-paste | ติดตั้งเองไม่ได้ — มีอยู่แค่ในฐานะ dependency และ template ของตัวเอง render เองไม่ได้โดยตั้งใจ |
OCI (oci://) chart registry | พิสูจน์แล้วด้านบน: ใช้ infrastructure ของ registry เดียวกับ container image ไม่ต้อง host chart-repo index แยก | ต้องมี --plain-http หรือ TLS cert จริง — OCI registry ที่ไม่มีทั้งคู่ปฏิเสธการเชื่อมต่อตรง ๆ |
ความเข้าใจผิดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ความเข้าใจผิดที่พบบ่อย”- “helm template กับ helm install —dry-run=server พิสูจน์เรื่องเดียวกัน” พิสูจน์แล้วด้านบน:
helm templateไม่เคยติดต่อ cluster เลย มีแค่--dry-run=serverเท่านั้นที่ส่ง render ไปที่ API server จริงและได้ schema validation กับ admission behavior จริงกลับมา - “—atomic ยังคือ flag ที่ควรใช้ใน Helm 4” พิสูจน์แล้วด้านบนกับ CLI จริง:
--atomicยัง parse ได้พร้อม deprecation warning แต่ flag ที่ Helm 4 document ไว้คือ--rollback-on-failure - “ค่าจากไฟล์ -f ชนะ —set เสมอ เพราะไฟล์ระบุชัดเจนกว่า” พิสูจน์แล้วด้านบน:
--setคือ source ที่ precedence สูงสุด apply หลังไฟล์-fทุกไฟล์ ไม่ใช่ก่อน - “library chart ก็แค่ chart ธรรมดาที่ไม่มีค่า default” พิสูจน์แล้วด้านบน:
type: libraryในChart.yamlหมายความว่า chart นั้นไม่มี template ที่ติดตั้งได้ของตัวเองเลย — มีแต่ helper ที่defineไว้ ไม่เคย apply เข้า cluster โดยตรง - “helm lint น่าจะจับ ImagePullBackOff จาก image tag ผิดได้”
helm lintเช็คแค่โครงสร้าง chart กับ syntax ของ template แบบ static — พิสูจน์แล้วด้านบน มันไม่เคยติดต่อ registry หรือ cluster เลย ดังนั้น image tag ที่ไม่มีอยู่จริง lint ผ่านสบาย ๆ แล้วไปพังตอนhelm upgrade --waitจริงเท่านั้น
อ่านโค้ดที่ AI เขียน
หัวข้อที่มีชื่อว่า “อ่านโค้ดที่ AI เขียน”ตอน review Helm chart, ขั้นตอน CI pipeline, หรือ upgrade script ที่ AI สร้าง ให้เช็ค
helm install/helm upgradeที่ไม่มี--rollback-on-failure(หรือ--atomicรุ่นเก่า) ใน CI pipeline — พิสูจน์แล้วด้านบน upgrade ที่ล้มเหลวโดยไม่มี flag ไหนเลยจะปล่อย Release ค้างที่ statefailedและ Pod เก่าอาจถูกรื้อไปแล้ว โดยไม่มีอะไร rollback ให้อัตโนมัติ--atomicที่ใช้ใน pipeline code ใหม่ของ Helm 4 — พิสูจน์แล้วด้านบน มันยังทำงานได้แต่ deprecated แล้ว--rollback-on-failureคือ flag ปัจจุบัน- chart template (ไฟล์
.tplหรือไฟล์ไหนใต้templates/ที่มี{{ }}) ที่ถูก apply ตรง ๆ ด้วยkubectl apply -fแทนที่จะ render ก่อน — Go-template syntax ไม่ใช่ YAML ที่ถูกต้อง พิสูจน์แล้วด้านบนด้วย harness ของคอร์สนี้ที่ข้าม fence แบบนี้ไปโดยตั้งใจ helm plugin installจาก URL พร้อม--verify=falseที่ใช้เป็นนิสัย default แทนที่จะเป็นข้อยกเว้นที่ตั้งใจและ review แล้ว — พิสูจน์แล้วด้านบน default ของ Helm 4 คือต้องมี signature ที่ verify ได้- chart ที่ไม่มี Pod
helm.sh/hook: testและไม่มี stephelm testใน deploy pipeline — ความต่างระหว่าง “chart render ผ่าน” กับ “Service ที่รันอยู่ตอบ request ได้จริง” คือสิ่งที่helm testพิสูจน์ และการ review แค่ template ไม่มีทางรู้ helm upgradeที่ pipe ตรงจาก CI โดยไม่มี stephelm diff(หรืออย่างน้อย--dry-run) นำหน้า — พิสูจน์แล้วด้านบนhelm diffแสดงการเปลี่ยนแปลงจริงของ live Release ก่อนที่จะเกิดขึ้น จับreplicas/image ที่ลดลงโดยไม่ตั้งใจได้ก่อนที่จะไปถึง production
🐛 หา bug ในโค้ดนี้
#!/usr/bin/env bashset -euo pipefail
helm upgrade --install orders ./orders-api \-f values-prod.yaml \--set image.tag="${IMAGE_TAG}" \--wait --timeout 5mเฉลย
upgrade นี้ไม่มี --rollback-on-failure (ชื่อปัจจุบันของ Helm 4; --atomic ยังทำงานได้แต่ deprecated แล้ว) พิสูจน์แล้วด้านบนด้วยประวัติ Release ของคอร์สนี้เอง: upgrade ที่ล้มเหลวจริงสองครั้งต่างก็ต้องการ rollback อัตโนมัติเพื่อไม่ให้ Deployment ค้างครึ่งอัปเดต — ถ้าไม่มี flag ไหนเลย --wait ที่ล้มเหลว (IMAGE_TAG ผิด, probe ที่ไม่มีวัน healthy) จะปล่อย Release ไว้ที่ STATUS: failed พร้อม rollout ครึ่ง ๆ ที่เกิดไปแล้ว และไม่มีอะไร revert ให้ วิธีแก้คือเติม --rollback-on-failure เข้าไปในคำสั่งเดียวกันนี้