Helm 是 Kubernetes 的軟件包管理工具。本文需要讀者對 Docker、Kubernetes 等相關知識有一定的瞭解。 本文將介紹 Helm 中的相關概念和基本工作原理,並通過一些簡單的示例來演示如何使用Helm來安裝、升級、回滾一個 Kubernetes 應用。
Helm 是什麼??
Helm 是 Kubernetes 的包管理器。包管理器類似於我們在 Ubuntu 中使用的apt、Centos中使用的yum 或者Python中的 pip 一樣,能快速查找、下載和安裝軟件包。Helm 由客戶端組件 helm 和服務端組件 Tiller 組成, 能夠將一組K8S資源打包統一管理, 是查找、共享和使用爲Kubernetes構建的軟件的最佳方式。
Helm 解決了什麼痛點?
在 Kubernetes中部署一個可以使用的應用,需要涉及到很多的 Kubernetes 資源的共同協作。比如你安裝一個 WordPress 博客,用到了一些 Kubernetes (下面全部簡稱k8s)的一些資源對象,包括 Deployment 用於部署應用、Service 提供服務發現、Secret 配置 WordPress 的用戶名和密碼,可能還需要 pv 和 pvc 來提供持久化服務。並且 WordPress 數據是存儲在mariadb裏面的,所以需要 mariadb 啓動就緒後才能啓動 WordPress。這些 k8s 資源過於分散,不方便進行管理,直接通過 kubectl 來管理一個應用,你會發現這十分蛋疼。
所以總結以上,我們在 k8s 中部署一個應用,通常面臨以下幾個問題:
- 如何統一管理、配置和更新這些分散的 k8s 的應用資源文件
- 如何分發和複用一套應用模板
- 如何將應用的一系列資源當做一個軟件包管理
Helm 相關組件及概念
Helm 包含兩個組件,分別是 helm 客戶端 和 Tiller 服務器:
- helm 是一個命令行工具,用於本地開發及管理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 協議來訪問存儲庫中 chart 的索引文件和壓縮包
Helm 原理
下面兩張圖描述了 Helm 的幾個關鍵組件 Helm(客戶端)、Tiller(服務器)、Repository(Chart 軟件倉庫)、Chart(軟件包)之間的關係以及它們之間如何通信
創建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 目錄如下所示:
- 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
執行上面命令後,可以通過 kubectl get po -n kube-system 來查看 tiller 的安裝情況。
由於 kubernetes 從1.6 版本開始加入了 RBAC 授權。當前的 Tiller 沒有定義用於授權的 ServiceAccount, 訪問 API Server 時會被拒絕,需要給 Tiller 加入授權。
- 創建 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 添加剛纔創建的 ServiceAccount
# 給 Tiller 的 deployments 添加剛纔創建的 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 應用。