第1章、Helm3 简介
helm3.jpg
一、什么是 Helm?
就像 Java 使用 maven;node 使用 npm;python 使用 pip;Linux 使用 yum 或 Apt 一样,不管是什么样的工作,技术人员都会希望有一种资源管理器/包管理器,以此来方便得查找、下载、安装、使用和分发软件包。
所以 Helm 即可以说是 K8S的包管理器
,它使得我们对于 K8S 的操作不再需要细化到资源对象,而是可以作为一个实例进行管理。不再需要去写 deployment
、service
、ingress
的 yaml,而是可以直接通过 install
命令实现服务实例的安装。
Helm 的主要功能总结:
- 查找要安装和使用的预打包软件
- 轻松创建和托管自己的软件包
- 将软件包安装到任何 K8S 集群中
- 查询集群以查看已安装和正在运行的程序包
- 更新、删除、回滚或查看已安装软件包的历史记录
二、Helm 中的基本概念
1、Chart
Helm 使用的包格式称为 chart
,它是一个描述 Kubernetes 相关资源对象的文件集合。它的技术特点类似 jinja模版,以渲染模版的方式,生成运行一个服务实例所需的一系列资源对象文件,并以此进行服务的发布。通过这种方式,我们也可以十分简单的制作自定义的 chart。
Chart 有自已特定的目录布局,我们以官方提供的 wordpress
为例说明,chart 的文件目录结构如下:
wordpress/
Chart.yaml # 包含了chart信息的YAML文件
LICENSE # 可选: 包含chart许可证的纯文本文件
README.md # 可选: 可读的README文件
values.yaml # chart 默认的配置值
values.schema.json # 可选: 一个使用JSON结构的values.yaml文件
charts/ # 包含chart依赖的其他chart
crds/ # 自定义资源的定义
templates/ # 模板目录, 当和values 结合时,可生成有效的Kubernetes manifest文件
templates/NOTES.txt # 可选: 包含简要使用说明的纯文本文件
⚠️ 注意:
Helm Chart 基本元素为
charts/
、Chart.yaml
、templates/
、values.yaml
,并保留crds/
,要正确的使用 chart 进行发布,该元素是必不可少的。
2、Repos
Helm chart 可以被存储在专用的 HTTP 服务器上,称为 chart 仓库(repositories)
,和 yum repository
类似,chart 仓库提供了一个 index.yaml
来描述一批 chart,并且提供了每个 chart 的下载地址信息。
Helm 客户端可以指向多个 chart 仓库,默认情况下是没有配置仓库的,需要使用 helm repo add
来进行添加。helm3 中对于一些常用服务的下载安装,用 bitnami 仓库
取代了原来的stable 仓库
,但是仍保留了 stable 仓库
的使用。
3、Release
当 chart 被发布后,Helm 库会创建一个 release
来跟踪这个发布的对象,它的实质是在 Kubernetes 中运行的各种资源,service
、deployment
、configmap
、secret
等,在 K8S 集群中的直接的表现就是一个或多个 pod。
⚠️ 注意:
Helm 的 release 是允许启动多个不同服务的,且每个服务之间遵循依赖关系,这点就比较类似 docker compose。
三、从 Helm2 到 Helm3 的变化
1、Helm3 新增的功能
Helm3 有很多新的功能,有个重要功能需要特别指出:
- release 的信息以新的形式存储
- 移除了 Tiller 组件
- Helm3 包含了对新版本 Helm charts (Charts v2)的支持
- Helm3 支持
library charts
—— 一种作为其他 charts 元素的 charts- 将 Chart 推送保存到 OCI 注册中心(类似 DockerRegistry ),以进行复用
- 升级Kubernetes资源时将应用3向战略合并补丁
- 支持使用 JSON Schema 对 charts 的 values 进行校验
- 为了使Helm更安全,可用和健壮,已进行了许多小的改进。
2、重要变化概述
1)移除 Tiller
Tiller
在 Helm2 中是一个重要的组成部分。Helm2 使用它和 GRPC
来处理 Helm chart
的安装和管理,呈现 chart
并将其推送到 Kubernetes API Server。Tiller
允许团队共享一个 Kubernetes 集群,多个 operator 可以使用同一组发行版,团队成员通过它就可以在一个共享的 Kubernetes 集群中管理复杂的应用发布。
但是从 Kubernetes 1.6 开始,考虑到安全性,集群默认会开启角色访问控制(RBAC
),这使得管理和配置Tiller会变得非常复杂,因为可能的安全策略数量太多了。为了简化安全模型实现方式,并使管理员/SRE不需要去深入研究 Kubernetes 的安全组件,helm 提供了一个不需要太过关注安全规则的默认配置,但是这又会使得授权变得宽松,这反而会导致安全隐患。
因此在 Helm3 中干脆移除了 Tiller,而是选择从 Kubernetes API Server 中获取信息来渲染 Charts 客户端,并在 Kubernetes 中存在安装记录,这些过程既是没有 Tiller 也可以实现。
Helm3 可以支持所有的 Kubernetes 认证及鉴权等全部安全特性。Helm和本地的 kubeconfig flie 中的配置使用一致的权限。管理员可以按照自己认为合适的粒度来管理用户权限。
helm3变化.png2)Chart 仓库升级
在 Helm3 中,helm search
除了支持本地 repository 搜索外,还支持 helm search hub
搜索 Artifact Hub 中所有公开的 charts。
3)改进升级策略:使用三路策略合并补丁
在 Helm2 中,使用了双路策略合并补丁,简单来说就是在使用 helm upgrade
更新过程中,会比对本次发布的 chart manifest 和 最近一次发布的 chart manifest 的差异,以此来决定哪些更改被应用到 Kubernetes 的资源中去。并且,Helm 只会将最后一次应用的 chart manifest 作为 release 的当前状态,如果 chart 状态没有更改,资源的活动状态就不会更改,也就是说使用诸如 kubectl edit
、kubectl scale
这种外部方式进行的修改不会被 Helm 识别的,这种情况下如果发生回滚操作,Helm 会由于 chart 并没有发生变化而导致回滚失败。
而在 Helm3 中,这种策略被升级成了三路策略合并,Helm 在生成一个补丁时,也会考虑之前老的 manifest 的活动状态。也就是说,在使用老的 chart manifest 生成新的补丁时,Helm 还会考虑当前的活动状态,并将其与之前老的 manifest 进行比对,并再比对新的 manifest 是否有改动,并进行自动补全,以此来生成最终的更新补丁。
示例说明:
用 Chart 渲染生成的 manifest 如下:
containers:
- name: server
image: my_app:2.0.0
通过非 Helm 的方式将应用的活动状态修改为如下:
containers:
- name: server
image: my_app:2.0.0
- name: sidecar
image: dump_handler:1.0.0
而现在我们想要将应用的镜像升级到 2.1.0
,通过 chart 进行升级操作。
在 Helm2 中,由于不会考虑 chart 之外的修改,而是检测 chart 生成的 manifest 之间的区别,因此修改后的状态如下:
containers:
- name: server
image: my_app:2.1.0
而在 Helm3 中,通过三路合并策略,会检查到除了 chart 的修改外,还多了一个 sidecar 容器,因此会进行补全,最终修改状态如下:
containers:
- name: server
image: my_app:2.1.0
- name: sidecar
image: dump_handler:1.0.0
4)release 名称存储位置改变
在 Helm2 中,release 的相关信息都被保存在 Tiller 的 namespace下,所以 release 的名称必须是唯一的;而随着 Tiller 组件的移除, Helm3 中release 相关的信息都被保存在了应用自己相对应的 namespace 下,因此根据 namespace 的隔离性质,在不同的 ns 下,release 的名称可以重复。
⚠️ 注意:
Helm3 中,在执行
helm list
时需要添加--all-namespaces
参数才能获取到 Helm2 中同样的结果
5)默认存储驱动程序更改为 Secrets
Helm 2 默认情况下使用 ConfigMaps 存储发行信息,直到 Helm 2.7.0 中,才使用 Secrets 用作存储驱动程序。而在 Helm 3 中默认就使用 Secrets。
静态加密密钥 在Kubernetes 1.7中作为alpha特性可以使用了,在Kubernetes 1.13中变成了稳定特性。 这允许用户静态加密Helm的发布元数据,同时也是一个类似Vault的以后可扩展的良好起点。
6)Go 导入路径更改
在 Helm3 中,Go 导入路径从k8s.io/helm
切换为 helm.sh/helm/v3
。 如果打算升级到Helm 3 Go客户端库,请确保更改导入路径。
7)使用 JSONSchema 验证 Chart 的 values
Helm3 支持用JSONSchema
来校验 Chart 的 values,它会自动检查所有输入的变量格式。这样可以确保用户提供的值遵循 Chart 维护者设计的架构,当用户为 Chart 提供一组错误值时,也能提供更好的错误报告。
当调用一下命令时会进行 JSON 格式验证:
- helm install
- helm upgrade
- helm template
- helm lint
8)requirements.yaml合并入 Chart.yaml
动态依赖关系的chart 依赖从 requirements.yaml
和 requirements.lock
移至 Chart.yaml
和 Chart.lock
。 推荐在 Helm3 的新 chart 中使用 Chart API v2 的新格式,但是 Helm3 中依然可以识别 v1 版本,并且会自动加载已有的 requirements.yaml
文件。
在 Helm2 中,requirements.yaml
的表达式类似如下形式:
dependencies:
- name: mariadb
version: 5.x.x
repository: https://charts.helm.sh/stable
condition: mariadb.enabled
tags:
- database
而在 Helm3 中,表达式的形式并没有变化,但是现在需要写在 Chart.yaml
中。Chart 依然会下载和放置在 charts/
目录,所以 charts/
目录中的子 chart 不需要做任何修改,可以沿用 Helm2 的。
9)指定名称和命名空间
1⃣️ 发布时必须指定 release 名称
在 Helm2 中,在发布时如果未提供 release 的名称,Helm 会自动生成一个,但是在 Helm3 中,如果未指定 release 名称,安装就会报错,如果仍然希望 Helm 能够自动生成 release 名称,可以使用 --generate-name
参数。
2⃣️ 不再自动创建 namespace
在 Helm2 中,如果在创建版本时,命名空间不存在,Helm2 会自动创建一个命名空间,但是在 Helm3 中,如果命名空间不存在就会报错,需要明确指定 --create-namespace
参数,Helm3 才会自动创建一个命名空间。
10)将 Chart 推送到 OCI 注册中心
这是一个 Helm3 中的试验性特性,使用时需要设置环境变量 HELM_EXPERIMENTAL_OCI=1
。
查看 helm help chart
和 helm help registry
了解如何打包chart并推送到Docker注册中心的更多信息。
11)移除 helm serve
在 Helm2 中,可以通过 helm serve
命令在本地临时搭建 Chart Repository
,但是由于并没有被开发工具接受,且在设计方面存在较多问题,故在 Helm3 中被删除了。
12)支持 library chart
Helm3 支持一类称为 library chart
的 chart,其本省不会创建任何应用,只是作为其他 chart 的共享依赖。library chart 只能用于声明定义元素,全局范围内的非定义内容将被忽略。这使用户可以重复使用和共享可在许多chart中重复使用的代码段,从而避免了冗余并使 chart 保持简洁。
Library chart 在 Chart.yaml 的依赖指令中声明,安装和管理与其他chart一致,其表达式类似如下形式:
dependencies:
- name: mylib
version: 1.x.x
repository: quay.io
13)Chart.yaml 的 apiVersion 升级
1⃣️ apiVersion v1 升级至 v2
由于 Helm3 中新增了许多新的特性,比如支持 library chart
、requirements.yaml
合并进 Chart.yaml
。而客户端虽然可以是别 Helm2 的包格式,却不能理解这些新的特性,因此 Helm3 中的 Chart.yaml 的 apiVersion 也从 v1 升级到可 v2。
使用 Helm3 的 helm create
创建的 chart 将使用新格式,默认的 apiVersion 也将使用 v2。
2⃣️ ApiVersion 改为 APIVersion
Helm3 对于驼峰的命令规范进行了修改,遵循驼峰命名的典型惯例,因此将 .Chart.ApiVersion
更正为了 .Chart.APIVersion
,其他诸如 .Capabilities.APIVersions.Has
都进行了更正处理。
14)XDG 基本目录支持
XDG 基本目录规范 是一个定义了配置、数据和缓存文件应该存储在文件系统什么位置的可移植标准。
在 Helm2 中,Helm 相关的信息都存储在 ~/.helm/
目录下,可以通过设置环境变量 $HELM_HOME
或者 --home
参数指定。而在 Helm3 中,相关的环境变量则变更为了以下规范形式:
- $XDG_CACHE_HOME # 用于存放缓存文件
- $XDG_CONFIG_HOME # 用于存放配置文件
- $XDG_DATA_HOME # 用于存放数据文件
但是在 Helm3 中仍保留了 $HELM_HOME
作为 $XDG_DATA_HOME
的别名,以此来保证过渡阶段的兼容性。
Helm 插件如过要支持 Helm3,也可以用以下环境变量,来适应这种变化:
- $HELM_PATH_CACHE # 用于存放缓存文件
- $HELM_PATH_CONFIG # 用于存放配置文件
- $HELM_PATH_DATA # 用于存放数据文件
各环境默认文件存放位置
🚩 可以通过
helm env
查看
Operating System | Cache Path | Configuration Path | Data Path |
---|---|---|---|
Linux | $HOME/.cache/helm | $HOME/.config/helm | $HOME/.local/share/helm |
macOS | $HOME/Library/Caches/helm | $HOME/Library/Preferences/helm | $HOME/Library/helm |
Windows | %TEMP%\helm | %APPDATA%\helm | %APPDATA%\helm |
15)CLI 命令重命名
1⃣️ helm delete
更改为 helm uninstall
在 Helm2 中,如果要清楚 release 的各种资源,必须要使用 --purge
参数,Helm3 中默认就会启用次功。
如果要保留历史行为数据,需执行 helm uninstall --keep-history
2⃣️ helm inspect
更改为 helm show
3⃣️ helm fetch
更改为 helm pull
🚩 这些命令还保留了它们较旧的命令作为别名,因此您可以继续以任何一种形式使用它们。
16)简化模板对象 .Capabilities
Capabilities
是 Helm 模版可以访问的内置对象之一,其提供了关于 Kubernetes 集群支持的功能的信息,包含以下内容:
对象名称 | 描述 |
---|---|
Capabilities.APIVersions | 集群的版本信息 |
Capabilities.APIVersions.Has $version | 说明集群中的版本 (例如, batch/v1 ) 或是资源 (例如, apps/v1/Deployment ) 是否可用 |
Capabilities.KubeVersion | 提供了查找 Kubernetes 版本的方法。可以获取到 Major ,Minor ,GitVersion ,GitCommit ,GitTreeState ,BuildDate ,GoVersion ,Compiler 和Platform 。 |
Capabilities.TillerVersion | 提供了查找Tiller版本的方法。可以获取到SemVer , GitCommit , and GitTreeState . |
四、Helm版本支持策略
1、版本形式
Helm 的版本用
x.y.z
的形式描述,x
是主版本,y
是次版本,z
是补丁版本。当一个 Helm 的新版本发布时,都是针对 Kubernetes 的一个特定版本编译的,比如3.0.0
基于 Kubernetes 的1.16.2
的客户端API版本构建,则可以兼容 Kubernetes 1.16。
2、可支持的版本偏差
相较于 Helm2 对于 Kubernetes 次版本变更支持的严格(
n-1
),Helm3 可以向下兼容n-3
的次版本,比如你使用一个针对 Kubernetes 1.18 客户端 API 版本编译的 Helm3 版本,那么它可以支持的 Kubernetes 版本为 1.18、1.17、1.16、1.15 ;如果你使用一个针对 Kubernetes 1.15 客户端 API 版本编译的 Helm2 版本,那么它可以支持的 Kubernetes 版本为 1.15、1.14。
⚠️ 注意: Helm 没有向上兼容机制,故推荐安装下表进行版本选择。
Helm 版本 | 支持的 Kubernetes 版本 |
---|---|
3.6.x | 1.21.x - 1.18.x |
3.5.x | 1.20.x - 1.17.x |
3.4.x | 1.19.x - 1.16.x |
3.3.x | 1.18.x - 1.15.x |
3.2.x | 1.18.x - 1.15.x |
3.1.x | 1.17.x - 1.14.x |
3.0.x | 1.16.x - 1.13.x |
2.16.x | 1.16.x - 1.15.x |
2.15.x | 1.15.x - 1.14.x |
2.14.x | 1.14.x - 1.13.x |
2.13.x | 1.13.x - 1.12.x |
2.12.x | 1.12.x - 1.11.x |
2.11.x | 1.11.x - 1.10.x |
2.10.x | 1.10.x - 1.9.x |
2.9.x | 1.10.x - 1.9.x |
2.8.x | 1.9.x - 1.8.x |
2.7.x | 1.8.x - 1.7.x |
2.6.x | 1.7.x - 1.6.x |
2.5.x | 1.6.x - 1.5.x |
2.4.x | 1.6.x - 1.5.x |
2.3.x | 1.5.x - 1.4.x |
2.2.x | 1.5.x - 1.4.x |
2.1.x | 1.5.x - 1.4.x |
2.0.x | 1.4.x - 1.3.x |
网友评论