Helm 從入門到實踐


Helm 是 Kubernetes 的軟件包管理工具臀栈。本文需要讀者對 Docker梭灿、Kubernetes 等相關知識有一定的了解咽白。 本文將介紹 Helm 中的相關概念和基本工作原理祥绞,并通過一些簡單的示例來演示如何使用Helm來安裝、升級未状、回滾一個 Kubernetes 應用俯画。

Helm 是什么?司草?

Helm 是 Kubernetes 的包管理器艰垂。包管理器類似于我們在 Ubuntu 中使用的apt、Centos中使用的yum 或者Python中的 pip 一樣翻伺,能快速查找材泄、下載和安裝軟件包。Helm 由客戶端組件 helm 和服務端組件 Tiller 組成, 能夠將一組K8S資源打包統(tǒng)一管理, 是查找吨岭、共享和使用為Kubernetes構建的軟件的最佳方式拉宗。

Helm 解決了什么痛點?

在 Kubernetes中部署一個可以使用的應用辣辫,需要涉及到很多的 Kubernetes 資源的共同協(xié)作旦事。比如你安裝一個 WordPress 博客,用到了一些 Kubernetes (下面全部簡稱k8s)的一些資源對象急灭,包括 Deployment 用于部署應用姐浮、Service 提供服務發(fā)現(xiàn)、Secret 配置 WordPress 的用戶名和密碼葬馋,可能還需要 pv 和 pvc 來提供持久化服務卖鲤。并且 WordPress 數(shù)據是存儲在mariadb里面的,所以需要 mariadb 啟動就緒后才能啟動 WordPress畴嘶。這些 k8s 資源過于分散蛋逾,不方便進行管理,直接通過 kubectl 來管理一個應用窗悯,你會發(fā)現(xiàn)這十分蛋疼区匣。
所以總結以上,我們在 k8s 中部署一個應用蒋院,通常面臨以下幾個問題:

  • 如何統(tǒng)一管理亏钩、配置和更新這些分散的 k8s 的應用資源文件
  • 如何分發(fā)和復用一套應用模板
  • 如何將應用的一系列資源當做一個軟件包管理

Helm 相關組件及概念

Helm 包含兩個組件,分別是 helm 客戶端 和 Tiller 服務器:

  • helm 是一個命令行工具欺旧,用于本地開發(fā)及管理chart姑丑,chart倉庫管理等
  • Tiller 是 Helm 的服務端。Tiller 負責接收 Helm 的請求辞友,與 k8s 的 apiserver 交互栅哀,根據chart 來生成一個 release 并管理 release
  • chart Helm的打包格式叫做chart,所謂chart就是一系列文件, 它描述了一組相關的 k8s 集群資源
  • release 使用 helm install 命令在 Kubernetes 集群中部署的 Chart 稱為 Release
  • Repoistory Helm chart 的倉庫,Helm 客戶端通過 HTTP 協(xié)議來訪問存儲庫中 chart 的索引文件和壓縮包

Helm 原理

下面兩張圖描述了 Helm 的幾個關鍵組件 Helm(客戶端)昌屉、Tiller(服務器)、Repository(Chart 軟件倉庫)茵瀑、Chart(軟件包)之間的關系以及它們之間如何通信


helm 組件通信
helm 架構

創(chuàng)建release

  • helm 客戶端從指定的目錄或本地tar文件或遠程repo倉庫解析出chart的結構信息
  • helm 客戶端指定的 chart 結構和 values 信息通過 gRPC 傳遞給 Tiller
  • Tiller 服務端根據 chart 和 values 生成一個 release
  • Tiller 將install release請求直接傳遞給 kube-apiserver

刪除release

  • helm 客戶端從指定的目錄或本地tar文件或遠程repo倉庫解析出chart的結構信息
  • helm 客戶端指定的 chart 結構和 values 信息通過 gRPC 傳遞給 Tiller
  • Tiller 服務端根據 chart 和 values 生成一個 release
  • Tiller 將delete release請求直接傳遞給 kube-apiserver

更新release

  • helm 客戶端將需要更新的 chart 的 release 名稱 chart 結構和 value 信息傳給 Tiller
  • Tiller 將收到的信息生成新的 release间驮,并同時更新這個 release 的 history
  • Tiller 將新的 release 傳遞給 kube-apiserver 進行更新

chart 的基本結構

Helm的打包格式叫做chart,所謂chart就是一系列文件, 它描述了一組相關的 k8s 集群資源马昨。Chart中的文件安裝特定的目錄結構組織, 最簡單的chart 目錄如下所示:


chart 結構
  • charts 目錄存放依賴的chart
  • Chart.yaml 包含Chart的基本信息竞帽,包括chart版本,名稱等
  • templates 目錄下存放應用一系列 k8s 資源的 yaml 模板
  • _helpers.tpl 此文件中定義一些可重用的模板片斷鸿捧,此文件中的定義在任何資源定義模板中可用
  • NOTES.txt 介紹chart 部署后的幫助信息屹篓,如何使用chart等
  • values.yaml 包含了必要的值定義(默認值), 用于存儲 templates 目錄中模板文件中用到變量的值

安裝Helm

Helm 提供了幾種安裝方式,本文提供兩種安裝方式匙奴,想要查看更多安裝方式堆巧,請閱讀 Helm 的官方文檔

  • 手動安裝方式
$ 下載 Helm 二進制文件
$ wget https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-linux-amd64.tar.gz
$ 解壓縮
$ tar -zxvf helm-v2.9.1-linux-amd64.tar.gz
$ 復制 helm 二進制 到bin目錄下
$cp linux-amd64/helm /usr/local/bin/

  • 使用官方提供的腳本一鍵安裝
$ curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh
$ chmod 700 get_helm.sh
$ ./get_helm.sh

你還可以通過 Helm 的 github 項目下找到你想要的 Helm 版本的二進制,然后通過手動安裝方式一樣安裝即可

安裝 Tiller

安裝好 helm 客戶端后泼菌,就可以通過以下命令將 Tiller 安裝在 kubernetes 集群中:

helm init

這個地方默認使用 “https://kubernetes-charts.storage.googleapis.com” 作為缺省的 stable repository 的地址谍肤,但由于國內有一張無形的墻的存在,googleapis.com 是不能訪問的哗伯』拇В可以使用阿里云的源來配置:

helm init --upgrade -i registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.9.1  --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts

執(zhí)行上面命令后,可以通過 kubectl get po -n kube-system 來查看 tiller 的安裝情況焊刹。

由于 kubernetes 從1.6 版本開始加入了 RBAC 授權系任。當前的 Tiller 沒有定義用于授權的 ServiceAccount, 訪問 API Server 時會被拒絕虐块,需要給 Tiller 加入授權俩滥。

  • 創(chuàng)建 Kubernetes 的服務帳號和綁定角色
$ kubectl create serviceaccount --namespace kube-system tiller                               
serviceaccount "tiller" created

$ kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
clusterrolebinding.rbac.authorization.k8s.io "tiller-cluster-rule" created
  • 給 Tiller 的 deployments 添加剛才創(chuàng)建的 ServiceAccount
# 給 Tiller 的 deployments 添加剛才創(chuàng)建的 ServiceAccount
$ kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
deployment.extensions "tiller-deploy" patched
  • 查看 Tiller deployments 資源是否綁定 ServiceAccount
$ kubectl get deploy -n kube-system tiller-deploy -o yaml | grep serviceAccount
serviceAccount: tiller
serviceAccountName: tiller

  • 查看 Tiller 是否安裝成功
$ helm version 
Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}

安裝成功后,即可使用 helm install xxx 來安裝 helm 應用非凌。如果需要刪除 Tiller举农,可以通過 kubectl delete deployment tiller-deploy --namespace kube-system 來刪除 Tiller 的 deployment 或者使用 helm reset 來刪除。

使用 Helm 操作 Chart

這一節(jié)將介紹如何使用 helm 來操作 chart敞嗡,包括創(chuàng)建颁糟、刪除、打包喉悴、安裝等使用棱貌。

先介紹一下 Helm 的核心命令:

  • helm create 創(chuàng)建一個 Chart 模板
$ helm create test
Creating test
  • helm package 打包一個 Chart 模板
$ helm package test                                                                          
Successfully packaged chart and saved it to: /root/test-0.1.0.tgz
  • helm search 查找可用的 Chart 模板
$ helm search nginx                                  
NAME                    CHART VERSION   APP VERSION DESCRIPTION
stable/nginx-ingress    0.9.5           0.10.2      An nginx Ingress controller that uses ConfigMap...
stable/nginx-lego       0.3.1                       Chart for nginx-ingress-controller and kube-lego
stable/gcloud-endpoints 0.1.0                       Develop, deploy, protect and monitor your APIs ...
  • helm inspect 查看指定 Chart 的基本信息
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: test
version: 0.1.0

略...(省略一大段信息)

  • helm install 根據指定的 Chart 部署一個 Release 到 Kubernetes 集群

Chart 模板示例

Chart 文件結構

