用 Helm 来简化 K8s 应用管理
- 1.诞生背景
- 2.主要功能
- 3.相关概念
- 4.工作原理
- 5.架构演变
- 6.Helm 常用命令
- 7.推荐仓库
- 8.Charts
- 8.1 目录结构
- 8.2 构建一个无状态应用模版 charts
Helm 对于 Kubernetes 来说就相当于 Yum 对于 Centos 来说,如果没有 Yum 的话,我们在 Centos 下面要安装一些应用程序是极度麻烦的,同样的,对于越来越复杂的 Kubernetes 应用程序来说,如果单纯依靠我们去手动维护应用程序的 YAML 资源清单文件来说,成本也是巨大的。
Helm 是 Deis 开发的一个用于 Kubernetes 的 包管理器。每个包称为一个 Chart,一个 Chart 是一个目录(一般情况下会将目录进行打包压缩,形成 name-version.tgz
格式的单一文件,方便传输和存储)。
对于应用发布者而言,可以通过 Helm 打包应用,管理应用依赖关系,管理应用版本并发布应用到软件仓库。
除此以外,Helm 还提供了 Kubernetes 上的软件部署,删除,升级,回滚应用的强大功能。
1.诞生背景
K8s 是一个分布式的容器集群管理系统,它将集群中的所有资源都抽象成 API 对象,并且使用声明的方式来创建、修改、删除这些对象。在微服务盛行的今天,如果使用这种方式将导致大量 API 声明文件的编写维护,使运维工作量爆发式增长,并且对每个微服务应用都需要编写对应的 YAML 配置文件,极容易出错,维护困难。Helm 就是为解决这些问题而诞生的。
在云(Kubernetes)上,部署一个应用往往不是那么简单。如果想要部署一个应用程序到云上,首先要准备好它所需要的环境,打包成 Docker 镜像,进而把镜像放在 部署文件(Deployment
)中,配置 服务(Service
)、应用所需的 账户(ServiceAccount
)及 权限(Role
)、命名空间(Namespace
)、密钥信息(Secret
)、可持久化存储(PersistentVolumes
)等资源。也就是编写一系列互相相关的 YAML 配置文件,将它们部署在 Kubernetes 集群上。
即便应用的开发者可以把这些 Docker 镜像存放在公共仓库中,并且将所需的 YAML 资源文件提供给用户,用户仍然需要自己去寻找这些资源文件,并把它们一一部署。倘若用户希望修改开发者提供的默认资源,比如使用更多的 副本(Replicas
)或是修改服务 端口(Port
),他还需要自己去查需要在这些资源文件的哪些地方修改,更不用提版本变更与维护会给开发者和用户造成多少麻烦了。
2.主要功能
Helm 主要功能如下:
- 查找要安装和使用的预打包软件(Chart)
- 轻松创建和托管自己的软件包
- 将软件包安装到任何 K8s 集群中
- 查询集群已安装和正在运行的程序包
- 更新、删除、回滚或查看已安装软件包的历史记录
从使用方角度看:
- 应用发布者:可以通过 Helm 打包应用,管理应用依赖关系,管理应用版本并发布应用到软件仓库。Helm 还提供了 Kubernetes 上的软件部署,删除,升级,回滚应用的强大功能。
- 使用者:使用 Helm 后不用需要了解 Kubernetes 的 Yaml 语法并编写应用部署文件,可以通过 Helm 下载并在 Kubernetes 上安装需要的应用。
3.相关概念
概念 |
|
---|---|
Helm | Helm 是一个命令行下的客户端工具。主要用于 Kubernetes 应用程序 Chart 的创建、打包、发布以及创建和管理本地和远程的 Chart 仓库。 |
Tiller(V2) | Tiller 是 Helm 的服务端,部署在 Kubernetes 集群中。Tiller 用于接收 Helm 的请求,并根据 Chart 生成 Kubernetes 的部署文件(Helm 称为 Release),然后提交给 Kubernetes 创建应用。Tiller 还提供了 Release 的升级、删除、回滚等一系列功能。 |
Chart | Helm 的软件包,采用 TAR 格式。类似于 APT 的 DEB 包或者 YUM 的 RPM 包,其包含了一组定义 Kubernetes 资源相关的 YAML 文件。Chart 有特定的文件目录结构,如果开发者想自定义一个新的 Chart,只需要使用 Helm create 命令生成一个目录结构即可进行开发。 |
Repoistory | Helm 的软件仓库,Repository 本质上是一个 Web 服务器,该服务器保存了一系列的 Chart 软件包以供用户下载,并且提供了一个该 Repository 的 Chart 包的清单文件以供查询。Helm 可以同时管理多个不同的 Repository, 官方仓库的地址是:https://hub.helm.sh。 |
Release | 使用 helm install 命令在 Kubernetes 集群中部署的 Chart 称为 Release。是运行在 Kubernetes 集群中的 chart 的实例,一个 chart 通常可以在同一个集群中安装多次。每一次安装都会创建一个新的 release 。以 MySQL chart 为例,如果你想在你的集群中运行两个数据库,你可以安装该 chart 两次。每一个数据库都会拥有它自己的 release 和 release name 。 |
4.工作原理
Chart Install 过程
- Helm 从指定的目录或者
tgz
文件中解析出 Chart 结构信息 - Helm 将指定的 Chart 结构和 Values 信息通过 gRPC 传递给 Tiller
- Tiller 根据 Chart 和 Values 生成一个 Release
- Tiller 将 Release 发送给 Kubernetes 用于生成 Release
Chart Update 过程
- Helm 从指定的目录或者
tgz
文件中解析出 Chart 结构信息 - Helm 将要更新的 Release 的名称和 Chart 结构,Values 信息传递给 Tiller
- Tiller 生成 Release 并更新指定名称的 Release 的 History
- Tiller 将 Release 发送给 Kubernetes 用于更新 Release
Chart Rollback 过程
- Helm 将要回滚的 Release 的名称传递给 Tiller
- Tiller 根据 Release 的名称查找 History
- Tiller 从 History 中获取上一个 Release
- Tiller 将上一个 Release 发送给 Kubernetes 用于替换当前 Release
5.架构演变
在 2019 年 11 月 4 日,Helm 社区 repo 中提供安全审计报告 , Helm v3 中的访问控制与 Helm v2 中的访问控制发生变更。
- 移除 Tiller
- 支持将 Chart 推送至 Docker 镜像仓库中
- 使用 JSONSchema 验证
chart values
- 给 helm charts 添加
test
了,通过helm test
命令针对部署的应用跑 tests - 部署时 release name 必须指定,helm2 时可自动随机生成
- 删除时无须再使用
–purge
- 为了更好地协调其他包管理者的措辞 Helm CLI 个别更名;
helm delete
更名为helm uninstall
,helm inspect
更名为helm show
,helm fetch
更名为helm pull
- 不再需要
requirements.yaml
,依赖关系是直接在chart.yaml
中定义 - 移除了用于本地临时搭建 Chart Repository 的
helm serve
命令
6.Helm 常用命令
命令 |
|
---|---|
create | 创建一个 chart 并指定名字 |
dependency | 管理 chart 依赖 |
get | 下载一个 release。可用子命令:all 、hooks 、manifest 、notes 、values |
history | 获取 release 历史 |
install | 安装一个 chart |
list | 列出 release |
package | 将 chart 目录打包到 chart 存档文件中 |
pull | 从远程仓库中下载 chart 并解压到本地,helm pull stable/mysql --untar |
repo | 添加、列出、移除、更新和索引 chart 仓库。可用子命令:add 、index 、list 、remove 、update |
rollback | 从之前版本回滚 |
search | 根据关键字搜索 chart。可用子命令:hub 、repo |
show | 查看 chart 详细信息。可用子命令:all 、chart 、readme 、values |
status | 显示已命名版本的状态 |
template | 本地呈现模板 |
uninstall | 卸载一个 release |
upgrade | 更新一个 release |
version | 查看 helm 客户端版本 |
7.推荐仓库
难免需要安装一些三方的基础服务,常用仓库如下 :
- bitnami 官方地址:https://bitnami.com/
- 微软仓库:http://mirror.azure.cn/kubernetes/charts/
- 阿里云仓库:https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
- 官方仓库:https://hub.kubeapps.com/charts/incubator
- elasticsearch:https://helm.elastic.co
添加微软仓库为 stable
$ helm repo add stable http://mirror.azure.cn/kubernetes/charts
"stable" has been added to your repositories
添加阿里云仓库为 aliyun
$ helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
"aliyun" has been added to your repositories
查看本地已添加的仓库
$ helm repo list
NAME URL
stable http://mirror.azure.cn/kubernetes/charts
aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
查看仓库所有的包
$ helm search repo stable
移除仓库
$ helm repo remove stable
列出仓库中相关的包
$ helm search repo mysql
8.Charts
8.1 目录结构
demochart/
├── charts # 目录用于存放所依赖的子chart
├── Chart.yaml # 描述这个 Chart 的相关信息、包括名字、描述信息、版本等
├── templates # 模板目录,通常会使用values.yaml配置内容进行填充,板引擎渲染此目录的文件后Tiller将渲染得到的结果 提交给Kubernetes创建响应的对象
│ ├── deployment.yaml # deployment 控制器的 Go 模板文件
│ ├── _helpers.tpl # 模板助手文件,定义的值可在模板中使用
│ ├── ingress.yaml # ingress 的模板文件
│ ├── NOTES.txt # Chart 部署到集群后的一些信息,例如:如何使用、列出缺省值,可以理解为帮助文档
│ ├── serviceaccount.yaml
│ ├── service.yaml # service 的 Go 模板文件
└── values.yaml # 模板的值文件,这些值会在安装时应用到 GO 模板生成部署文件
Chart.yaml
的模板及注释如下:
apiVersion: chart API 版本 (必需) #必须有
name: chart名称 (必需) # 必须有
version: 语义化2 版本(必需) # 必须有
kubeVersion: 兼容Kubernetes版本的语义化版本(可选)
description: 一句话对这个项目的描述(可选)
type: chart类型 (可选)
keywords:
- 关于项目的一组关键字(可选)
home: 项目home页面的URL (可选)
sources:
- 项目源码的URL列表(可选)
dependencies: # chart 必要条件列表 (可选)
- name: chart名称 (nginx)
version: chart版本 ("1.2.3")
repository: (可选)仓库URL ("https://example.com/charts") 或别名 ("@repo-name")
condition: (可选) 解析为布尔值的yaml路径,用于启用/禁用chart (e.g. subchart1.enabled )
tags: # (可选)
- 用于一次启用/禁用 一组chart的tag
import-values: # (可选)
- ImportValue 保存源值到导入父键的映射。每项可以是字符串或者一对子/父列表项
alias: (可选) chart中使用的别名。当你要多次添加相同的chart时会很有用
maintainers: # (可选) # 可能用到
- name: 维护者名字 (每个维护者都需要)
email: 维护者邮箱 (每个维护者可选)
url: 维护者URL (每个维护者可选)
icon: 用做icon的SVG或PNG图片URL (可选)
appVersion: 包含的应用版本(可选)。不需要是语义化,建议使用引号
deprecated: 不被推荐的chart (可选,布尔值)
annotations:
example: 按名称输入的批注列表 (可选).
values.yaml
包含应用程序的默认配置值,举例:
image:
repository: nginx
tag: '1.19.8'
在模板(templates
)中引入 values.yaml
里的配置,在模板文件中可以通过 .VAlues
对象访问到,例如:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-helm-{{ .Values.image.repository }}
spec:
replicas: 1
selector:
matchLabels:
app: nginx-helm
template:
metadata:
labels:
app: nginx-helm
spec:
containers:
- name: nginx-helm
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
ports:
- containerPort: 80
protocol: TCP
8.2 构建一个无状态应用模版 charts
- 目录结构
$ tree demochart/
demochart/
├── charts
├── Chart.yaml
├── templates
│ ├── deployment.yaml
└── values.yaml
Chart.yaml
apiVersion: v2
name: demochart
description: A Helm chart for Kubernetes, The author is Daizhe
type: application
version: 0.1.0
appVersion: 1.16.0
templates/deployment.yaml
$ vim templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: deployment
name: {{ .Values.Name }}
spec:
replicas: {{ .Values.replicas }}
selector:
matchLabels:
app: deployment
template:
metadata:
labels:
app: deployment
spec:
containers:
- image: {{ .Values.image }}
name: nginx
values.yaml
Name: demo-deploy-nginx
replicas: 1
image: nginx:latest
install
安装
$ helm install nginx-dep demochart/ --dry-run
$ helm install nginx-dep demochart/
$ helm list
upgrade
升级
$ helm upgrade -f values.yaml nginx-dep demochart
rollback
回滚
$ helm history nginx-dep
$ helm rollback nginx-dep 1