Helm教程

1.概述

Helm是k8s的包管理工具,相似Linux系統經常使用的 apt、yum等包管理工具。html

使用helm能夠簡化k8s應用部署前端

2.基本概念

  • Chart:一個 Helm 包,其中包含了運行一個應用所須要的鏡像、依賴和資源定義等,還可能包含 Kubernetes 集羣中的服務定義,相似 Homebrew 中的 formula、APT 的 dpkg 或者 Yum 的 rpm 文件。
  • Release:在 Kubernetes 集羣上運行的 Chart 的一個實例。在同一個集羣上,一個 Chart 能夠安裝不少次。每次安裝都會建立一個新的 release。例如一個 MySQL Chart,若是想在服務器上運行兩個數據庫,就能夠把這個 Chart 安裝兩次。每次安裝都會生成本身的 Release,會有本身的 Release 名稱。
  • Repository:用於發佈和存儲 Chart 的存儲庫。

3.架構

Chart Install 過程:linux

  1. Helm從指定的目錄或者tgz文件中解析出Chart結構信息
  2. Helm將指定的Chart結構和Values信息經過gRPC傳遞給Tiller
  3. Tiller根據Chart和Values生成一個Release
  4. Tiller將Release發送給Kubernetes運行。


Chart Update過程:git

  1. Helm從指定的目錄或者tgz文件中解析出Chart結構信息
  2. Helm將要更新的Release的名稱和Chart結構,Values信息傳遞給Tiller
  3. Tiller生成Release並更新指定名稱的Release的History
  4. Tiller將Release發送給Kubernetes運行

4.安裝helm

helm主要包括helm客戶端和Tiller服務端兩部分,Tiller部署在k8s集羣中。github

ps: 若是使用阿里雲容器服務kubernetes版,默認已經安裝了helm的服務端(Tiller),只要安裝helm客戶端便可。docker

能夠根據本身的環境從github地址下載對應的安裝包:shell

下載地址:https://github.com/helm/helm/releases數據庫

下載後解壓到本身喜歡的目錄,而後配置下對應的PATH環境變量。json

 

默認狀況helm操做k8s集羣,須要藉助kubectl命令的集羣配置,能夠參考這裏配置kubectl命令-(k8s應用配置詳解),固然也能夠直接給helm命令指定--kubeconfig 參數指定k8s集羣證書路徑。windows

 
#這是經過--kubeconfig參數指定k8s證書的方式操做k8s集羣
#下面命令是部署一個名字叫app-demo的應用,helm包在./chart目錄中
/alidata/server/helm-v2.13.1/helm --kubeconfig ./config/k8s.conf install app-demo ./chart

 

安裝服務端:

使用helm init 命令,能夠一鍵安裝。

 

ps: 關於chart倉庫(Repository),經過helm命令:helm serve 就能夠啓動倉庫服務,可是一般不少時候咱們每一個項目本身的chart包都跟着源碼一塊兒提交到git倉庫,因此這裏的chart倉庫不是必須的。

5.基本用法

這裏以製做一個簡單的網站應用chart包爲例子介紹helm的基本用法。

ps: 這裏跳過docker鏡像製做過程,鏡像製做能夠參考:Docker基礎教程

5.1.建立chart包

經過helm create命令建立一個新的chart包

例子:

#在當前目錄建立一個myapp chart包

$ helm create myapp

 

建立完成後,獲得的目錄結構以下:

myapp                                   - chart 包目錄名
├── charts                              - 依賴的子包目錄,裏面能夠包含多個依賴的chart包
├── Chart.yaml                          - chart定義,能夠定義chart的名字,版本號信息。
├── templates                           - k8s配置模版目錄, 咱們編寫的k8s配置都在這個目錄, 除了NOTES.txt和下劃線開頭命名的文件,其餘文件能夠隨意命名。
│   ├── deployment.yaml
│   ├── _helpers.tpl                    - 下劃線開頭的文件,helm視爲公共庫定義文件,主要用於定義通用的子模版、函數等,helm不會將這些公共庫文件的渲染結果提交給k8s處理。
│   ├── ingress.yaml
│   ├── NOTES.txt                       - chart包的幫助信息文件,執行helm install命令安裝成功後會輸出這個文件的內容。
│   └── service.yaml
└── values.yaml                         - chart包的參數配置文件,模版能夠引用這裏參數。

 