wordpress
├── charts
├── Chart.yaml
├── README.md
├── requirements.lock
├── requirements.yaml
├── templates
│   ├── deployment.yaml
│   ├── externaldb-secrets.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── pvc.yaml
│   ├── secrets.yaml
│   ├── svc.yaml
│   └── tls-secrets.yaml
└── values.yaml

一個 wordpress chart 如上(去除部分 test 和 charts 依賴), 基本結構由以下幾個部分組成:

  • charts 存放子Chart (Subchart) 的定義箕肃,Subchart 指的是當前 Chart 依賴的 Chart 婚脱, 在 requirements.yaml 中定義
  • Chart.yaml 包含 Chart 信息的 YAML 文件, 包括 Chart 的版本、名稱等障贸,在 DCE Helm 插件中還包含 Chart 的 團隊授權 信息 和 是否公開 的信息
  • README.md 可選:Chart 的介紹信息等(該文件對于一個大型 Chart 來說十分重要)
  • Requirements.yaml 可選:列舉當前 Chart 的需要依賴的 Chart
  • templates
    • 該目錄下存放 Chart 所有的 K8s 資源定義模板错森,通常不同的資源放在不同的文件中,DCE Helm 插件中自定義模板的 K8s 資源統(tǒng)一放在 all_sources.yaml 文件中
    • _helpers.tpl 篮洁, 通常這個文件存放可重用的模板片段涩维,該文件中的定義可以在 Chart 其它資源定義模板中使用
    • NOTES.txt,可選:一段簡短使用說明的文本文件袁波,用于安裝 Release 后提示用戶使用
  • values.yaml 當前 Chart 的默認配置的值

編寫一個簡單的 Chart 示例

本節(jié)以構建一個名稱為 nginx-test Chart 為示例瓦阐,來描述一個 chart 必要條件。
1篷牌、Chart.yaml 文件是 一個 chart 必要文件睡蟋, 該文件可以簡單包括以下字段(具體字段請參考Helm官網)

apiVersion: v1  (chart 的API版本, 總是"v1", 必要)
name: hello     (chart 的名稱, 必要)
version: 0.0.1  (chart 的版本,這個版本必須必要遵循 SemVer 2標準)
description: A Helm chart for Kubernetes   (chart 模板的簡介描述)
...
下面省略一些字段枷颊,默認情況下有這幾個字段定義就可以了

2戳杀、values.yaml 文件是 chart 的必要文件,以 nginx 為示例:


# Default values for test.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1

image:
  repository: nginx
  tag: stable
  pullPolicy: IfNotPresent
service:
  type: ClusterIP
  port: 80

ingress:
  enabled: false
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  path: /
  hosts:
    - chart-example.local
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

resources: {}
  # We usually recommend not to specify default resources and to leave this as a conscious
  # choice for the user. This also increases chances charts run on environments with little
  # resources, such as Minikube. If you do want to specify resources, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  # limits:
  #  cpu: 100m
  #  memory: 128Mi
  # requests:
  #  cpu: 100m
  #  memory: 128Mi

nodeSelector: {}

tolerations: []

affinity: {}

從示例中可以看出偷卧,values.yaml 中定義了一些當前chart 的一些默認值豺瘤,用于 templates 下的 K8s 資源 yaml 渲染時填充默認值。不過需要注意的是听诸,如果使用 helm install 來部署一個 Release , 可以通過下面命令指定一份yaml 文件作為填充值:

$ helm install --values=myvals.yaml nginx

3坐求、創(chuàng)建 templates 下的模板文件, 用于生成 Kubernetes 資源清單(manifests) 如下所示:

# nginx-test/templates/deployments.yaml 
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: {{ template "nginx-test.fullname" . }}
  labels:
    app: {{ template "nginx-test.name" . }}
    chart: {{ template "nginx-test.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ template "nginx-test.name" . }}
      release: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app: {{ template "nginx-test.name" . }}
        release: {{ .Release.Name }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
{{ toYaml .Values.resources | indent 12 }}
    {{- with .Values.nodeSelector }}
      nodeSelector:
{{ toYaml . | indent 8 }}
    {{- end }}
    {{- with .Values.affinity }}
      affinity:
{{ toYaml . | indent 8 }}
    {{- end }}
    {{- with .Values.tolerations }}
      tolerations:
{{ toYaml . | indent 8 }}
    {{- end }}
    
# nginx-test/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ template "nginx-test.fullname" . }}
  labels:
    app: {{ template "nginx-test.name" . }}
    chart: {{ template "nginx-test.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http 
      protocol: TCP
      name: http
  selector:
    app: {{ template "nginx-test.name" . }}
    release: {{ .Release.Name }}

上面定義了 一個 deployments.yaml 和 service.yaml 資源文件晌梨,里面使用 {{ }} 符號的是 Go 模板語言的標準桥嗤。其中可以通過:

  • .Values 對象訪問 values.yaml 文件的內容, 前面的dot(.) 表示從頂層命名空間開始仔蝌,找到 Values 對象(下同)
  • .Release泛领、.Chart 開頭的預定義值可用于任何的模板中
  • .Chart 對象用來訪問 Chart.yaml 文件的內容
  • .Release 對象是 Helm的內置對象之一, 使用 Helm 安裝一個 release 時敛惊,由 Tiller 分配 release 的名稱

4渊鞋、命名模板(_helper.tpl) :可以從上面看到有 {{ template "nginx-test.fullname" . }} 定義。該定義由 _helper.tpl 文件定義的字段來實現(xiàn)瞧挤,比如下面一個 _helper.tpl :

{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "nginx-test.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "nginx-test.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "nginx-test.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}

該模板定義了 "nginx-test.name"锡宋、"nginx-test.fullname"、"nginx-test.chart" 等可重用模板部分特恬,當模板引擎讀取該文件時执俩,它存儲對 nginx-test.name等的引用, 直到調用 template "nginx-test.name" 為止癌刽。然后把值渲染到模板中役首。

注意 {{ template "nginx-test.chart" . }} 后面有個dot(.)尝丐,這是因為一個已命名的模板(用于創(chuàng)建 define) 被渲染時,它將接收由該 template 調用傳入的范圍(scope)衡奥。沒有范圍傳入爹袁,在模板中無法訪問任何內容,因此在:

{{- define "nginx-test.chart" -}}
這里面的 .Chart 將無法訪問矮固,導致在模板中無法看到內容呢簸,因為這里值為空
{{- end -}}

因此在模板中將 范圍(scope) 傳入即可正常使用:

# nginx-test/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ template "nginx-test.fullname" . }}
  在末尾傳遞了 . 這樣就可以使用 .Values 或者 .Chart 或其它范圍(scope)

5、Chart 依賴(requirements.yaml):比如 WordPress Chart 依賴于 mariadb Chart乏屯, 下面是 WordPress 的依賴(requirements.yaml):

dependencies:
- name: mariadb
  version: 5.x.x
  repository: https://kubernetes-charts.storage.googleapis.com/
  condition: mariadb.enabled
  tags:
    - wordpress-database

該文件列舉當前 Chart 所有的 依賴(subchart)。有幾個字段是必要的:

  • name: 依賴 Chart 的名稱(必要)
  • version: 依賴 Chart 的版本號(必要)
  • repository: 依賴 Chart 的存儲庫完整URL瘦赫,必須通過 helm repo add 添加 repository(存儲庫)到本地
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末辰晕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子确虱,更是在濱河造成了極大的恐慌含友,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件校辩,死亡現(xiàn)場離奇詭異窘问,居然都是意外死亡,警方通過查閱死者的電腦和手機宜咒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門惠赫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來住练,“玉大人铃在,你說我怎么就攤上這事⌒灾茫” “怎么了场晶?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵混埠,是天一觀的道長。 經常有香客問我诗轻,道長钳宪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任扳炬,我火速辦了婚禮吏颖,結果婚禮上,老公的妹妹穿的比我還像新娘鞠柄。我一直安慰自己侦高,他們只是感情好,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布厌杜。 她就那樣靜靜地躺著奉呛,像睡著了一般计螺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瞧壮,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天登馒,我揣著相機與錄音,去河邊找鬼咆槽。 笑死陈轿,一個胖子當著我的面吹牛,可吹牛的內容都是我干的秦忿。 我是一名探鬼主播麦射,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼灯谣!你這毒婦竟也來了潜秋?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤胎许,失蹤者是張志新(化名)和其女友劉穎峻呛,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辜窑,經...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡钩述,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了穆碎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牙勘。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖所禀,靈堂內的尸體忽然破棺而出谜悟,到底是詐尸還是另有隱情,我是刑警寧澤北秽,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布葡幸,位于F島的核電站,受9級特大地震影響贺氓,放射性物質發(fā)生泄漏蔚叨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一辙培、第九天 我趴在偏房一處隱蔽的房頂上張望蔑水。 院中可真熱鬧,春花似錦扬蕊、人聲如沸搀别。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽歇父。三九已至蒂培,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間榜苫,已是汗流浹背护戳。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留垂睬,地道東北人媳荒。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像驹饺,于是被迫代替她去往敵國和親钳枕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內容