Basic Kubernetes Part 8 - Helm - เครื่องมือที่ช่วยในการ Deploy อะไรที่ซับซ้อน Part 1

Basic Kubernetes Part 8 - Helm - เครื่องมือที่ช่วยในการ Deploy อะไรที่ซับซ้อน Part 1

ในตอนที่แล้วเราได้ลองทำโจทย์การ Deploy : WordPress ทำให้เราเห็นว่ามันมีความต้องการที่ต้องการ Deploy WordPress ที่มี Template เดียวกัน แตกต่างกันแค่ Config เช่น domain name ซึ่งในตอนที่แล้วเราใช้ envsubst ในการทำ แต่ปัญหาที่เรายังแก้ไม่ได้ก็คือ ถ้ามีการแบ่งลูกค้าเป็นหลายแบบ แต่ละแบบมี template ที่ deploy แตกต่างกันเพียงเล็กน้อยเราจะทำอย่างไร (จริงๆก็แยกเป็นหลายๆ template เลยก็ได้นะ แต่มันดูเหนื่อยเกินไปถ้ามีสัก 5 แบบ แล้วแตกต่างกันนิดเดียว) ซึ่งปัญหานี้ได้มีคนสร้างเครื่องมือเพื่อแก้ปัญหาแล้ว เครื่องมือนั้นคือ Helm ที่เรากำลังจะไปเรียนรู้นั่นเอง

Helm คืออะไร

สำหรับผม Helm คือเครื่องมือที่ใช้ในการ Deploy application ที่ซับซ้อนบน k8s โดยมี Feature ในการ Install , Update , Rollback , Uninstall ก็ได้ (นิยามจริงๆอ่านได้ที่นี่) ซึ่งจะเห็นว่าพวก Feature ที่ว่าไปนั้นตัว k8s ไม่มีให้ ลองนึกถึงตอนที่ทำการ Uninstall อะไรที่เราพึ่งสั่ง apply ไปสิครับ เราต้องไปไล่หาไฟล์ทั้งหมดที่เราสั่ง apply มาสั่ง delete แต่ถ้าเป็น Helm ล่ะก็คุณสั่งแค่คำสั่งเดียวครับ

Install Helm

ก่อนจะใช้งาน Helm เราต้อง install helm กันก่อนครับ โดยวิธี Install ดูได้ตาม Link นี้เลย : https://helm.sh/docs/intro/install/ ลงแบบไหนเอาตามที่ท่านสะดวกเลย

  • สำหรับใครที่ VM ของผม

ให้แก้ไขไฟล์ : /root/.bashrc

จากนั้นเพิ่มบรรทัดนี้เข้าไปใไฟล์

1
export KUBECONFIG="/etc/rancher/k3s/k3s.yaml"

จากนั้นสั่ง

1
source /root/.bashrc

จากนั้นสั่งกด ctrl + , เพื่อเปิดหน้าจอ Setting และกดตามภาพเราจะเปิดหน้า setting ขึ้นมา

จากนั้นนำข้อมูล JSON ด้านล่างไปใส่ในไฟล์ที่เปิดขึ้นมา

1
2
3
{
"terminal.integrated.defaultProfile.linux": "bash"
}

จากนั้นลองสั่งคำสั่งด้านล่างผ่าน terminal

1
helm list

ถ้าลงสำเร็จจะต้องได้ดังภาพ

เริ่มใช้งาน Helm

ตัวอย่างไฟล์ทั้งหมดสามารถดูได้ที่ Link

ทำการสั่ง command ด้านล่าง

1
helm create whoami

คำสั่งนี้จะเป็นคำสั่งที่สั่งสร้างสิ่งที่เรียกว่า Charts ขึ้นมา โดย Charts ก็เป็นเหมือน Template ที่บอกว่าเราต้องการ Deploy อะไรบ้าง ตัวแปร config ที่จะไปแทนที่ใน Template เป็นอะไร โดยเมื่อสั่งคำสั่งด้านบนเราจะได้ Folder และไฟล์แบบด้านล่าง

