最近给部门的小伙伴做了一个关于helm的入门介绍,收到了不错的反响,于将资料整理分享给博客的读者们。 本文第一部分介绍helm是做什么的以及能解决什么问题。第二部分介绍helm的核心概念及安装使用helm的教程, 第三部分介绍helm使用的核心即chart的开发,这一章节通过一个示例给大家演示基本的开发步骤。最后一部分, 简单说明如何搭建私有模板仓。在读完后,相信你会对Helm及生态有一个简单的了解。

什么是 helm

如标题所示,官方给Helm的定义是 kubernetes 的包管理器。那么什么是包管理器呢?

什么是包管理工具

包管理器一组软件工具,它们以一致的方式自动安装、升级、配置和删除计算机操作系统的计算机程序 -维基百科
helm 帮助用户管理 kubernetes 程序,helm chart 帮助用户定义、安装和升级最复杂的 Kubernetes 应用程序,Charts 很容易 创建,版本管理,共享和发布,所以停止 copy-and-paste,开始使用 helm -helm 官方

核心概念

helm的官方文档中的描述更加详细,这里只列出一些重要的概念:

Helm Concept 描述 重点
Chart(unpackaged) 一个文件夹的文件,遵循 chart 的准则 可以直接部署到集群
Chart(packaged) 上述文件的压缩包 tar.gz 可以直接部署到集群
Chart name Chart.yaml 定义包的名称 部分标识 chart
Templates 构成应用程序的一组 Kubernetes 清单 Golang 模板引擎
Values 可以在 Kubernetes 清单中参数化的设置 用于 template 渲染
Chart version chart 版本 部分标示 chart
App Version chart 中包含的应用程序版本 与 chart 版本独立
Release kubernetes 集群中部署的 chart 同一个 chart 可能部署多个 release
Release name release 任意名称 独立于 chart name
Release Revision 每次部署/升级应用程序时递增的数字 于 chart 版本无关

helm 发展

  • 每个月超过百万次下载
  • CNCF Incubating project
  • 繁荣的社区

helm 如何使用

helm 安装

helm3剔除了服务 Tiller,直接与kubernetes apiserver通信,所以安装相比helm2更加简单。

1
2
3
4
5
6
7
8

# mac通过homebrew安装
brew install helm

# 二进制文件
wget https://github.com/helm/helm/releases/helm-v3.0.0-linux-amd6
tar -zvxf helm-v3.0.0-linux-amd6
mv linux-amd64/helm /usr/local/bin/helm

对于需要从 Helm2 升级到 helm3 的用户,官方提供了升级插件,我是使用插件进行升级的,没有遇到问题。

chart

chart:一个包含足够信息的 Helm 包,用于将一组 Kubernetes 资源安装到 Kubernetes 集群中。

helm 命令行工具能够自动生成一个 chart 结构:helm create myapp

templates包含了所有所需 kubernetes 各个资源的模板文件,Value.yaml文件存储chart的默认值, 这些值可以通过helm install ,helm upgrade更新,Chart.yaml包含了chart的描述信息,如版本,名称等。 charts目录存储其依赖的第三方chart

安装 Chart

在根据正在运行的 Kubernetes 集群进行身份验证的环境中,使用 Helm 从本地 chart 目录或 chart repo 安装。

使用自定义值

查看 release 状态

查看所有运行的 release

升级 release

回滚 release

移除一个 release

helm chart 如何开发

chart的开发是Helm的核心,也比较复杂。Helm使用Go模板对资源文件进行模板化,除了Go附带的几个内置函数,还添加了许多其他函数。

chart 开发核心特性

以下列举了helm chart开发中几个核心知识点,这里只简单罗列,如果你需要使用,还是建议参考官方文档。

  1. 内置对象:Release,Values,Chart,Files
  2. Values 文件,--set>-f customValue> default file;
  3. 模板函数及流水线:对传入 template 的值进行轻度处理,helm 内置了 60 多个常见函数;
  4. 控制语句的使用;
  5. 变量;
  6. 命名模版;
  7. 访问 templates 中的文件;
  8. 帮助文件 NOTS.Txt 如何编写;
  9. subcharts 与全局变量;
  10. .helmignore 文件忽略不需要的文件;
  11. chart 开发如何进行调试:helm lint,helm install --dry-run --debug,helm get manifest

开发一个 chart Demo

我们通过一个Goweb 程序iim,来演示开发一个 chart 的完整流程。web 应用镜像已经推送到镜像仓中。

  1. 首先在项目中创建 chart 目录,我们使用helm create iim工具生成。其中templates会自动生成 deployment,service ,serviceaccount 资源文件,以及自定义帮助文件模板。我们可以移除一些不必要的文件,如 serviceaccount,因为这里不需要使用这些 kubernetes 资源; _ NOTES.txt:关于应用的帮助信息,如访问地址 _ _helpers.tpl: 放置 chart 帮助程序的地方,便于后续重用
  2. 修改 deployment.yaml,添加入口程序参数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
containers:
- name: { { .Chart.Name } }
securityContext: { { - toYaml .Values.securityContext | nindent 12 } }
image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}"
imagePullPolicy: { { .Values.image.pullPolicy } }
command: ["./iimserver"]
args:
[
"-c",
"/app/config.toml",
"-m",
"/app/model.conf",
"-menu",
"/app/menu.json",
]
  1. 修改程序默认配置,即 Value.yaml 文件
1
2
3
4
5
replicaCount: 1

image:
repository: daocloud.io/daocloud/iim-backend
pullPolicy: IfNotPresent
  1. 修改程序说明文件,即Chart.yaml文件
1
2
3
4
5
6
apiVersion: v2
name: iim
description: 工业机理模型冲刺项目
type: application
version: 0.1.0
appVersion: 0.2.9
  1. 检测Chart是否合法
