Kubernetes 基礎教學(三)Helm 介紹與建立 Chart

什麼是 Helm?Helm 如何運作?手把手體驗如何建立一個 Helm Chart。

image

Kubernetes(K8S)是一個可以幫助我們管理微服務(microservices)的系統,他可以自動化地部署及管理多台機器上的多個容器(Container)。簡單來說,他可以做到:

  • 同時部署多個容器到多台機器上(Deployment)
  • 服務的乘載量有變化時,可以對容器做自動擴展(Scaling)
  • 管理多個容器的狀態,自動偵測並重啟故障的容器(Management)

系列文目錄

在系列文的第一篇文章中,我們了解了構成 Kubernetes 的四個重要元素:Pod、Node、Master、Cluster,並安裝好了我們要實際動手玩 Kubernetes 前需要的套件與工具。而在第二篇文章中,我們實際動手操作了 Kubernetes 中的 Pod、Service、Deployment、Ingress。

接下來在這篇文章中,我們會介紹一個建立 Kubernetes 應用變得輕鬆簡單的好幫手:Helm。並且一如往常地,我們一樣可以在這篇文章中動手實際操作它!

Helm

image 1

如何建立一個 Pod 以及 Kubernetes 進階三元件我們介紹了多個 Kubernetes 的元件與他們所對應到的 yaml 設定檔。假設我們今天有一個複雜的服務,裡面同時包含了很多種設定檔時,如何同時做好版本控制、管理、更新這些設定檔就變得不太容易,且要快速部署這個含有多個設定檔的服務也變得困難。因此 Helm 就是一個用來解決上述問題的工具。

簡單來說,Helm 就是一個管理設定檔的工具。他會把 Kubernetes 一個服務中各種元件裡的 yaml 檔統一打包成一個叫做 chart 的集合,然後透過給參數的方式,去同時管理與設定這些 yaml 檔案。

使用一個現有 Helm Chart

接下來我們要來示範用一個現有的 Helm Chart 來嘗試部署一個 Wordpress 的服務。首先,我們的第一步當然就是要下載 Helm。MacOS 中我們可以直接使用 Homebrew 安裝,其他環境可以參考 Helm 的 Github

brew install kubernetes-helm

下載完後,我們記得要 Helm 把 Cluster 配置初始化

helm init

接下來讓我們安裝 Wordpress 的 Chart,我們可以直接透過指令

helm install stable/wordpress

這個指令會讓我們直接到 Chart Repository 去載入 Chart 檔並將它部署到我們的 Kubernetes Cluster 上,我們現在可以透過指令檢查我們的 Cluster

kubectl get all
NAME                                    READY   STATUS    RESTARTS
pod/peddling-hog-mariadb-0              1/1     Running   0
pod/peddling-hog-wordpress-7bf6d69c8b   1/1     Running   1
 ​
NAME                             TYPE           CLUSTER-IP
service/peddling-hog-mariadb     ClusterIP      10.109.96.113
service/peddling-hog-wordpress   LoadBalancer   10.101.157.184
EXTERNAL-IP   PORT(S)
<none>        3306/TCP
<pending>     80:30439/TCP,443:31824/TCP
 ​
NAME                                   READY UP-TO-DATE AVAILABLE
deployment.apps/peddling-hog-wordpress 1/1   1          1
 ​
NAME                                                DESIRED
replicaset.apps/peddling-hog-wordpress-7bf6d69c8b   1
 ​
NAME                                    READY   AGE
statefulset.apps/peddling-hog-mariadb   1/1     60s

可以看到我們透過 Chart 一次就安裝與部署了兩個 Pod、兩個 Service 以及其他各種元件。如果要一次把所有 Chart 所安裝的元件刪除,我們可以先透過 helm list 列出我們所有的 Chart。

NAME         REVISION UPDATED                  STATUS   CHART
peddling-hog 1        Fri Apr 26 16:08:30 2019 DEPLOYED wordpress

然後輸入 helm delete peddling-hog 就可以一次把所有元件刪除。

Chart 的運作方式

嘗試完從 Chart 部署元件後,我們可以進一步來暸解 Chart 是如何運作的。我們可以到 Wordpress chart 的 Github 上觀察這個 Chart 的檔案結構,或是透過指令來建立一個最簡單的 Chart

helm create helm-demo

接下來我們來看看 ./helm-demo 的資料夾

.
├── Chart.yaml
├── charts
├── templates
│   ├── deployment.yaml
│   ├── ingress.yaml
│   └── service.yaml
└── values.yaml

