Helm是k8s的包管理工具,相似Linux系統經常使用的 apt、yum等包管理工具。html
使用helm能夠簡化k8s應用部署前端
Chart Install 過程:linux
Chart Update過程:git
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倉庫不是必須的。
這裏以製做一個簡單的網站應用chart包爲例子介紹helm的基本用法。
ps: 這裏跳過docker鏡像製做過程,鏡像製做能夠參考:Docker基礎教程
經過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命令已經建立好了。
爲了演示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
上面已經完成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
#域名 host: www.XXX.com #鏡像參數 image: XXXXXXXXXXXXXXXXXX imageTag: 1.7.9 #pod 副本數 replicas:1
安裝應用:
#命令格式: 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
模版表達式: {{ 模版表達式 }}
模版表達式: {{- 模版表達式 -}} , 表示去掉表達式輸出結果前面和後面的空格,去掉前面空格能夠這麼寫{{- 模版表達式 }}, 去掉後面空格 {{ 模版表達式 -}}
默認狀況點( . ), 表明全局做用域,用於引用全局對象。
例子:
#這裏引用了全局做用域下的Values對象中的key屬性。
{{ .Values.key }}
helm全局做用域中有兩個重要的全局對象:Values和Release
Values表明的就是values.yaml定義的參數,經過.Values能夠引用任意參數。
例子:
{{ .Values.replicaCount }}
#引用嵌套對象例子,跟引用json嵌套對象相似
{{ .Values.image.repository }}
Release表明一次應用發佈,下面是Release對象包含的屬性字段:
例子:
{{ .Release.Name }}
除了系統自帶的變量,咱們本身也能夠自定義模版變量。
#變量名以$開始命名, 賦值運算符是 := (冒號+等號)
{{- $relname := .Release.Name -}}
引用自定義變量:
#不須要 . 引用
{{ $relname }}
調用函數的語法:{{ 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 }}
語法:
{{ 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}}
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 }}
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}}
咱們能夠在_(下劃線)開頭的文件中定義子模版,方便後續複用。
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"
編寫好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