1
2
3
4
# 校验
helm lint
# 显示模板渲染结果
helm install iim-dmep --dry-run --debug .
  1. 运行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
➜  iim git:(haier-shanghai) ✗ helm install iim .
NAME: iim
LAST DEPLOYED: Thu Feb 13 16:59:25 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=iim,app.kubernetes.io/instance=iim" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:80

➜ iim git:(haier-shanghai) ✗ kubectl get pods
NAME READY STATUS RESTARTS AGE
chartmuseum-chartmuseum-795fb657bd-7h9hw 1/1 Running 0 3h51m
iim-d4567c587-8zzpj 0/1 Running 0 40s

搭建私有仓库

定义与方案

a chart repository存储和共享打包好的charts官方 chart repository维护了许多常用中间件的chart。 本质上,一个chart repo就是一个普通的 http server,其包含一个index.yaml文件和一些packaged chartindex.yaml定义了chart repo的元数据。因此,用户可以使用Google Cloud Storage bucket,Amazon S3 bucket,Github Page去搭建私有仓。

https://example.com/charts这个 chart repo 的布局如下:

1
2
3
4
5
6
7
charts/
|
|- index.yaml
|
|- alpine-0.1.2.tgz
|
|- alpine-0.1.2.tgz.prov

其中的index.yaml内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
apiVersion: v1
entries:
alpine:
- created: 2016-10-06T16:23:20.499814565-06:00
description: Deploy a basic Alpine Linux pod
digest: 99c76e403d752c84ead610644d4b1c2f2b453a74b921f422b9dcb8a7c8b559cd
home: https://helm.sh/helm
name: alpine
sources:
- https://github.com/helm/helm
urls:
- https://technosophos.github.io/tscharts/alpine-0.2.0.tgz
version: 0.2.0
- created: 2016-10-06T16:23:20.499543808-06:00
description: Deploy a basic Alpine Linux pod
digest: 515c58e5f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cd78727
home: https://helm.sh/helm
name: alpine
sources:
- https://github.com/helm/helm
urls:
- https://technosophos.github.io/tscharts/alpine-0.1.0.tgz
version: 0.1.0
nginx:
- created: 2016-10-06T16:23:20.499543808-06:00
description: Create a basic nginx HTTP server
digest: aaff4545f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cdffffff
home: https://helm.sh/helm
name: nginx
sources:
- https://github.com/helm/charts
urls:
- https://technosophos.github.io/tscharts/nginx-1.1.0.tgz
version: 1.1.0
generated: 2016-10-06T16:23:20.499029981-06:00

ChartMuseum是开源的helm chart repository,使用Golang开发,并且对主流的云存储 都有支持。其本身也支持容器化部署,提供了丰富的 api,重要的是其支持多租户。

1
2
3
4
5
6
7
charts
├── org1
│ ├── repoa
│ │ └── nginx-ingress-0.9.3.tgz
├── org2
│ ├── repob
│ │ └── chartmuseum-0.4.0.tgz

搭建chart repo demo

我们以chartmusuem为例,介绍如何搭建chart repo,以及如何将我们上面开发好的chart打包发布到我们的仓库中。

  1. 安装并启动 chartmusuem:
1
2
3
4
5
6
7
curl -LO https://s3.amazonaws.com/chartmuseum/release/latest/bin/linux/amd64/chartmuseum
chmod +x ./chartmuseum
mv ./chartmuseum /usr/local/bin

[root@localhost ~]# chartmuseum --port=9081 --storage="local" --storage-local-rootdir="/root/charts"
2020-02-13T14:30:26.543+0800 INFO Starting ChartMuseum {"port": 9081}

  1. helm 添加 repo:
1
2
3
4
5
➜  helmdemo helm repo add chartmuseum http://192.168.5.82:9081
➜ helmdemo helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "chartmuseum" chart repository
...Successfully got an update from the "incubator" chart repository
  1. 将开发好的 chart 打包 tgz 文件并且发布到我们的仓库中:
1
2
3
4
5
6
7
8
9
10
11
12
13
➜  helmdemo create myappone
➜ helmdemo cd myappone/
➜ myappone helm lint
==> Linting .
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed
➜ myappone helm package .
Successfully packaged chart and saved it to: /Users/donggang/Documents/Temp/helmdemo/myappone/myappone-0.1.0.tgz
➜ myappone ls
Chart.yaml charts myappone-0.1.0.tgz templates values.yaml
➜ myappone curl -L --data-binary "@myappone-0.1.0.tgz" http://192.168.5.82:9081/api/charts
{"saved":true}%
  1. 其他集群下载使用私有仓库的 chart
1
2
3
4
➜  myappone helm repo update
➜ myappone helm search repo myappone
NAME CHART VERSION APP VERSION DESCRIPTION
chartmuseum/myappone 0.1.0 1.16.0 A Helm chart for Kubernetes

一句话

  1. kubeapps: 一个web ui工具部署helm chart
  2. helm 支持丰富的插件,版本升级工具即通过插件实现的;
  3. helm 提供了golang sdk
  4. 目前包括openshift在内的厂商都支持Helm
  5. lens:一个kubernetes管理看板,支持Helm,其交互设计非常值得学习。

总结

Helm已经成为事实上kubernetes包管理器的标准,并且也成功从 CNCF 中毕业。Helm能够很好的解决企业使用 kubernetes 所遇到的各种痛点, 且新版本的helm架构更加清晰,职责也更加明确。在阅读本文后,相信您也对Helm有了一个初步的认识。

参考

  1. 官方文档
  2. kubecon helm introduce
  3. kubecon helm deep dive
  4. codefresh helm 最佳实践