把這個 Chart 的檔案結構化簡後就如上所見。

Chart.yaml

  • 定義了這個 Chart 的 Metadata,包括 Chart 的版本、名稱、敘述等

charts

  • 在這個資料夾裡可以放其他的 Chart,這裡稱作 SubCharts

templates

  • 定義這個 Chart 服務需要的 Kubernetes 元件。但我們並不會把各元件的參數寫死在裡面,而是會用參數的方式代入

values.yaml

  • 定義這個 Chart 的所有參數,這些參數都會被代入在 templates 中的元件。例如我們會在這邊定義 nodePortsservice.yaml 、定義 replicaCountdeployment.yaml、定義 hostsingress.yaml 等等

從上面的檔案結構可以看到,我們透過編輯 values.yaml,就可以對所有的 yaml 設定檔做到版本控制與管理。並透過 install / delete 的方式一鍵部署 / 刪除。

如何建立自己的 Chart

了解了 Chart 大致上是如何運作後,我們就可以來實際建立一個簡單的 Chart。我們的目標是要透過 deploymentserviceingress 來讓使用者在輸入 blue.demo.com 時可以得到一隻小鯨魚。而首先,我們一樣輸入指令

helm create helm-demo

之後我們就先借看一下在 ingress 章節有使用過的 yaml 檔們。

deployment.yaml

apiVersion: extensions/v1beta1
 kind: Deployment
 metadata:
   name: blue-nginx
 spec:
   replicas: 2
   template:
     metadata:
       labels:
         app: blue-nginx
     spec:
       containers:
         - name: nginx
           image: hcwxd/blue-whale
           ports:
             - containerPort: 3000

service.yaml

apiVersion: v1
 kind: Service
 metadata:
   name: blue-service
 spec:
   type: NodePort
   selector:
     app: blue-nginx
   ports:
     - protocol: TCP
       port: 80
       targetPort: 3000

ingress.yaml

apiVersion: extensions/v1beta1
 kind: Ingress
 metadata:
   name: web
 spec:
   rules:
     - host: blue.demo.com
       http:
         paths:
           - backend:
               serviceName: blue-service
               servicePort: 80

然後我們就可以嘗試來把上述 yaml 檔中可以作為參數的部分抽取出來,在這邊為了降低複雜度,我們只簡單挑幾個參數出來,然後我們就可以把這些參數寫到 values.yaml 中。

values.yaml

replicaCount: 2image:
   repository: hcwxd/blue-whale
 ​
 service:
   type: NodePort
   port: 80ingress:
   enabled: truehosts:
     - host: blue.demo.com
       paths: [/]

把參數提取出來後,我們就來依樣畫葫蘆地把 template 中其他三個 yaml 檔寫成可以接受參數的方式:

deployment.yaml

apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: {{ include "value-helm-demo.fullname" . }}
 spec:
   replicas: {{ .Values.replicaCount }}
   selector:
     matchLabels:
       app: {{ include "value-helm-demo.fullname" . }}
   template:
     metadata:
       labels:
         app: {{ include "value-helm-demo.fullname" . }}
     spec:
       containers:
         - name: {{ .Chart.Name }}
           image: '{{ .Values.image.repository }}'
           ports:
             - containerPort: 3000

service.yaml

apiVersion: v1
 kind: Service
 metadata:
   name: {{ include "value-helm-demo.fullname" . }}
 spec:
   type: {{ .Values.service.type }}
   ports:
     - port: {{ .Values.service.port }}
       targetPort: 3000
       protocol: TCP
   selector:
     app: {{ include "value-helm-demo.fullname" . }}

ingress.yaml

{{- if .Values.ingress.enabled -}}
 {{- $fullName := include "value-helm-demo.fullname" . -}}
 apiVersion: extensions/v1beta1
 kind: Ingress
 metadata:
   name: {{ $fullName }}
 spec:
   rules:
   {{- range .Values.ingress.hosts }}
     - host: {{ .host | quote }}
       http:
         paths:
         {{- range .paths }}
           - backend:
               serviceName: {{ $fullName }}
               servicePort: 80
         {{- end }}
   {{- end }}
 {{- end }}

寫好後,我們就可以來一鍵部署我們的這三份檔案囉。我們可以直接在 /helm-demo 資料夾下輸入指令

helm install .