โดยสิ่งที่เราจะสนใจคือไฟล์ดังต่อไปนี้

  1. Chart.yaml

    ไฟล์นี้เป็นไฟล์ที่บอกรายละเอียดของ Chart นี้ว่าใช้ version อะไร เอาไปใช้ทำอะไร ให้คนที่เอา Chart เราไปใช้รู้ว่ามันคืออะไร

  2. templates

    Folder นี้เป็น Folder ที่เก็บไฟล์ yml ของ k8s ที่เราต้องการทำเป็น template

  3. values.yaml

    ไฟล์นี้เป็นไฟล์ที่ใส่ค่า config ที่เราจะไปแทนที่ใน template

จากนั้นทำการลบไฟล์ให้หมดจนเหลือแค่นี้ครับ (ลบไฟล์ใน Folder ด้วย)

สร้างไฟล์ template

สร้างไฟล์ whoami.yml ใน folder : templates โดยเราจะสร้าง deployment : whoami จากนั้นให้ยิงเข้ามาผ่าน ingress ที่ domain ชื่อ company-c.com ( อย่าลืม Add Domain name ใน file hosts นะครับ )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-deployment
labels:
app: whoami
spec:
selector:
matchLabels:
app: whoami-app
template:
metadata:
labels:
app: whoami-app
spec:
containers:
- name: whoami-container
image: traefik/whoami
ports:
- containerPort: 80
env:
- name: "OWNER"
value: "company-c.com"
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: whoami-ingress
spec:
rules:
- host: "company-c.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: whoami-service
port:
number: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami-service
spec:
selector:
app: whoami-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP

จากนั้นสั่งคำสั่งด้านล่างเพื่อให้ helm ทำงาน (เดี๋ยวอธิบายคำสั่งทีหลังนะครับ)

1
helm upgrade --install whoami-helm --namespace whoami-namespace  --create-namespace whoami/

จากนั้นสั่งคำสั่งด้านล่างเพื่อดูว่า helm ทำงานสำเร็จหรือไม่

1
helm list -A

จากนั้นลองสั่งคำสั่งด้านล่างเพื่อเช็คว่ามีอะไรเกิดขึ้นบ้าง

1
2
3
kubectl -n whoami-namespace get deployment
kubectl -n whoami-namespace get service
kubectl -n whoami-namespace get ingress

จากภาพจะเห็นว่ามีการสร้าง deployment , service ,ingress ขึ้นมาให้ตาม template เลย

จากนั้นลองเข้า Browser ไปที่ URL : http://company-c.com?env=true ซึ่งจะพบว่าสามารถเข้าถึง Container whoami ที่เราสร้างขึ้นมาได้

จากทั้งหมดเราจะเห็นว่าคำสั่งของ helm จะทำการสร้าง k8s object ตามไฟล์ที่ใส่ไว้ใน folder : template จากตัวอย่างคือไฟล์ : whoami.yaml

ทำ helm เอาค่า variable มาใส่ใน template ได้

จากตอนที่แล้วเรามีความต้องการที่จะ deploy app หลายๆตัวที่มีโครงสร้าง app เหมือนกันหมดเลย ต่างกันแค่บางค่าที่เฉพาะเช่น เปลี่ยน domain name เปลี่ยนค่า config ให้กับ app เป็นต้น ซึ่งตอนที่แล้วเราใช้ตัว envsubst ในการทำ แต่ตอนนี้เราจะใช้ helm ทำกันครับ

กำหนด Variable ที่จะใช้ในการแทนค่าได้

ส่วนนี้จะคล้ายๆกับการ set environment แต่ของ helm เราต้องกำหนดค่าที่ไฟล์แทน โดยเราจะกำหนดค่าที่ไฟล์ values.yaml โดยตัวไฟล์มีค่าดังนี้ (ค่าเก่าลบทิ้งไปได้เลยครับ)

1
2
domain: "company-c.com"
owner: "NORMAL PROGRAMMER"

ทำให้ Template สามารถเอาค่ามาใส่ได้