咱們要在k8s中部署一個網站應用,須要編寫deployment、service、ingress三個配置文件,剛纔經過helm create命令已經建立好了。

5.2.編寫k8s應用部署配置文件

爲了演示chart包模版的用法,咱們先把deployment、service、ingress三個配置文件的內容清空,從新編寫k8s部署文件。

deployment.yaml 配置文件定義以下:

 
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: myapp           #deployment應用名
  labels:
    app: myapp          #deployment應用標籤訂義
spec:
  replicas: 1           #pod副本數
  selector:
    matchLabels:
      app: myapp          #pod選擇器標籤
  template:
    metadata:
      labels:
        app: myapp          #pod標籤訂義
    spec:
      containers:
        - name: myapp           #容器名
          image: xxxxxx:1.7.9    #鏡像地址
          ports:
            - name: http
              containerPort: 80
              protocol: TCP

 

service.yaml定義以下:

apiVersion: v1
kind: Service
metadata:
  name: myapp-svc #服務名
spec:
  selector: #pod選擇器定義
    app: myapp
  ports:
  - protocol: TCP 
    port: 80
    targetPort: 80

 

ingress.yaml定義以下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myapp-ingress #ingress應用名
spec:
  rules:
    - host: www.xxxxx.com  #域名
      http:
        paths: 
          - path: /  
            backend: 
              serviceName: myapp-svc #服務名
              servicePort: 80

 

5.3.提取k8s應用部署配置文件中的參數,做爲chart包參數。

上面已經完成k8s應用部署配置文件的編寫。

爲何要提取上面配置文件中的參數,做爲chart包的參數?

思考下面的問題:

咱們製做好一個chart包以後,如實現chart包更具備通用性,咱們如何換域名?換鏡像地址?改一下應用部署的名字?  部署多套環境(例如:dev環境、test環境分別以不一樣的應用名字部署一套)

 

5.2定義的k8s配置文件還不能稱之爲模版,都是固定的配置。(這裏所說的模版就相似你們平時作前端開發的時候用的模版技術是一個概念)

咱們經過提取配置中的參數注入模版變量,模版表達式將配置文件轉化爲模版文件,helm在運行的時候根據參數動態的將模版文件渲染成最終的配置文件。

 

下面將deployment、service、ingress三個配置文件轉換成模版文件。

ps:  {{  }} 兩個花括號包裹的內容爲模版表達式,具體含義,後面會說明,這裏不用理會。

 

deployment.yaml 配置模版以下:

 
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: {{ .Release.Name }}  #deployment應用名
  labels:
    app: {{ .Release.Name }}          #deployment應用標籤訂義
spec:
  replicas: {{ .Values.replicas}}           #pod副本數
  selector:
    matchLabels:
      app: {{ .Release.Name }}          #pod選擇器標籤
  template:
    metadata:
      labels:
        app: {{ .Release.Name }}          #pod標籤訂義
    spec:
      containers:
        - name: {{ .Release.Name }}           #容器名
          image: {{ .Values.image }}:{{ .Values.imageTag }}    #鏡像地址
          ports:
            - name: http
              containerPort: 80
              protocol: TCP

 

service.yaml定義以下:

apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}-svc #服務名
spec:
  selector: #pod選擇器定義
    app: {{ .Release.Name }}
  ports:
  - protocol: TCP 
    port: 80
    targetPort: 80

 

ingress.yaml定義以下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ .Release.Name }}-ingress #ingress應用名
spec:
  rules:
    - host: {{ .Values.host }}  #域名
      http:
        paths: 
          - path: /  
            backend: 
              serviceName: {{ .Release.Name }}-svc #服務名
              servicePort: 80

 