NAME:   gilded-peacock
LAST DEPLOYED: Mon May  6 16:31:27 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME                      READY  UP-TO-DATE  AVAILABLE  AGE
gilded-peacock-helm-demo  0/2    2           0          0s

==> v1/Pod(related)
NAME                                READY STATUS          RESTARTS
gilded-peacock-helm-demo-5fc5964759 0/1   ContainerCreating  0
gilded-peacock-helm-demo-5fc5964759 0/1   ContainerCreating  0

==> v1/Service
NAME                      TYPE      CLUSTER-IP     EXTERNAL-IP  PORT(S)
gilded-peacock-helm-demo  NodePort  10.106.164.53  <none>       80:30333/TCP

==> v1beta1/Ingress
NAME                      HOSTS          ADDRESS  PORTS
gilded-peacock-helm-demo  blue.demo.com  80       0s

NOTES:
1. Get the application URL by running these commands:
  http://blue.demo.com/

部署成功後顯示的 NAME: gilded-peacock 就是這個 Chart 部署後的名稱囉(在 Helm 中稱部署出去的這個實體為 release)。我們可以再透過指令

helm list

列出我們目前所有的 releases。接下來我們可以用 kubectl get all 來看到我們目前的 kubernetes 狀況

NAME                                    READY STATUS  RESTARTS
pod/gilded-peacock-helm-demo-5fc5964759 1/1   Running 0
pod/gilded-peacock-helm-demo-5fc5964759 1/1   Running 0

NAME                               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)
service/gilded-peacock-helm-demo   NodePort    10.106.164.53   <none>        80:30333/TCP

NAME                                     READY UP-TO-DATE AVAILABLE
deployment.apps/gilded-peacock-helm-demo 2/2   2          2

NAME                                                DESIRED CURRENT
replicaset.apps/gilded-peacock-helm-demo-5fc5964759 2       2

這邊就可以看到我們所指定的資源都有按照 chart 的配置建立起來囉,所以打開 blue.demo.com 就可以看到一隻我們透過 Helm 實際部署出的小鯨魚。

以上,我們就完成 Helm 的實際部署囉!

而其他常用的 Helm 指令還有:

helm delete --purge RELEASE_NAME

刪除一個 release(--purge 這個 flag 可以把該 RELEASE_NAME 釋放出來供之後重複使用)。

helm upgrade RELEASE_NAME CHART_PATH

如果有更新 Chart 的檔案時,可以透過 upgrade 去更新對應的 Release。

helm lint CHART_PATH

檢查你的 Chart 檔案有沒有錯誤的語法。

helm package CHART_PATH

打包並壓縮整個 Chart 資料夾的檔案。

kubectl 額外補充

簡寫

覺得每次下指令都要打 kubectl 很花時間的話,可以透過 alias 來節省時間,例如設定 alias kbs=kubectl

kubectl 中的各項資源的名稱其實也都有內建的簡寫,可以透過指令

kubectl api-resources

去看到各個資源的簡寫,例如 deployments 可以簡寫成 deploy、services 簡寫成 svc 等。

auto-complete

覺得 kubectl 的指令沒有 auto-complete 很痛苦的話可以參考官網的教學。像是如果使用 zsh 的話,就可以透過指令

echo "if [ $commands[kubectl] ]; then source <(kubectl completion zsh); fi" >> ~/.zshrc

來啟用 kubectl 的 auto-complete

create vs apply

在之前提到透過 yaml 建立資源時,我們都用了 kubectl create -f。但其實也可以使用 kubectl apply -f 達成建立與更新資源,雖然在單純建立的使用情景上沒有差別,但其它用法上的差別可見 kubectl apply vs kubectl create

小結

呼!希望這三篇 Kubernetes 基礎教學能對你有幫助!再次溫故知新一下:

在系列文的第一篇文章中,我們了解了構成 Kubernetes 的四個重要元素:Pod、Node、Master、Cluster,並安裝好了我們要實際動手玩 Kubernetes 前需要的套件與工具。

而在第二篇文章中,我們實際動手操作了 Kubernetes 中的 Pod、Service、Deployment、Ingress。

在最後的這篇文章中,我們了解了讓 Kubernetes 部署變得好輕鬆好棒棒的工具 Helm,並實際透過 Helm 部署了一個 Helm。

在學會了上述的各個基礎後,如果想要實際在各個雲端服務上操作 Kubernetes 的話,歡迎接下來可以進一步去了解 Kops

參考資料:


Discuss this article on: Twitter | Facebook.
To get updates when I write, sign up my newsletter below:

You might also like