เมื่อเรากำหนดค่า variable มาแทนค่าได้แล้ว ส่วนต่อไปที่เราต้องทำคือทำให้ไฟล์ template สามารถเอาค่า variable มาใส่ โดยเราสามารถทำได้โดยการไปแก้ไขไฟล์ : whoami.yml โดยแก้ไขเป็น

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-deployment
labels:
app: whoami
spec:
selector:
matchLabels:
app: whoami-app
template:
metadata:
labels:
app: whoami-app
spec:
containers:
- name: whoami-container
image: traefik/whoami
ports:
- containerPort: 80
env:
- name: "OWNER"
value: {{ .Values.owner }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: whoami-ingress
spec:
rules:
- host: {{ .Values.domain }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: whoami-service
port:
number: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami-service
spec:
selector:
app: whoami-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP

โดยเราจะเห็นว่าส่วนแก้ไขคือ

1
2
{{ .Values.owner }}
{{ .Values.domain }}

ซึ่งมันคือ variable ที่เราประกาศไว้ในไฟล์ values.yaml ที่เราพึ่งกำหนดไป

จากนั้นลองสั่งคำสั่งด้านล่าง

1
helm upgrade --install whoami-helm --namespace whoami-namespace  --create-namespace whoami/

จากนั้นลองเปิด Browser ไปที่ URL : http://company-c.com?env=true ซึ่งจากภาพจะเห็นว่าสามารถเข้าไปที่ company-c.com ตาม value ที่กำหนดใน domain และ environment : onwer นั้นมีค่าเป็น NORMAL PROGRAMMER

คุณสามารถลองเปลี่ยนค่า variable ในไฟล์ values.yaml เป็นค่าอื่นดูแล้วสั่ง helm upgrade ดูว่าค่านั้นเปลี่ยนไปตามที่คุณต้องการหรือไม่

ถ้าอยากลบล่ะ

เราสามารถลบชุดการ deploy ที่สร้างขึ้นมาได้โดยใช้คำสั่ง

1
helm delete -n whoami-namespace whoami-helm

โดยเมื่อเราลองสั่ง list ดูจะเห็นว่าไม่มีข้อมูลชุดการ deploy : whoami-helm เหลืออยู่แล้ว

อธิบาย helm command

helm upgrade

คำสั่งนี้เราได้ใช้มาหลายครั้งแล้ว ส่วนนี้เรามาเข้าใจว่ามันทำอะไร

1
helm upgrade --install whoami-helm --namespace whoami-namespace  --create-namespace whoami/
  • helm upgrade : คำสั่งนี้เป็นการสั่งให้ helm upgrade ชุดการ deploy ที่ระบุ โดยในที่นี้คือสั่งให้ upgrade : whoami-helm

  • –install : ส่วนนี้คือการบอกว่าถ้าไม่เคยสร้างตัวชุดการ deploy มาก่อนให้ทำการสร้าง ในที่นี้คือถ้าไม่เคยมี whoami-helm

  • –namespace : ส่วนนี้คือการบอกว่าตัวชุดการ deploy นั้นจะไปอยู่ใน namespace ไหน ในที่นี้คือไปสร้างใน namespace : whoami-namespace

  • –create-namespace : ส่วนนี้คือการบอกว่าถ้า namespace ที่จะให้ไปอยู่ยังไม่เคยสร้าง ให้ทำการสร้าง namespace ขึ้นมาด้วย

  • whoami/ : ส่วนนี้คือ parameter ที่บอกว่าตัว template และ variable อยู่ที่ใด โดยในที่นี้คืออยู่ใน folder : whoami

รวมแล้วคำสั่งนี้คือการสั่งให้ helm ทำการสร้างชุด deploy ชื่อ whoami-helm ให้อยู่ที่ namespace : whoami โดยรายละเอียดที่ว่าต่างๆจะอยู่ใน folder whoami โดยถ้าชุดการ deploy : whoami-helm ไม่เคยสร้างให้ทำการสร้าง ถ้า namespace : whoami ไม่เคยสร้างให้ทำการสร้าง

helm list

1
helm list -A
  • helm list : คำสั่งนี้เป็นคำสั่งที่ทำการแสดง ชุดการ deploy ทั้งหมดที่สร้างด้วย helm ใน namespace ที่เรากำลังอยู่

  • -A : ส่วนนี้คือบอกว่าให้แสดงทุก namespace

รวมแล้วคำสั่งนี้คือให้แสดงชุดการ deploy ทั้งหมดทีสร้างด้วย helm ในทุก namespace

helm delete

1
helm delete -n whoami-namespace whoami-helm
  • helm delete : คำสั่งนี้เป็นคำสั่งให้ทำการลบชุดการ deploy ที่ต้องการ

  • -n : คือการบอกว่าชุดการ deploy ที่ต้องการลบอยู่ namespace ไหน ในที่นี้คือ namespace : whoami-namespace

  • whoami-helm : คือ parameter ชื่อชุดการ deploy ในที่นี้คือ whoami-helm

รวมแล้วคำสั่งนี้คือการสั่งให้ลบ ชุดการ deploy ที่ชื่อ whoami-helm ที่อยู่ใน namespace : whoami-namespace

อยาก Deploy หลายๆ config

จากที่ส่วนที่ผ่านมาจะเห็นว่าเราสามารถแทน variable ไปใส่ใน template ได้แล้ว และเราสามารถแก้ไข variable ได้ที่ไฟล์ : values.yaml แต่ถ้าลองคิดดีๆมันก็เหมือนว่าเราต้องค่อยๆแก้ไขไฟล์ values.yaml ทุกครั้งที่เราอยากจะ deploy app ด้วย config ที่แตกต่าง ซึ่งนั่นไม่แตกต่างจากการแก้ไขที่ไฟล์ template เลย

แต่ไม่ต้องกังวลครับ helm เขาคิดเรื่องนี้มาแล้วและเปิดช่องทางให้เราสามารถ deploy ด้วยการใช้ values.yaml จากหลายที่ได้

สร้างไฟล์ values ใหม่ขึ้นมาเพื่อใช้ในการ deploy ที่มี config แตกต่าง

ทำการสร้าง folder : config-value จากนั้นทำการสร้างไฟล์

  • values-company-a.yaml
1
2
domain: "company-a.com"
owner: "COMPANY-A-WASINEE"
  • values-company-b.yaml
1
2
domain: "company-b.com"
owner: "COMPANY-B-PICHAYA"

จะเห็นว่าเรากำหนดตัว domain และ owner แตกต่างกันไว้

ทำการ deploy โดยใช้ไฟล์ values.yaml ตามที่เรากำหนด

ลองสั่งคำสั่งด้านล่าง โดยจะเห็นว่ามี parameter เพิ่มเข้ามาคือ -f ซึ่ง parameter ตัวนี้เป็นตัวบอกว่าไฟล์ values.yaml ที่เราอยากใช้นั้นคือไฟล์ไหน

1
2
helm upgrade --install company-a-whoami-helm --namespace whoami-a-namespace  --create-namespace whoami/ -f config-value/values-company-a.yaml
helm upgrade --install company-b-whoami-helm --namespace whoami-b-namespace --create-namespace whoami/ -f config-value/values-company-b.yaml

จากภาพจะเห็นว่าเราได้ชุดการ deploy มาสองตัวคือ company-a-whoami-helm , company-b-whoami-helm ออกมา

มาทดสอบว่าการ deploy นี้ใช้งานได้จริงหรือไม่โดยเข้า browser แล้วไปที่ : http://company-a.com/?env=true

จากภาพจะเห็นว่าสามารถเข้าถึง company-a ได้จริงและค่า environment owner นั้นค่าตรงกับที่ config ไว้ในไฟล์ values-company-a.yaml

มาลองกับ company-b โดยเข้าไปที่ http://company-b.com/?env=true

จากภาพจะเห็นว่าสามารถเข้าถึง company-b และ environment เป็นไปตามที่ config ไว้ใน values-company-b.yaml

สรุป

สำหรับตอนนี้เราได้รู้เกี่ยวกับวิธีการใช้ helm ในการ deploy ประกาศ template ยังไง ประกาศ variable ยังไง และจะเอา variable มาใส่ใน template ยังไง อีกทั้งเรายังสามารถ deploy โดยกำหนดไฟล์ values ตามตำแหน่งที่เราต้องการได้ ซึ่งจากการทำวิธีนี้ทำให้เราสามารถ deploy application ให้แตกต่างตาม config ได้เทียบเท่ากับการใช้ envsubst ในตอนที่แล้ว (อาจจะง่ายกว่าด้วย) สำหรับตอนหน้าเรามาลองใช้ feature อื่นๆของ helm ที่คิดว่าทำให้การ deploy นั้นซับซ้อนขึ้นได้อีก และ คำสั่งที่จะอำนวยความสะดวกเราในการ deploy