เรียน Helm essential course — day1
“เรามาเรียนรู้ Helm เข้ามาช่วยให้การ deploy service ลง Kubernetes ให้ง่ายขึ้นอย่างไร”
…เกริ่นนำ: ผมได้มีโอกาสลงคอร์สเรียน Helm essential ของทางพี่โจโจ้ Jumpbox และในบทความนี้ผมจะมาแชร์สิ่งได้เรียนรู้ใน day1 … เริ่มกันเลยย
ถ้าเราอยากจะ deploy application ลงบน Kubernetes (k8s) แน่นอนว่า เราจะต้องรู้ basic component, มี 5 ตัวดังนี้
(**ทบทวน k8s overview กันซะหน่อย**)
1.Pod: หน่วยที่เล็กสุดของ k8s, เป็นที่เก็บ container ของ application
2.Replicaset: เป็นตัวควบคุมดูแล pod ในด้านต่างๆ เช่น ถ้า pod ตายให้ restart หรือ ให้ scale จำนวน pod
3.Deployment: เป็นตัวกำหนด strategy ของการ deployment process
4.Service: เป็นตัวกำหนด traffic ไปยัง pod (aka virtual Load balancer — มีหน้าที่ guild traffic)
5.Ingress: เป็น physical load balancer (VM) ที่จะ mapping DNS ไปยัง service
*ขอจัดกลุ่ม Deployment, Replicaset และ pod ไว้ในกลุ่มเดียวกัน เพราะทั้ง 3 ตัวมีการทำงานที่สอดคล้องและสัมพันธ์กัน
อะเครเมื่อเรามีไฟล์ config k8s (manifest) เรียบร้อยแล้ว next step คือเราต้อง apply ลง k8s cluster ….
World without Helm
ในการ apply นั่นก็ทำได้หลายท่า หลายสไตล์
เริ่มกันที่ท่าแรก “แบ่ง manifest เป็นไฟล์ย่อยๆ ตามชนิดของ k8s component (kind)” ซึ่งเราก็จะได้ 3 ไฟล์ เป็นอย่างน้อย และอาจมากกว่านั้นถ้าต้องการ config เพิ่มเติม:
Base
- deployment.yml
- service.yml
- ingress.yml
Additional
- secret.yml
- configmap.yml
- pv.yml
- pvc.yml
จากนั้นก็ใช้ k8s cli apply มันเรียงไฟล์
$ kubectl apply -f deployment.yml -n="<namespace>"
$ kubectl apply -f service.yml -n="<namespace>"
$ kubectl apply -f ingress.yml -n="<namespace>"
.
...
.
$ kubectl apply -f pvc.yml -n="<namespace>"
ซึ่งจะเห็นว่าอันนี้แค่ 1 application หรือ 1 service เราต้อง apply มัน 3++ ครั้งๆ แล้วถ้าเรามีเป็น 100+ services ละ😱
ด้วยท่านี้:
🟢Pros: ไฟล์แต่ละไฟล์แยกกันอย่างชัดเจนตาม k8s componenet , อ่านง่าย, maintain ง่าย
🛑Cons: ถ้ามี service เยอะ จำนสนไฟล์ก็จะเยอะตามไปด้วย เช่นถ้าเป็น micro-service 100 ตัว ก็จะมี 300++ ไฟล์
โอเครท่าแรกเจอ pain ที่ถ้าจำนวนไฟล์เยอะมากๆ จะเป็นปัญหา -> งั้นถ้าเรารวมมาเป็นไฟล์เดียวละ (all-in-one)
ท่าที่สอง “all-in-one” ยำ config ของแต่ละ k8s component มาเป็นไฟล์เดียว
ด้วยท่านี้:
🟢Pros: ทุกอย่างอยู่ที่เดียว ไฟล์เดียวจบๆ
🛑Cons: การ maintain แต่ละ k8s component ลำบากและซับซ้อนมาก
และอีกท่า “Hybird” ก็นำท่าแรก และท่าสองมารวมกัน แต่ด้วยทั้ง 2 ท่ามี cons ที่เด่นชัดทำให้ก็ออกมาไม่เวิร์ค
Helm comes to save the world…
Helm จึงได้ถูกพัฒนามาเพื่อแก้ pain point ข้างต้น เพื่อรับจบปัญหา ด้วย concept: “Helm-value”
โดยเราจะสร้าง k8s component แยกกันเหมือนเดิม แต่จะมีอีกไฟล์เพิ่มเติมขึ้นมาก็คือไฟล์ helm-value ที่จะเก็บแค่ค่า value โดยเฉพาะ เพื่อให้ไฟล์ k8s component ดึงไปใช้ และเมื่อ apply ลง cluster ก็จะ generate เป็นไฟล์ all-in-one ให้อีกที(ทำให้เบื้องหลัง)
Helm Overview
What is Helm ?
จะว่ากันตรงๆเลย helm ก็คือตัว package manager สำหรับ k8s ซึ่งจะจัดการเกี่ยวกับการ สร้าง, แชร์ และการเรียกใช้ software ที่สมบูรณ์แล้วมาใช้งาน (อารมณ์เดียวกับ image ของ docker เลยแฮะ)
โดย Helm มี 5 components ดังนี้:
- Cli / client: เป็นส่วนของช่องทางที่ทำให้เราสามารถ interact กับ helm ได้, cli ที่เราใช้กันบ่อยๆ:
//install
helm install <name / release_name> <repository>
//upgrade
helm upgrade <name / release_name> <repository> --verison <specific_version>
*ถ้าไม่กำหนด specific_version จะเป็นการกำหนดค่าเป็น version latest
//rollback
helm rollback <name / release_name> <revision_number>
//uninstall
helm uninstall <name / release_name>
2. Chart: เป็นตัว package ของ k8s (manifest) ที่มัดรวมกันไว้แล้ว พร้อมใช้งาน 3.Release: คือชื่อที่ตั้งตอน install ของ helm chart นั้นๆ โดยตัว release จะเอาไว้เก็บ version / snapshot (revision)ไว้
4. Chart repository: เป็น storage ที่เอาไว้เก็บ helm-chart
(หลักการคล้ายๆ container / image เลย ที่ต้องเก็บอยู่ที่ container registry)
5. Metadata: ปกติ meta data คือ data ที่อธิบายความหมายของ data แต่พอเป็น helm มันคือ data ที่เก็ความหมายทั้งหมดของ helm-chart
*metadata จะถูกเก็บใน secret
Lab / Activity time !
ในการทำ lab ผมจะใช้ตัว local k8s คือตัว k3d
k3d create cluster local-k3d --agents 2 --servers 1
Task1: install Nginx via Helm
ลง nginx chart version 16.0.6
$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm repo update
$ helm install <release_>bitnami/nginx --version 16.0.6 --set service.ports.http=8080 --set service.ports.https=8443
*ของผมถ้าลงแบบ ไม่กำหนด port มันชนแฮะ เหมือน machine ผมจอง 80 ไว้จึงไปท่า ให้ nginx ออกไป 8080 แทน
*ผมใช้ release_name ชื่อ nginx
ลองเช็คว่า helm ให้ k8s component อะไรเรามาบ้าง
$ kubectl get all
โอเรา ก็ได้ deployment, replicaset, pod, service
ดูว่า nginx ด้วยการ ลอง port forward ออกมาดู
$ kubectl port-forward svc/nginx 8080:8080
$ curl localhost:8080
Task2: เรามา upgrade ตัว nginx เป็นเวอร์ชันล่าสุด
$ helm upgrade nginx bitnami/nginx
result: ตัว nginx chart จะถูก upgrade เป็น version 18.1.11
เรามาดูซิ ว่า relase เก็บ revision ยังไง
$ helm ls
$ helm history <release_name>
จะเห็นว่าตอนนี้ release name ที่ชื่อ nginx จะใช้ revision เป็น 2
และ history จะแสดงอยู่ 2 version
Task3: ต้องการ rollback version ของ nginx chart (กลับไปเป็น revision 1)
$ helm rollback <release_name> <revision_number>
result: rollback เรียบร้อย ไวมากๆ
เรามาเช็คดู k8s component, helm list และ history
$ kubectl get all
$ helm ls
$ helm history <release_name>
จะเห็นว่า k8s จะ redeploy ตัว k8s component ของ nginx chart ให้ใหม่ทั้งหมด
⚠️ แต่ แต่ แต่ เมื่อเช็ค helm list ตัว revision จะไม่กลับเป็น 1 นะ
และ history ก็จะบอกว่าตอนนี้จะใช้ revision 3 ซึ่งจะกลับไปใช้ nginx version 16.0.6
Rollback ไม่ใช่การย้อนกลับ revision แต่เป็นการสร้าง revision ใหม่ ที่มี version เปลี่ยนไป
… ก็อย่างที่รู้กันว่า release จะเก็บอยู่ที่ secret
$ kubectl get secret
Task4: clear nginx chart
$ helm uninstall <release_name>
result: uninstall nginx chart หมดเกลี้ยง (ลบทุก revision)
Conclude
ในวันแรกได้เรียนรู้ “เทคนิคการเรียน” เข้าเนื้อหาหลัก Helm ด้วย k8s overiew เมื่อเตรียมไฟล์เสร็จแล้ว ก็ตามต่อด้วยการ deploy แต่การ “deploy ด้วยการไม่มี Helm มันทำให้ชีวิตเรายาก และง่ายยังไงเมื่อมี Helm เข้ามาช่วย”
… เมื่อรู้สรรพคุณของ Helm แล้ว ก็มาเจาะว่า Helm คืออะไร มีโครงสร้าง, ส่วนประกอบอะไรบ้าง รวมไปถึงการใช้ cli เพื่อเล่นกับ feature ของ Helm ไม่ว่าจะเป็นการ install , การ upgrade, การ rollback และการ uninstall ซึ่งได้เล่นและซ้อมมือใน lab / activity ในช่วงท้าย 🙌🏻
*ปล เริ่มต้นนั้นพี่โจโจ้เทคนิคการเรียน แต่คิดว่าจะทำออกมาเป็นบทความแยก ซึ่งในบทความนี้จะเน้นเนื้อหาของ Helm ไปเลย
curiosity gap
จะยังเหลืออีก 2 หัวข้อ คือตอนที่ทำงานจริงได้ใช้ helm เข้ามาช่วยในการเขียน config ในลักษณะ helm-template (ซึ่งเอา pattern มาจากคอร์ส Kubernetes Mastery ของพี่เดีย) ซึ่งเป็นการ deploy ใช้ใน k8s cluster โดยไม่ได้ push ขึ้น chart-repository ส่วนนี้อยากรู้ประเด็นนี้ว่าเป็นท่าที่โอเครไหม เพราะตอนนี้เจอปัญหาที่ว่าใช้ท่า helm template นี้กับทั้ง 3env (prod, stg, develop) ซึ่งตอนที่ผมจะแก้ไข หรือ maintain ตัว template manifest สักตัว (deployment, service, ingress) มันจะกระทบทั้ง 3 env 🥹