values.yaml chart包參數定義:

#域名
host: www.XXX.com
 
#鏡像參數
image: XXXXXXXXXXXXXXXXXX
imageTag: 1.7.9
 
#pod 副本數
replicas:1

 

5.4.經過helm命令安裝/更新應用

安裝應用:

#命令格式: helm install  chart包目錄

$ helm install ./myapp

 

經過命令注入參數

#命令格式: helm install  --set key=value   chart包目錄

#–set 參數能夠指定多個參數,他的值會覆蓋values.yaml定義的值,對象類型數據能夠用 . (點)分割屬性名,例子:  --set apiAppResources.requests.cpu=1

$ helm install     \

--set replicas=2   \

--set host=www.xxxx.com \

 ./myapp

 

更新應用:

#命令格式: helm upgrade release名字  chart包目錄

$ helm upgrade myapp ./myapp

 

#也能夠指定–set參數

$ helm upgrade      \

--set replicas=2   \

--set host=www.xxxx.com \

 myapp ./myapp

 

#默認狀況下,若是release名字不存在,upgrade會失敗,能夠加上-i 參數當release不存在的時候則安裝,存在則更新,將install和uprade命令合併。

$ helm upgrade  -i    \

--set replicas=2   \

--set host=www.xxxx.com \

 myapp ./myapp

 

6.模版語法

6.1.表達式

模版表達式: {{ 模版表達式 }}

模版表達式: {{- 模版表達式 -}} , 表示去掉表達式輸出結果前面和後面的空格,去掉前面空格能夠這麼寫{{- 模版表達式 }}, 去掉後面空格 {{ 模版表達式 -}}

6.2.變量

默認狀況點( . ), 表明全局做用域,用於引用全局對象。

例子:

#這裏引用了全局做用域下的Values對象中的key屬性。 

{{ .Values.key }}

 

helm全局做用域中有兩個重要的全局對象:Values和Release

Values表明的就是values.yaml定義的參數,經過.Values能夠引用任意參數。

例子:

{{ .Values.replicaCount }}

#引用嵌套對象例子,跟引用json嵌套對象相似

{{ .Values.image.repository }}

 

Release表明一次應用發佈,下面是Release對象包含的屬性字段:

  • Release.Name   - release的名字,通常經過Chart.yaml定義,或者經過helm命令在安裝應用的時候指定。
  • Release.Time    - release安裝時間
  • Release.Namespace    - k8s名字空間
  • Release.Revision      - release版本號,是一個遞增值,每次更新都會加一
  • Release.IsUpgrade   - true表明,當前release是一次更新.
  • Release.IsInstall       - true表明,當前release是一次安裝

例子:

{{ .Release.Name }}

 

除了系統自帶的變量,咱們本身也能夠自定義模版變量。

#變量名以$開始命名, 賦值運算符是 := (冒號+等號)

{{- $relname := .Release.Name -}}

 

引用自定義變量:

#不須要 . 引用

{{ $relname }}

6.3.函數&管道運算符

調用函數的語法:{{ functionName arg1 arg2... }}

例子:

#調用quote函數,將結果用「」引號包括起來。

{{ quote .Values.favorite.food }}

 

管道(pipelines)運算符 |

相似linux shell命令,經過管道 | 將多個命令串起來,處理模版輸出的內容。

例子:

#將.Values.favorite.food傳遞給quote函數處理,而後在輸出結果。

{{ .Values.favorite.food | quote  }}

#先將.Values.favorite.food的值傳遞給upper函數將字符轉換成大寫,而後專遞給quote加上引號包括起來。

{{ .Values.favorite.food | upper | quote }}

#若是.Values.favorite.food爲空,則使用default定義的默認值

{{ .Values.favorite.food | default "默認值" }}

#將.Values.favorite.food輸出5次

{{ .Values.favorite.food | repeat 5 }}

#對輸出結果縮進2個空格

{{ .Values.favorite.food | nindent 2 }}

 

 

經常使用的關係運算符>、 >=、 <、!=、與或非在helm模版中都以函數的形式實現。

