สำหรับวันนี้เป็นวันสุดท้ายของ Helm Essential Class ของคุณคุณโจโจ้ JumpBox แล้วครับ วันนี้มา output เป็นการบ้านอีก Blog ครับ โดยมีหัวข้อ ดังนี้
สำหรับ Helm Essential มี 4 ตอนนะครับ
Designing Solution (Workflow)
key: ทำให้ดี คนอื่นมาดูต่อได้ operational work / แล้วค่อยมาปรับ perf
Source - ทำมือ หรือ จะเอาพวก CI/CD มาช่วย
Share / Publish เวลาเราเอา Chart เอาไป Share ในทีม หรือ องค์ เพราะเราอาจจะไม่ได้ใช้คนเดียวนะ ซึ่งมันมีหลายวิธีการตั้งแต่ง่ายๆ
- ฝากไว้ใน Source Control อย่าง GitHub / GitLab เอาไฟล์ .tgz Commit ไปตรงๆ
- หรือ ไปใช้ Package Repository อย่าง เช่น
- GitHub Package
- GitLab Package Registry (ของ GitLab ยังเป็น Beta Version อยู่นะ)
- Artifacthub.io - หรือ ทำ Repository ขึ้นมา เก็บไว้ใช้ภายใน มีตัว chart museum / nexus (Community / Paid Version)- nexus
Comsume - การเรียกใช้
- Add Repository เข้าไปตรงๆ
- หรือ ใช้วิธีการ Proxy เราอยาก Add แค่ Source เพียงแหล่งเดียว แล้วให้ตัว Tools มันวิ่งไปหาจาก Data Source ที่ Map ไว้ อย่างเคสของ Helm Proxy จาก Artifacthub.io / Helm Data (ภายใน) ข้อดีทำ Cache ภายใน และ map จุดเดียว Tools ที่แนะนำ nexus
Record - จดบันทึกกการตัดสินใจ จะได้จำได้ว่าเราทำอะไรลงไป สมัยนี้จะเป็นเอกสาร ADR
อันนี้ของแชร์ของตัวเองบ้าง เพราะมี Software หลายตัว
- อย่างตัว Package Repo ตอนแรกใช้ NuGet.Server เก็บของ แล้วมาพบปัญหาว่าพอเวลาจะไปดึง nuget.org มันมี Traffic สูงมาก โดยเฉพาะช่วงนี้ Jenkins มัน Trigger เลยเลือกใช้ Nexus เพราะมัน Cache ได้ และเก็บได้อย่างทั้ง NuGet / Maven / NPM / Container ตอนนี้มี Helm
- ส่วน GitLab มีใช้นะ แต่ทำไมใช้ Repository ของมัน จริงๆกลัวเรื่อง Vendor Lock เพราะใช้ตัว Community + Self Manage ถ้ามีอะไรเปลี่ยน อย่าง License มันจะลำบากเลยแยก nexus ออกมา โดดๆอีกตัว แล้วให้มันคุยโยนของกันผ่าน Protocal https แทน
Helm in Nexus ตอนนี้ ถ้าดูใน Helm ยังมี
- helm (hosted) - ใช้กับภายใน Local
- helm (proxy) - ให้ nexus เป็นตัวแทนเราไปดึง จาก url ที่กำหนด เช่น https://artifacthub.io/ แล้วมันจะช่วย Cache ให้ด้วย
- helm (group) - ยังไม่มี แต่อันนี้มีคนเปิด Ticker ไว้แล้ว อีกไม่นาน จะได้เห็น Add Helm group repository #409
Verying Helm Chart
การตรวจสอบ Helm Chart ของเราที่ทำ ว่ามัน work ไหม โดยมี 3 วิธี (helm lint
/ helm template
/ --dry-run
) และ 1 พิเศษ --debug
( แบบสั่งบะหมี่เลย)
- helm lint
helm lint <path_to_helm> <option> //sample helm lint .
lint - บอก Syntax / ตรวจ โครงสร้างของ Chart คร่าวๆ / ตรวจ yaml format เรื่อง indent + space
- พอมาลองจริง นอกจาก Error แล้ว มันยังแนะนำตาม Rule ด้วยนะ อย่างอันนี้ผมเอาตัว Helm ที่ใช้ได้มาลอง มันบอก ควรใส่รูป icon นะ
แล้วถ้าลองให้ Error
- yaml มันบอกนะ พวก space error นะ ที่เจอปัญหาพวกนี้ เอา vscode plugin Prettier มาช่วยได้
- ที่ลองมาพวก pre-define จะ Error อย่างพวก
.Release.xxx
/.Chart.xxx
/.Capabilities
ที่มันมีตัวแปรพิเศษที่มัน build-in มันจะตรวจให้ อย่าง.Capabilities.KubeVersion
>.Capabilities.Kubeversion
น่าจะชื่อไม่ตรงกับ Struct
- แต่ถ้าเป็นกลุ่ม
.Values.xxx
มันจะดักได้เฉพาะ ส่วนแรก Values ถ้าเขียนผิด มันดักได้ส่วนค่าข้างหลังตรวจไม่ได้
- ลองแก้นามสกุลของไฟล์เป็น json มันตรวจได้นะ
==> Linting .
[INFO] Chart.yaml: icon is recommended
[ERROR] templates/configmap.json: file extension '.json' not valid. Valid extensions are .yaml, .yml, .tpl, or .txt
- helm template
Template - ลองให้ helm render yaml ของ k8s ว่าค่าที่ได้จะเป็นยังไง
สำหรับที่เรียนมา มันตอบปัญหาที่ผมจดไว้ใน Blog ตอนก่อนหน้าด้วย ตอนแรก ผมเข้าใจว่า พวก Release Name มันต้องลงจริง ถึงจะได้ค่ามา แต่จริงๆแล้ว Syntax Helm Template
helm template <relase_name> <path_to_chart> <option> //หิวพอดี ตั้งชื่อ release ชายสี 5555 helm template chai4 .
ลองดูเต็มๆได้จาก Blog ของตอนที่ 3: จดๆ ลงมือทำ Helm Essential > Helm Package
- helm .... --dry-run
ลองต่อกับ Kube Cluster แล้วให้มันส่งผลลัพธ์กลับมา โดย option --dry-run
มีเกือบทุก Command ของ Helm แต่ต้องตรวจสอบด้วย ดูจาก help ของแต่ละคำสั่ง โดย dry-run
ปล Sample dry-run ดูได้จาก blog ตอนที่ 2 ตอนนั้นสงสัยว่า kubectl มี dry-run client แลัว helm มีไหมเลยได้ลอง และ cap จดๆไว้นิดหน่อย
ค่าที่เป็นไปได้ ลองใส่มั่วๆให้มันด่า มันบอกว่ามี 5 ค่า
PS D:\2024Helm\sample> helm template . --dry-run=foo Error: Invalid dry-run flag. Flag must one of the following: false, true, none, client, server
ถ้าอยากรู้ว่ามันใช้ได้/ไม่ได้ อีกท่าที่คุณโจ้สอน เอาสิ่งที่ helm template มา render สงให้ kube ลองเลย ผมจะประมาณนี้ kubectl apply -f -
ตัว -
ดึงจากตัว std io ที่ helm template print มายัด
helm template chai4 . | kubectl apply -f - --dry-run=client helm template chai4 . | kubectl apply -f - --dry-run=server #หรือ ส่งไป Run จริงเลย helm template chai4 . | kubectl apply -f -
- helm .... --debug
--debug
เปิด debug mode ของ go มาดูว่าพังที่ไหน โดยเป็น Global Flag ของ helm โดยดูจาก help มันจะเรียกใช้ได้ทุกคำสั่ง ดังนั้น helm lint
/ helm template
/ --dry-run
เอา --debug มาให้คู่เสริมได้เหมือนกัน อารมณ์แบบสั่งพิเศษ
- Plug-in Check ตัว yaml เยือง space - YAML - Visual Studio Marketplace
สุดท้ายการที่มี Lint / Template / --dry-run / --debug มันแค่เป็นการลดความเสี่ยงที่จะเอาไปติดตั้งบน kube แล้วพังเท่านั้น อย่าลืมลองจริง ก่อนส่งงานด้วยนะ
Writing Helm Chart
- helm function
งานที่มันซ้ำ หรือ ต้องใช้บ่อยๆ ไม่ต้องมาเขียนเอง แบบพวก string upper / lower เป็นต้น โดยเราสามารถเรียกใช้ function ได้ อย่างเช่น
- ลองใช้ตัวเดียว ตัว default
apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: {{ default "dotnetapp" .Values.appName }} release: {{ .Release.Name }} name: {{ .Values.appName }} ...
ถ้าต้องการใช้ 2-3 อันต่อกันทำยังไง
- ใช้ pipe ต่อกัน
app: {{ default "dotnetapp" .Values.appName | upper | quote }}
- เรียก function ซ้อนกัน
app: {{ quote (upper (default "dotnetapp" .Values.appName)) }}
เหมือน coding เลย ตัว Helm ทำจาก Go เลยใช้แบบนี้ได้
ตัว _ หน้าชื่อไฟล์ _xxx.yaml บอกว่า ให้ helm ไม่ต้อง Generate
- helm control flow
- if / else เหมือนใน coding ทั่วไป
{{- if <expression> }} ... {{- else if <expression> }} ... {{- end }}
- โดยที่ต้องเติม - หน้า if เพราะต้องการตัดบรรทัดเกิน ทำให้อ่านยาก โดย
{{ template direction }}
มีรูปแบบ trim ดังนี้
{{- trims all whitespace to the left of the expression. trims all whitespace to the right of the expression. -}} แต่ มันต้องติดปีกกานะ {{- if << ทำงานได้ {{ - if << error
จากตัว if มันสามารถทำตัว feature toggle ขึ้นมาได้ เช่น
- กำหนดจำนวน replica ใน prod เอาไปเลย ตามในไฟล์ value ที่กำหนด แต่ไม่ใช่ เช่น dev test ให้แต่ 2 ถ้าให้ label ผิด ให้ไปเลย 1 ตัว Deployment เดิม เราเติมเงื่อนไขเข้าไป ตามนี้
//deployment spec: {{- if eq .Values.environment "prod" }} replicas: {{ .Values.replicaCount }} {{- else if or (eq .Values.environment "test") (eq .Values.environment "dev") }} replicas: 2 {{- else }} replicas: 1 {{- end }} selector: matchLabels: app: {{ .Values.appName }} strategy: {}
- ไม่จำเป็นต้องสร้าง kube object เช่น service ถ้าใช้ภายในนั้น หรือ ให้ pod มันทำงานเงียบๆไป ก็ทำ if ครอบที่ต้น และท้ายไฟล์เลย
พวก operator ที่เป็นไปได้ Helm | Template Functions and Pipelines - Operators are functions
- helm with block
ตอนเรียน ผมฟังครั้งแรกนึกถึงพวก with ของ vba นะ มันเอาไล่ลดการอ้างอิง เรียกว่า Code สะอาดขึ้น สำหรับใน Helm ทำหน้าที่คล้ายๆกันนะ
- ก่อนอื่นตัว Values.yaml มันแปลงเป็น tree ได้นะ > Binary tree ถ้าอยากให้เร็ว ลดลง level Optimize เรื่อง search
- ตัว tree แล้วที่นี้ถ้าอยาก access ถึงค่านั้นเร็วๆ เรากำหนด scope ให้มันชัด มันจะเลื่อนมาจุดที่สนใจ
- แต่มีข้อเสีย อยู่ใน with แล้ว เราจะอ้างอืงถึงข้อมูลอื่นๆไม่ได้นะ ถ้าต้องการจริงๆ $ เพื่อให้กลับไป root (Line 8-9)
{{- if .Values.service.enabled -}} apiVersion: v1 kind: Service {{- with .Values.service }} metadata: name: {{ .name }} labels: app: {{ default "dotnetapp" $.Values.appName | upper | quote }} version: {{ $.Chart.AppVersion }} spec: selector: app: aspnetapp ports: - name: http protocol: TCP port: {{ .port }} targetPort: {{ .targetPort }} nodePort: {{ .externalPort }} type: NodePort {{- end -}} {{- end -}}
ควรมีกี่ level จริงๆแล้วแต่ Use-Case แต่ปกติ 3-5 เพราะ ถ้ายิ่งเยอะ จะยิ่งอ่านยาก สุดท้ายขึ้นกับข้อตกลงของทีม
- อีกอัน เรื่องของ with การใช้ซ้อนกัน มันอาจจะอ่านยากขึ้น แบบตัวอย่างด้านล่าง ต้องมาแบ่งให้ดี อันนี้เอามาจาก appsetting ถ้าวาดเป็น Tree มันจะหนักขวา
apiVersion: v1 kind: ConfigMap metadata: name: aspnetcore-config data: {{- with .Values.appSettings }} appsettings.json: | { {{- with $.Values.appSettings.Logging.LogLevel }} "Logging": { "LogLevel": { "Default": {{ .Default | quote }}, "Microsoft": {{ .Microsoft | quote }}, "Microsoft.Hosting.Lifetime": {{ .MicrosoftHostingLifetime | quote }} } }, {{- end }} "AllowedHosts": {{ .AllowedHosts | quote }}, "ConnectionStrings": { "DefaultConnection": {{ .ConnectionStrings | quote }} } } {{- end }}
appSettings: Logging: LogLevel: Default: Information Microsoft: Warning MicrosoftHostingLifetime: Information AllowedHosts: "example.com;localhost" ConnectionStrings: "example_connection_string"
- และ helm lint ตรวจได้นะ ตามรูป
อีก usecase ของ with เอาไว้ set ค่าเยอะๆ ในกลุ่ม configmap กับ value.yaml นอกจากนี้แล้วมี kustomize มันเอา env / app.setting มาได้ เพราะบางอย่าง configmap มันต้องเอา value.yaml มา map อีกที
{{- with .Values.favorite }} drink: {{ .drink | default "tea" | quote }} food: {{ .food | upper | quote }} release: {{ $.Release.Name }} {{- end }} ///////////////////////////////////////// {{- with .Values.favorite }} drink: {{ .drink | default "tea" | quote }} food: {{ .food | upper | quote }} {{- end }} release: {{ .Release.Name }}
- helm range
เอาไว้ให้ทำงานที่ซ้ำ เอาค่าในที่กำหนดไว้เป็น List มา for each ตัวอย่างผมเอามาจาก helm.sh ไปงมกับอีกโจทย์ที่อยากลอง
- values.yaml
favorite: drink: coffee food: pizza pizzaToppings: - mushrooms - cheese - peppers - onions
แล้วยัดค่าลงมา เริ่มบรรทัดที่ 9
- บรรทัด 9 toppings:
|-
บอกว่าเป็น multiline string - บรรทัด 10-12 เข้า Loop ดึงค่าจาก pizzaToppings จากนั้นเข้า pipe
- Title ทำให้ตัวใหญ่ขึ้น
- quote
apiVersion: v1 kind: ConfigMap metadata: name: {{ .Release.Name }}-configmap data: myvalue: "Hello World" {{- with .Values.favorite }} drink: {{ .drink | default "tea" | quote }} food: {{ .food | upper | quote }} toppings: |- {{- range $.Values.pizzaToppings }} - {{ . | title | quote }} {{- end }} {{- end }}
พอมาคิดว่าจะใช้จริงตรงไหนได้ configmap น่าจะ 1 ที และอีกจุดเลยย้อนมาคิดถุึง blog ลง Ingress-nginx ผิด พังยาวเลย ตรง ingress ที่เรา Config มันจะมี pattern น่าจะใช้ได้ เลยให้ map เอง คิด nested loop ตบตีมาครึ่งวันได้จะได้แบบนี้ //ถ้าถาม AI อาจจะไวกว่า 55
- ingress template
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/rewrite-target: / name: ingress-production namespace: application spec: ingressClassName: nginx rules: {{- range .Values.ingress.rules }} - host: {{ .host }} http: paths: {{- range .paths }} - path: {{ .path }} pathType: {{ .pathType }} backend: service: name: {{ .serviceName }} port: number: {{ .servicePort }} {{- end }} {{- end }}
- values.yaml ของมัน
ingress: rules: - host: admin.pingkunga.dev paths: - path: / pathType: ImplementationSpecific serviceName: admin-console servicePort: 4200 - host: user.pingkunga.dev paths: - path: / pathType: ImplementationSpecific serviceName: user-console servicePort: 3000 - host: api.pingkunga.dev paths: - path: /api/dashboard pathType: ImplementationSpecific serviceName: dashboard-service servicePort: 5000 - path: /api/payment pathType: ImplementationSpecific serviceName: payment-service servicePort: 1323 - path: /api/report pathType: ImplementationSpecific serviceName: report-service servicePort: 4000 - path: /api/order pathType: ImplementationSpecific serviceName: order-service servicePort: 10456
ลองแล้วดูผ่านๆ เหมือนตันฉบับอยู่นะ แล้วด้วยความสงสัยไปส่อง Sample ของ helm ตอน new ขั้นมา มันซับซ้อนกว่าเยอะมาก แต่ดูทรงคล้ายๆกัน
- helm Named Templates
ปัญหา เรามีส่วนของ yaml ซ้ำซ้อนกันให้ทุกจุด และอยากให้การแก้ไข ทำได้จากจุดเดียว และให้ทุกจุดเอาไป Apply เอง จะตรงกันแนวคิด DRY (Don’t Repeat Yourself) นะ พอทุกจุดมันสอดคล้องกัน เราข้อมูลในจุดนั้นไปใช้งานต่อได้ เช่น กำหนด pattern ของ label เอาข้อมูลตรงนั้นมีวิเคราะห์ Cost (FinOps) ได้
ใน Helm มีตัวช่วยมาให้ โดยการทำ Named Templates ซึ่งจะมีไฟล์ _xxxxx.tpl
- _ บอกให้ตัว helm ไม่เอาไป Generate
- .tpl บอกให้ตัว helm รู้ว่าต้องเอา ข้อความจากนี้ไปตัดแปะต่อ เพราะในส่วนนี้มันเป็น partial ที่ถูกำหนดไว้ตาม {{- define <your_key> }} เท่าน้้น
การใช้งาน Named Templates
1. เรียกใช้ผ่าน {{- template <your_key> <replace_scope> }}
- ถ้าไม่ใส่
<replace_scope>
มันจะแก้ไขค่าตัวแปรไน template ไม่ได้ เพราะไม่รู้ Scope
ข้อเสียนี้ มันไม่จัด indent ให้นะ พวก yaml มันจะ error ได้ มันเอาค่ามา replace ตรงๆ
2. เรียกใช้ผ่าน {{- include <your_key> <replace_scope> }}
ทำงานเหมือนกับตัวแรก มันเป็น function เลยเราเลยสามารถทำ pipeline เรียก func indent ได้
เรื่องของ replace scope หากเราส่ง
.
ไป หากมันถูกครอบด้วย with จะเกิดปัญหาหาของไม่เจอ บางทีต้องส่ง$
แทน
นอกจากนี้แล้ว ตัว Named Templates ถ้ามัน Common มากๆ จนเอาไปใช้งานกับหลายๆ Helm Chart ได้ จะถูกยกเป็น dependeny ให้ Chart อื่นๆได้นะ
Ref: Helm | Named Templates / https://stackoverflow.com/questions/63196657/helm-how-do-we-decide-indent-value-in-helm-templates
Chart Hooks
สำหรับตัว ChartHooks โดยผมมีอะไรที่สงสัยที่ลองแปะไว้ใน Blog ตอน 2 ลองวาด Flow ออกมาไว้เป็นภาพนี้
พอเรียนแล้วลองมาจด Recap กันต่อ ว่า Chart Hooks เป็นจุดให้ที่เราแทรก Action ต่างๆได้ ก่อนที่จะมี Action ต่างๆ install / upgrade / rollback / uninstall / test มี 5 ส่วน โดยแต่ละแบบ 2 กลุ่ม ตาม Event
- Pre / Post Event- ก่อน action install / upgrade / rollback / uninstall
- Test Event - เป็นกลุ่มพิเศษเลย
โดยก่อนจะเข้า action มันจะต้องผ่าน Step verify (ตาม Lint) / render (ตาม logic ที่เราเขียนลงไป) จากนั้นเข้าส่วนของ Chart Hooks โดยภาพใหม่ของผม จะประมาณนี้
ถ้าเริ่มทำ Chart Hooks โดยการที่จะรู้ว่าของอันนั้นเป็น Hook ต้องมี annotation ส่วนใหญ่ของใน Hook จะเป็นแบบ job ทำแล้วจบไป โดยมี annotations ที่เปลี่ยนข้อง
- "helm.sh/hook": บอกว่า yaml นี้ อยู่ในส่วนไหนของ Hooks ถ้าไม่มี มันจัดเป็นส่วนนึงของ release เลย
- "helm.sh/hook-weight": บอกลำดับของการ Hooks ตามกลุ่ม "helm.sh/hook" ถ้าเลขน้อย จะถูกทำเป็นตัวแรก สมมิตเลขเรียงตามนี้ -1 < 1 < 5 ลำดับเริ่มจาก -1 ก่อน
- "helm.sh/hook-delete-policy": ป้องกันมี resource ของ hook เหลือ (Clean-Up) โดยมี 3 แบบ
- before-hook-creation - ถ้ามีของเดิม ให้ลบทิ้ง (Default)
- hook-succeeded - ลบเมื่อทำสำเร็จ
- hook-failed - ลบแม้ว่าจะ fail
ตัว hook อาจจะไม่จำเป็นต้องใช้ได้ ก็ได้นะ ตัว helm เองจะการจัดการ state ของมัน เช่น ถ้ามัน fail ให้มัน
helm upgrade <release_name> <path_to_chart> -f [your_value.yaml] --cleanup-on-fail
แต่ถ้าลองแล้ว มันซับซ้อนกว่านั้นมาลอง implement pre-upgrade / post-upgrade
- ลองเล่น Chart Hooks
โจทย์ ก่อนจะ helm upgrade ลองส่งเมล์ดู จะอยู่ใน event pre-upgrade และเป็น job สั้นๆ
- ลองเพิ่มพวกการตั้งต่า email ใน values.yaml ผมใช้ gmail ต้องมาเปิด App Password มีจด Blog ไว้ Google Account เปิดใช้งาน App Password
#================== # Pre-upgrade Values smtp: user: <sender_mail>@gmail.com pass: <sender_app_password> to: <recipient_mail@example.com? subject: "Helm Chart Upgrade Notification" body: "The Helm chart Start Upgrade."
- ทีนี้ตัว helm chart ของเรามาเพิ่ม job ลง และแน่นอน คิดว่ามันไม่น่าจะ secure นะ เอา user pass replace โต้งๆ บรรทัดที่ 5-7 ส่วนสำคัญเลย ใส่ annotation บอก ตอนแรกผมใส่ Label ไป มันส่งทุกรอบ 555555
- "helm.sh/hook": pre-upgrade //ให้ทำตอน pre-upgrade
- "helm.sh/hook-delete-policy": hook-succeeded //ถ้าทำจบให้ delete job ทิ้ง
apiVersion: batch/v1 kind: Job metadata: name: "{{ .Release.Name }}-pre-upgrade-email" annotations: "helm.sh/hook": pre-upgrade "helm.sh/hook-delete-policy": hook-succeeded spec: template: spec: containers: - name: send-email image: alpine:3.12 command: ["/bin/sh", "-c"] args: - | apk add --no-cache msmtp ca-certificates && \ # Email details SMTP_USER="{{ .Values.smtp.user }}" \ SMTP_PASS="{{ .Values.smtp.pass }}" \ TO_EMAIL="{{ .Values.smtp.to }}" \ SUBJECT="{{ .Values.smtp.subject }}" \ BODY="{{ .Values.smtp.body }}" && \ # Create msmtp configuration cat <<EOF > /etc/msmtprc defaults auth on tls on tls_trust_file /etc/ssl/certs/ca-certificates.crt logfile /var/log/msmtp.log account gmail host smtp.gmail.com port 587 from ${SMTP_USER} user ${SMTP_USER} password ${SMTP_PASS} account default : gmail EOF # Send email echo -e "Subject:${SUBJECT}\n\n${BODY}" | msmtp --debug --from=${SMTP_USER} -t ${TO_EMAIL} restartPolicy: Never
- ลอง install ของผมยังไม่ได้ pack ลองแบบนี้
helm install netapp .
- จากนั้นไปที่ Chart.yaml แล้วแก้ตัว version: 0.1.1 ของผมแก้เป็น version: 0.1.2
- ลอง upgrade
helm upgrade netapp .
แต่ก่อนจะรันแอบไปเปิด Terminal อีกอัน แล้ว run
//powershell นะ จะเห็น job มันทำงาน และเด้งเมล์มาwhile (1) {kubectl get pod; sleep 1}
อีกอันที่ลองตรวจ version helm เหมือนมันจะเอ๋อๆอยู่ ถ้ามัน OK เขียนลงอีก blog ครับ อยากลองแบบพวก DB แต่ DB ยังสาย docker compose / VM อยู่
Ref: Helm | Chart Hooks
อื่นๆ
- Q:ควรใช้ Chart เดียว หรือ แยก Sub Chart ย่อยๆเยอะๆ ทำ Common
- ทำความเข้าใจ ก่อน
-> อาจจะรวม Chart เดียว และทำ Feature Toggle
-> แต่ถ้ามันเป็นคนละ Domain อย่าง เช่น ของ Bitnami Nginx / Nexus / Redmine อันนี้เค้าทำ Common ขึ้นมา เพื่อกำหนดแนวทางให้ไปทางเดียวกัน เช่น พวก partial / name / error - Q: กรณีเราใช้ third-party chart ควรเป็น Value อย่างไร
- เก็บที่ทำแยกไว้ ส่วน Chart ถ้ามี Repository ในองค์กร อย่าง nexus ก็โยนขึ้นไป รวมกันใช้ที่ Repo กลางแทน - พวก chart มี test ด้วยนะ และมี tools สำหรับทำ CI เช่น kind action - small k8s chart test / chart-testing Action
Blog ของท่านอื่น
เขียน blog นี้จบ ว่าจะหนีไป podman desktop / docker desktop มันกิน Ram เกิ๊นนน เรียนเสร็จ เหลือเอาไปลอง pack จริงๆและว่าจะเจออะไรบ้างครับ หากอ่านแล้วชอบสนใจเรียนติดต่อคุณโจโจ้ JumpBox ครับ ^__^
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.