Custom helm stater template

Prawit Chaivong
Zeabix
Published in
2 min readDec 18, 2023

Introduction

จากประสบการณ์ในการ design & implement microservice และตัว gitops เพื่อช่วยในการ deployment ซึ่งเป็นเรื่องที่ค่อนข้างที่จะสำคัญโดยเฉพาะ microservice ที่รันอยู่ใน Kubernetes Cluster. โดยทั่วไป technology stack ที่ใช้กันแพร่หลาย น่าจะหนีไม่พ้นตัว helm + argoCD โดยที่เราจะสร้าง helm charts ของ microservices ทั้งหลายที่เราต้องการจะ deploy แล้ว maintain ไว้ใน git repository ซึ่งถือว่าเป็น best practice ของการทำ GitOps

สิ่งที่น่าสนใจก็คือโครงสร้างของ helm chart สำหรับ microservices หลายๆตัว โดยหลักๆแล้วจะแบ่งออกมาได้สองแบบ

  1. One helm chart rules them all

บางองค์กรอาจจะใช้วิธีที่มี chart เดียวแล้วมีทุกๆ microservices อยู่ใน helm ตัวเดียวซึ่งก็มีข้อดี (และข้อเสีย) ข้อดีของมันก็คือ ง่ายตอน deploy ขั้นตอนไม่เยอะ แค่ run helm install เพียงแค่ chart เดียวก็ขึ้นทุกๆ microservices แต่ข้อเสียของมันก็มีอยู่เหมือนกัน คือ ถ้ามีจำนวน microservices เยอะๆมา แล้วมันจะทำให้ customize ค่อนข้างลำบาก ทุกอย่างนัวเนียกันไปหมด อาจจะทำให้การจัดการ หรืองาน maintain helm chart ตัวนี้มีความยุ่งยากมากขึ้น

2. One helm for one microservice

อีกวิธีนึงก็คือการทำ chart ขึ้นมา 1 chart ต่อ 1 microservice (แต่อยู่ใน git repository เดียวกัน) วิธีนี้ก็จะแก้ปัญหาของวิธีที่หนึ่งเพราะจัดการง่ายกว่า impact ในการแก้ไข helm ของ microservice ใดๆ ก็ไม่ได้กระทบตัวอื่นๆ

ในบทความนี้เราจะโฟกัสถึงการทำ GitOps ในแบบที่ 2 ซึ่งก็จะมี Challenge ตามมาในเรื่องของการสร้าง helm chart สำหรับ microservices ใหม่ๆ โดยปกติแล้วหลายๆคนอาจจะใช้ การสร้าง helm จาก template default ของที่ helm มีให้

helm create <chart-name>

แต่ปัญหาที่เราเจอก็คือว่า สิ่งที่ generate มาให้เราอาจจะไม่ใช่สิ่งที่เราต้องการ หรือว่าอาจจะทำให้เราต้องเข้าไปทำการ customize เยอะ ซึ่งอาจจะเกิดปัญหาเหล่านี้ขึ้นมา

  • ความ inconsistency ระหว่าง helm chart แต่ละ chart โดยเฉพาะถ้าทำงานกันเป็นทีม ซึ่งแต่ละคนก็มี style ในการเขียนไม่เหมือนกัน ซึ่งจะทำให้เรา maintain ลำบากมากขึ้น
  • เปลือง effort ในการ customize

Solution

สิ่งที่จะช่วยนำมาแก้ปัญหานี้ คือการทำ custom starter template ซึ่งวิธีการมันง่ายมาก

  • สร้าง helm template ขึ้นมาตัวนึง แล้วทำการเปลี่ยน ชื่อของ chart ให้เป็น <CHARTNAME> ให้หมด
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "microservice-name.fullname" . }}
labels:
{{- include "microservice-name.labels" . | nindent 4 }}
spec:
...

จากตัวอย่างด้านบนเราจะเปลี่ยนชื่อของ chart (ในตัวอย่างนี้คือ microservice-name ให้ไปเป็น <CHARTNAME> เหมือนดังตัวอย่างข้างล่าง

apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "<CHARTNAME>.fullname" . }}
labels:
{{- include "<CHARTNAME>.labels" . | nindent 4 }}
spec:
...
  • Chart ที่เป็น template ตัวนี้ อาจจะต้องนำไปอยู่ใน location ที่ค่อนข้าง specific นิดนึง (จริงๆอยากจะ request ให้ helm รองรับให้มัน flexible มากกว่านี้แต่ว่าตอนนี้ก็ใช้แบบนี้ไปก่อน

<TEMPLATE-LOCATION>/helm/template/gitops-starter

โดยที่ <TEMPLATE-LOCATION> จะเป็น path ไหนก็ได้ แต่เดี๋ยวเราต้องเอาค่านี้ไปใช้อีกที, ส่วน gitops-starter เป็นชื่อของ chart starter template ที่เราสร้างขึ้นมาใน step ก่อนหน้านี้ (ซึ่งจะเป็นชื่ออะไรก็ได้)

  • การสร้าง helm จาก custom starter template สามารถทำได้ง่ายๆโดยการใช้ command
XDG_DATA_HOME=<TEMPLATE-LOCATION> helm create new-microservice -p gitops-starter

ซึ่งตอนการ run command helm create นั้น เราต้องระบุ environment variable ชื่อว่า XDG_DATA_HOME ซึ่งเราจะระบุให้เป็น location ของ <TEMPLATE-LOCATION> ที่เราสร้างไว้

new-microservice คือ ชื่อ chart ใหม่ที่เราต้องการสร้าง ซึ่งเราจะระบุเป็นชื่อ chart ที่เราต้องการ

gitops-starter คือชื่อ chart template ที่เราได้สร้างไว้

แค่นี้เราก็ได้ helm chart ที่เราได้ทำ customize template เอาไว้แล้ว โดยที่เราไม่ต้องไปเสียแรงในการสร้าง default helm chart แล้วค่อยมาไล่นั่งแก้ หรือ custom มันให้เป็นไปตามความต้องการของเรา ซึ่งจะช่วยลด effort ได้มาก นอกจากนั้นแล้วยังช่วยลดในเรื่องของความผิดพลาด (human error) เช่นอาจจะลืมแก้ไขในบางส่วน หรือว่าความ inconsitency ที่เกิดขึ้นใน แต่ละ chart ซึ่งอาจจะเกิดขึ้นเพราะ style ในการเขียน chart ที่ต่างกัน

--

--