關係運算函數定義:

eq  至關於 =

ne  至關於 !=

lt  至關於 <=

gt  至關於 >=

and  至關於 &&

or   至關於 ||

not  至關於 !

例子:

#至關於 if (.Values.fooString && (.Values.fooString == "foo"))

{{ if and .Values.fooString (eq .Values.fooString "foo") }}
    {{ ... }}
{{ end }}

 

6.4.流程控制語句

6.4.1. IF/ELSE

語法:

{{ if 條件表達式 }}
# Do something
{{ else if 條件表達式 }}
# Do something else
{{ else }}
# Default case
{{ end }}

 

例子:

 
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {{ .Values.favorite.drink | default "tea" | quote }}
  food: {{ .Values.favorite.food | upper | quote }}
  {{if eq .Values.favorite.drink "coffee"}}
    mug: true
  {{end}}

 

6.4.2. with

with主要就是用來修改 . 做用域的,默認 . 表明全局做用域,with語句能夠修改.的含義.

語法:

{{ with 引用的對象 }}
這裏可使用 . (點), 直接引用with指定的對象
{{ end }}

 

例子:

#.Values.favorite是一個object類型

{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}   #至關於.Values.favorite.drink
food: {{ .food | upper | quote }}
{{- end }}

 

ps: 不能在with做用域內使用 . 引用全局對象, 若是非要在with裏面引用全局對象,能夠先在with外面將全局對象複製給一個變量,而後在with內部使用這個變量引用全局對象。

例子:

{{- $release:= .Release.Name -}}   #先將值保存起來

{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}   #至關於.Values.favorite.drink
food: {{ .food | upper | quote }}

release: {{ $release }} #間接引用全局對象的值
{{- end }}

 

6.4.3. range

range主要用於循環遍歷數組類型。

語法1:

#遍歷map類型,用於遍歷鍵值對象

#變量$key表明對象的屬性名,$val表明屬性值

{{- range $key, $val := 鍵值對象 }}
{{ $key }}: {{ $val | quote }}
{{- end}}

 

語法2:

{{- range 數組 }}

{{ . | title | quote }} # . (點),引用數組元素值。

{{- end }}

例子:

 
#values.yaml定義
 
#map類型
favorite:
  drink: coffee
  food: pizza
 
#數組類型
pizzaToppings:
  - mushrooms
  - cheese
  - peppers
  - onions
 
map類型遍歷例子:
{{- range $key, $val := .Values.favorite }}
{{ $key }}: {{ $val | quote }}
{{- end}}
 
數組類型遍歷例子:
{{- range .Values.pizzaToppings}}
{{ . | quote }}
{{- end}}

 

6.5.子模版定義

咱們能夠在_(下劃線)開頭的文件中定義子模版,方便後續複用。

helm create默認爲咱們建立了_helpers.tpl 公共庫定義文件,能夠直接在裏面定義子模版,也能夠新建一個,只要如下劃線開頭命名便可。

子模版語法:

定義模版
{{ define "模版名字" }} 模版內容 {{ end }}

引用模版:
{{ include "模版名字" 做用域}}

例子:

 
#模版定義
{{- define "mychart.app" -}}
app_name: {{ .Chart.Name }}
app_version: "{{ .Chart.Version }}+{{ .Release.Time.Seconds }}"
{{- end -}}
 
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
  labels:
    {{ include "mychart.app" . | nindent 4 }} #引用mychart.app模版內容,並對輸出結果縮進4個空格
data:
  myvalue: "Hello World"

 

6.6.調試

編寫好chart包的模版以後,咱們能夠給helm命令加上--debug --dry-run 兩個參數,讓helm輸出模版結果,可是不把模版輸出結果交給k8s處理

例子:

#helm install命令相似,加上--debug --dry-run兩個參數便可

$ helm upgrade --debug --dry-run -i    \

--set replicas=2   \

--set host=www.xxxx.com \

 myapp ./myapp

相關文章
相關標籤/搜索