Helm 從入門到實踐


一、概述

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(軟件包)之間的關系以及它們之間如何通信

helm 組件通信

 

helm 架構

 

創建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.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

 

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

二、安裝Helm

環境說明

系統 k8s版本 docker ip 主機名 配置 網絡驅動
centos 7.6 1.18.1 19.03.5 192.168.128.130 k8s-master 2核4G flannel
centos 7.6 1.18.1 19.03.5 192.168.128.131 k8s-node01 2核4G flannel
centos 7.6 1.18.1 19.03.5 192.168.128.132 k8s-node02 2核4G flannel

 

 

 

 

 

 

安裝Helm

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

目前最新穩定版為:2.16.6

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

wget https://get.helm.sh/helm-v2.16.6-linux-amd64.tar.gz
tar zxvf helm-v2.16.6-linux-amd64.tar.gz -C /usr/src/
cp /usr/src/linux-amd64/helm /usr/local/bin/

 

安裝 Tiller

由於默認使用 “ https://kubernetes-charts.storage.googleapis.com” 作為缺省的 stable repository 的地址,但由於國內有一張無形的牆的存在, googleapis.com 是不能訪問的。可以使用阿里雲的源來配置
helm init --upgrade -i registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.16.6  --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

# kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
deployment.apps/tiller-deploy patched

 

查看 Tiller deployments 資源是否綁定 ServiceAccount

# kubectl get deploy -n kube-system tiller-deploy -o yaml | grep serviceAccount
            f:serviceAccount: {}
            f:serviceAccountName: {}
      serviceAccount: tiller
      serviceAccountName: tiller

 

查看 Tiller 是否安裝成功

# helm version
Client: &version.Version{SemVer:"v2.16.6", GitCommit:"dd2e5695da88625b190e6b22e9542550ab503a47", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.16.6", GitCommit:"dd2e5695da88625b190e6b22e9542550ab503a47", GitTreeState:"clean"}
安裝成功后,即可使用 helm install xxx 來安裝 helm 應用。
如果需要刪除 Tiller,可以通過 kubectl delete deployment tiller-deploy --namespace kube-system 來刪除 Tiller 的 deployment 或者使用 helm reset 來刪除。
 
 

三、使用 Helm 操作 Chart

這一節將介紹如何使用 helm 來操作 chart,包括創建、刪除、打包、安裝等使用。

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

helm create

創建一個 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 to store ...
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 with Googl...

 

helm inspect

查看指定 Chart 的基本信息

# helm inspect test
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: test
version: 0.1.0
...

 

四、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 資源統一放在 all_sources.yaml 文件中
    • _helpers.tpl , 通常這個文件存放可重用的模板片段,該文件中的定義可以在 Chart 其它資源定義模板中使用
    • NOTES.txt,可選:一段簡短使用說明的文本文件,用於安裝 Release 后提示用戶使用
  • values.yaml 當前 Chart 的默認配置的值

編寫一個簡單的 Chart 示例

本節以構建一個名稱為 nginx-test Chart 為示例,來描述一個 chart 必要條件。

# helm create nginx-test
Creating nginx-test

 

1、Chart.yaml 文件是 一個 chart 必要文件, 該文件可以簡單包括以下字段(具體字段請參考Helm官網)

# cat nginx-test/Chart.yaml 
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: nginx-test
version: 0.1.0

 

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

# cat nginx-test/values.yaml 
# Default values for nginx-test.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

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

注意:上面命令不要復制執行,執行會報錯的。請根據實際情況執行!!!



3、創建 templates 下的模板文件, 用於生成 Kubernetes 資源清單(manifests) 如下所示:

# cat nginx-test/templates/deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "nginx-test.fullname" . }}
  labels:
...

上面定義了 一個 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 文件定義的字段來實現,比如下面一個 _helper.tpl :

# cat nginx-test/templates/_helpers.tpl 
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
...

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

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

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

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

# cat nginx-test/templates/service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: {{ include "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(存儲庫)到本地

 

 

 

本文參考鏈接:

https://www.jianshu.com/p/4bd853a8068b

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM