Helm / Kubernetes 從無到有使用自己的 image 建立 Service 簡單教學

本文使用 Helm Charts 從無到有,超基礎建立一個簡單的 Kubernetes Service

Published in
10 min readAug 30, 2020

--

前言

本文使用 Helm Charts 從無到有,超基礎建立一個簡單的 Kubernetes ( 使用自己 build 的 image ) Service

如上圖的 Kubernetes 服務,有一個 Front End / Back End 並且使用 helm 自己設定任意的 image 還有 helm 中設定環境變數 ( environment ) 給 pod
本文的範例可以於 x86 / arm 的 minikube 上執行

我們不做 helm / kuberentes 安裝介紹
基本 kuberentes 安裝可以參考本人之前文章 於樹莓派上執行 kubernetes ( 以 minikube 為例)

使用自製 Docker Image

本文使用的 Server Code 於此
https://github.com/Seachaos/kube-demo-request/tree/v0.1.0

使用的 image 於此
https://hub.docker.com/r/seachaos/kube-demo-request

各位如果了解 docker image build 的話可以自行修改,或是使用自己的 docker registry
只要各位確定 Kubernetes 有辦法 pull image 即可
這部分如果有空再另開文章介紹

1. 建立 Helm Charts

此範例中我們會建立三個 charts ,分別為整個服務 (service),前端 (front end),後端 ( back end )

我們先用 helm create 指令建立三個 charts

helm create myserver-frontend
helm create myserver-backend
helm create myserver
helm create 指令建立三個 charts

2. 後端 Server 設定

進入 Helm 幫我們建立的 myserver-backend
此為簡單教學,所以我們不做測試,先將系統測試檔案移除

rm templates/tests/test-connection.yaml

接下來設定 chart 的 image
一個 Helm chart 的設定大多在 values.yaml 中
所以我們在檔案中修改以下設定,先找到

image:
repository: nginx
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""

改成

image:
repository: seachaos/kube-demo-request
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: “v0.1.0”

解說 repository:

這裡的 repository 其實就是 image 的資訊
實務上可以是自己的 docker build 出來的 image 或是 mysql / redis / api server 等等服務
如果沒有 image 的人可以使用本人建立的教學用 image
seachaos/kube-demo-request

解說 tag :

tag 是 image 版本,實務上因為 server 會有不同的版號,這裡如果使用本人的 image, 有提供 x86 與 arm 版本
如果你是在 Kubernetes 樹莓派上執行,輸入”v0.1.0-arm” 即可
如果是 Mac , x86 Linux ( Ubuntu ) 輸入 “v0.1.0” 即可

然後我們要修改 service port, 因為本範例 image 的 port 是 3000, 找到

service:
type: ClusterIP
port: 80

然後修改成

service:
type: ClusterIP
port: 3000

service type 有 ClusterIP 與 NodePort 常用,但是一樣不在本教學範圍就先略過介紹 ( 可參考 https://kubernetes.io/docs/concepts/services-networking/service/ )

values.yalm 修改完成的範例如下

image:
repository: seachaos/kube-demo-request
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: “v0.1.0”
… ( 中略 )
service:
type: ClusterIP
port: 3000

可以參考此處完整範例
https://github.com/Seachaos/helm-tutorial/blob/step-1/myserver-backend/values.yaml#L7
( 裡面的 env 部分請先略過,後面會設定 )

修改 deployment

再來因為 Kubernetes 會持續監控 Pod 健康狀況,所以我們要讓 Kubernetes 知道去哪邊看我們 Service 的狀態(知道我們的 Server 活得很好),不然 Pod 會被認為異常導致一直被重啟

編輯 templates/deployment.yaml
找到


containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: “{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}”
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 80
protocol: TCP
```

其中

ports:
— name: http
containerPort: 80
protocol: TCP

containerPort: 80 即為狀態檢查用的 port
可以直接設定成 3000 ( 我們的 image 使用的 http port ) 或是變數 ( 抓取 values.yaml 中的值,如下 )

ports:
— name: http
containerPort: {{.Values.service.port}}
protocol: TCP

參考檔案 : https://github.com/Seachaos/helm-tutorial/blob/step-1/myserver-backend/templates/deployment.yaml#L40

3. 驗證後端 Server

我們先安裝看看這個 chart , 確認 pod 正常啟動

helm install myback .

然後輸入

kubectl get pods 

觀察 kubernetes 是否正常

觀察看看我們的 backend chart 是否安裝成功

加入 environment ( 環境變數 )

接下來我們可以做 helm 升級 chart 練習並觀察是否成功

我們於 values.yaml 加入 env 設定

env: 
— name: service_name
value: ‘MY-BACKEND’

values.yaml 設定參考
https://github.com/Seachaos/helm-tutorial/blob/step-1/myserver-backend/values.yaml#L13

關於環境變數

這是用來指定我們 server 的名稱,位置等等參數
這是 yaml 陣列格式,詳情可以參考 [Helm | Appendix: YAML Techniques](https://helm.sh/docs/chart_template_guide/yaml_techniques/)

實務上環境變數是相當好用,可以是 database / token / develop / staging / production 等等 server 設定
這部分就是建立 server image 時需要設定的 ( 可以參考本文範例的 code 於此 )

接下來修改 templates/deployment.yaml
於 containers 內 加入

env:
{{- toYaml .Values.env | nindent 12 }}

{{- toYaml .Values.env | nindent 12 }}
意思是 將 values.yaml 中的 env 轉成 yaml 格式且縮排 12 空白 ( yaml 格式 )

例如範例 :


containers:
— name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: “{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}”
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
{{- toYaml .Values.env | nindent 12 }}
ports:
— name: http
containerPort: {{ .Values.service.port }}
protocol: TCP

設定完整參考
https://github.com/Seachaos/helm-tutorial/blob/step-1/myserver-backend/templates/deployment.yaml#L36

然後我們使用以下指令進行 chart 升級

helm upgrade myback .

然後輸入

kubectl get pods 

觀察 kubernetes 是否正常

測試 Server 正常

如果你安裝的 helm install name 也是 myback, 可以直接使用以下指令

export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=myserver-backend,app.kubernetes.io/instance=myback" -o jsonpath="{.items[0].metadata.name}")
kubectl --namespace default port-forward $POD_NAME 3000:3000 --address 0.0.0.0

利用 kubectl 做 port-forward 讓我們透過 3000 port 去存取我們的 back end server

輸入 server 位置 port 3000 ( 例如 192.168.1.1:3000 , localhost: 3000 )
可以看到 server 的資訊

如果一切正常表示我們自製的 helm chart backend server 運作的很好

可以看到 server name 設定正確成功

( 此範例於 Raspberry pi 樹莓派上 minikube 執行 )

有問題歡迎留言分享,或是有想更暸解的地方
接下來 front-end 設定我們下回分曉…

--

--