Helm 2 后的变更
Helm 2 后的变更
以下是 Helm 3 中引入的所有主要变更的详尽列表。
移除 Tiller
在 Helm 2 的开发周期中,我们引入了 Tiller。Tiller 在团队在共享集群上工作时发挥了重要作用——它使多个不同的操作员可以与同一组发布交互。
随着 Kubernetes 1.6 中默认启用基于角色的访问控制 (RBAC),在生产环境中锁定 Tiller 以供使用变得更加难以管理。由于可能的安全策略数量众多,我们的立场是提供一个宽松的默认配置。这使首次使用 Helm 和 Kubernetes 的用户无需深入了解安全控制即可开始试验。不幸的是,这种宽松的配置可能会授予用户不应具有的广泛权限。DevOps 和 SRE 在将 Tiller 安装到多租户集群时必须学习额外的操作步骤。
在听取了社区成员在某些情况下如何使用 Helm 后,我们发现 Tiller 的发布管理系统无需依赖集群内操作员来维护状态或充当 Helm 发布信息的中心枢纽。相反,我们只需从 Kubernetes API 服务器获取信息,在客户端渲染图表,并将安装记录存储在 Kubernetes 中。
Tiller 的主要目标可以在没有 Tiller 的情况下实现,因此我们关于 Helm 3 的第一个决定之一就是完全移除 Tiller。
随着 Tiller 的消失,Helm 的安全模型得到了彻底简化。Helm 3 现在支持现代 Kubernetes 的所有现代安全、身份和授权功能。Helm 的权限使用您的 kubeconfig 文件 进行评估。集群管理员可以根据需要限制用户权限的粒度。发布仍然在集群内记录,Helm 的其余功能保持不变。
改进的升级策略:3 路战略合并补丁
Helm 2 使用了 2 路战略合并补丁。在升级期间,它将最新图表的清单与拟议图表的清单(在 helm upgrade
期间提供的清单)进行比较。它比较了这两个图表之间的差异以确定需要对 Kubernetes 中的资源应用哪些更改。如果对集群进行了外部更改(例如在 kubectl edit
期间),则不会考虑这些更改。这导致资源无法回滚到其先前状态:因为 Helm 仅将最后应用的图表的清单视为其当前状态,如果图表的 state 没有更改,则实时状态将保持不变。
在 Helm 3 中,我们现在使用 3 路战略合并补丁。Helm 在生成补丁时会考虑旧清单、其实时状态和新清单。
示例
让我们通过一些常见的示例来了解此更改的影响。
回滚到实时状态已更改的地方
您的团队刚刚使用 Helm 将其应用程序部署到 Kubernetes 上的生产环境。图表包含一个 Deployment 对象,其中副本数设置为 3
$ helm install myapp ./myapp
一名新开发人员加入了团队。在他们第一天观察生产集群时,发生了可怕的键盘上洒咖啡的事故,他们将生产部署的副本数从 3 个缩减到 0 个。
$ kubectl scale --replicas=0 deployment/myapp
您团队中的另一位开发人员注意到生产网站已关闭,并决定将发布回滚到其先前状态
$ helm rollback myapp
会发生什么?
在 Helm 2 中,它将生成一个补丁,比较旧清单与新清单。因为这是一个回滚,所以是同一个清单。Helm 将确定没有更改,因为旧清单与新清单之间没有差异。副本数继续保持为 0。恐慌随之而来。
在 Helm 3 中,补丁是使用旧清单、实时状态和新清单生成的。Helm 认识到旧状态为 3,实时状态为 0,新清单希望将其更改回 3,因此它生成了一个补丁以将状态更改回 3。
实时状态已更改的升级
许多服务网格和其他基于控制器的应用程序会将数据注入 Kubernetes 对象。这可能是 sidecar、标签或其他信息。以前,如果您有从图表渲染的给定清单
containers:
- name: server
image: nginx:2.0.0
而实时状态被另一个应用程序修改为
containers:
- name: server
image: nginx:2.0.0
- name: my-injected-sidecar
image: my-cool-mesh:1.0.0
现在,您想将 nginx
镜像标签升级到 2.1.0
。因此,您升级到具有以下清单的图表
containers:
- name: server
image: nginx:2.1.0
会发生什么?
在 Helm 2 中,Helm 生成旧清单与新清单之间的 containers
对象的补丁。在补丁生成期间不会考虑集群的实时状态。
集群的实时状态被修改为如下所示
containers:
- name: server
image: nginx:2.1.0
sidecar Pod 已从实时状态中删除。更多恐慌随之而来。
在 Helm 3 中,Helm 生成旧清单、实时状态和新清单之间的 containers
对象的补丁。它注意到新清单将镜像标签更改为 2.1.0
,但实时状态包含 sidecar 容器。
集群的实时状态被修改为如下所示
containers:
- name: server
image: nginx:2.1.0
- name: my-injected-sidecar
image: my-cool-mesh:1.0.0
发布名称现在限定到命名空间
随着 Tiller 的移除,关于每个发布的信息必须存储在某个地方。在 Helm 2 中,这存储在与 Tiller 相同的命名空间中。实际上,这意味着一旦发布使用了一个名称,其他发布就不能使用相同的名称,即使它部署在不同的命名空间中也是如此。
在 Helm 3 中,有关特定发布的信息现在存储在与发布本身相同的命名空间中。这意味着用户现在可以在两个不同的命名空间中 helm install wordpress stable/wordpress
,并且每个都可以通过更改当前命名空间上下文来使用 helm list
引用(例如 helm list --namespace foo
)。
随着与本机集群命名空间的这种更紧密的对齐,helm list
命令不再默认列出所有发布。相反,它只列出当前 kubernetes 上下文命名空间中的发布(即在运行 kubectl config view --minify
时显示的命名空间)。这也意味着您必须向 helm list
提供 --all-namespaces
标志以获得类似于 Helm 2 的行为。
秘密作为默认存储驱动程序
在 Helm 3 中,秘密现在用作 默认存储驱动程序。Helm 2 默认使用 ConfigMaps 来存储发布信息。在 Helm 2.7.0 中,实现了使用 Secrets 来存储发布信息的新的存储后端,现在它是从 Helm 3 开始的默认值。
将秘密更改为 Helm 3 的默认值,可以与 Kubernetes 中发布的秘密加密相结合,为保护图表提供额外的安全保障。
在静止状态下加密秘密 成为 Kubernetes 1.7 中的 alpha 功能,并从 Kubernetes 1.13 开始成为稳定功能。这使用户能够在静止状态下加密 Helm 发布元数据,因此这是一个良好的起点,可以扩展到以后使用类似 Vault 的内容。
Go 导入路径更改
在 Helm 3 中,Helm 将 Go 导入路径从 k8s.io/helm
切换到 helm.sh/helm/v3
。如果您打算升级到 Helm 3 Go 客户端库,请确保更改您的导入路径。
功能
在渲染阶段可用的 .Capabilities
内置对象已简化。
使用 JSONSchema 验证图表值
现在可以对图表值强制执行 JSON Schema。这确保了用户提供的值遵循图表维护人员制定的模式,在用户为图表提供不正确的值集时提供更好的错误报告。
在以下任何命令被调用时,都会进行验证
helm install
helm upgrade
helm template
helm lint
有关更多信息,请参见关于 模式文件 的文档。
将 requirements.yaml
合并到 Chart.yaml
中
图表依赖管理系统已从 requirements.yaml 和 requirements.lock 迁移到 Chart.yaml 和 Chart.lock。我们建议为 Helm 3 准备的新图表使用新格式。但是,Helm 3 仍然理解图表 API 版本 1 (v1
),并将加载现有的 requirements.yaml
文件
在 Helm 2 中,requirements.yaml
的外观如下
dependencies:
- name: mariadb
version: 5.x.x
repository: https://charts.helm.sh/stable
condition: mariadb.enabled
tags:
- database
在 Helm 3 中,依赖项以相同的方式表达,但现在是从您的 Chart.yaml
中表达的
dependencies:
- name: mariadb
version: 5.x.x
repository: https://charts.helm.sh/stable
condition: mariadb.enabled
tags:
- database
图表仍然会下载并放置在charts/
目录中,因此 vendored 到charts/
目录中的子图表将继续工作而无需修改。
安装时现在需要名称(或 --generate-name)
在 Helm 2 中,如果没有提供名称,则会使用自动生成的名称。在生产环境中,这被证明是麻烦大于有用的功能。在 Helm 3 中,如果在helm install
中没有提供名称,Helm 会抛出错误。
对于那些仍然希望自动生成名称的用户,可以使用--generate-name
标志为你创建一个。
将图表推送到 OCI 仓库
这是一个在 Helm 3 中引入的实验性功能。要使用它,请设置环境变量HELM_EXPERIMENTAL_OCI=1
。
从高层次来看,图表仓库是一个存储和共享图表的场所。Helm 客户端将 Helm 图表打包并发送到图表仓库。简而言之,图表仓库是一个基本 HTTP 服务器,它包含一个 index.yaml 文件和一些打包的图表。
虽然图表仓库 API 满足最基本存储需求,但具有一些优点,但也开始出现一些缺点
- 图表仓库很难抽象生产环境中所需的大多数安全实现。在生产环境中,拥有一个标准的认证和授权 API 非常重要。
- Helm 的图表来源工具用于签署和验证图表的完整性和来源,是图表发布过程中的一个可选部分。
- 在多租户场景中,相同的图表可以被其他租户上传,导致存储相同的內容需要支付两倍的存储成本。更智能的图表仓库被设计来处理这个问题,但这不是正式规范的一部分。
- 使用单个索引文件进行搜索、元数据信息和获取图表,使得在安全的多租户实现中难以或笨拙地设计。
Docker 的 Distribution 项目(也称为 Docker Registry v2)是 Docker Registry 项目的继任者。许多主要的云供应商都提供 Distribution 项目的产品,并且由于许多供应商提供相同的产品,Distribution 项目得益于多年的强化、安全最佳实践和实战测试。
请查看helm help chart
和 helm help registry
,了解如何打包图表并将其推送到 Docker 仓库的更多信息。
更多信息,请参见此页面。
移除helm serve
helm serve
在你的机器上运行了一个本地图表仓库,用于开发目的。但是,它并没有被广泛用作开发工具,并且在设计方面存在许多问题。最终,我们决定将其移除并将其拆分为插件。
要获得类似于helm serve
的体验,请查看ChartMuseum中的本地文件系统存储选项和servecm 插件。
库图表支持
Helm 3 支持一种名为“库图表”的图表类。这是一种由其他图表共享的图表,但不会创建自己的任何发布工件。库图表的模板只能声明define
元素。全局范围内的非define
内容将被忽略。这允许用户重复使用和共享代码片段,这些代码片段可以在许多图表中重复使用,避免冗余并保持图表DRY。
库图表在 Chart.yaml 中的依赖项指令中声明,并且像其他图表一样安装和管理。
dependencies:
- name: mylib
version: 1.x.x
repository: quay.io
我们非常高兴看到此功能为图表开发人员带来的用例,以及使用库图表产生的任何最佳实践。
Chart.yaml apiVersion 升级
随着库图表支持的引入以及 requirements.yaml 合并到 Chart.yaml 中,理解 Helm 2 包格式的客户端将无法理解这些新功能。因此,我们在 Chart.yaml 中将 apiVersion 从v1
升级到v2
。
helm create
现在使用这种新格式创建图表,因此默认的 apiVersion 也在那里升级了。
希望支持两个版本 Helm 图表的客户端应该检查 Chart.yaml 中的apiVersion
字段,以了解如何解析包格式。
XDG 基础目录支持
XDG 基础目录规范是一个可移植的标准,定义了在文件系统上存储配置、数据和缓存文件的位置。
在 Helm 2 中,Helm 将所有这些信息存储在~/.helm
(被称为helm home
)中,可以通过设置$HELM_HOME
环境变量或使用全局标志--home
进行更改。
在 Helm 3 中,Helm 现在根据 XDG 基础目录规范尊重以下环境变量
$XDG_CACHE_HOME
$XDG_CONFIG_HOME
$XDG_DATA_HOME
Helm 插件仍然将$HELM_HOME
作为$XDG_DATA_HOME
的别名传递,以与希望使用$HELM_HOME
作为临时环境的插件向后兼容。
还将一些新的环境变量传递到插件的环境中,以适应这种更改
$HELM_PATH_CACHE
用于缓存路径$HELM_PATH_CONFIG
用于配置路径$HELM_PATH_DATA
用于数据路径
希望支持 Helm 3 的 Helm 插件应该考虑使用这些新的环境变量。
CLI 命令重命名
为了更好地与其他包管理器的用语保持一致,helm delete
被重命名为helm uninstall
。helm delete
仍然保留为helm uninstall
的别名,因此可以使用两种形式。
在 Helm 2 中,为了清除发布分类账,必须提供--purge
标志。此功能现在默认启用。要保留之前的行为,请使用helm uninstall --keep-history
。
此外,还对其他一些命令进行了重命名,以符合相同的约定
helm inspect
->helm show
helm fetch
->helm pull
这些命令也保留了它们旧的动词作为别名,因此你可以继续以任何一种形式使用它们。
自动创建命名空间
在不存在的命名空间中创建发布时,Helm 2 会创建该命名空间。Helm 3 遵循其他 Kubernetes 工具的行为,如果命名空间不存在,则返回错误。如果你显式指定--create-namespace
标志,Helm 3 会创建命名空间。
.Chart.ApiVersion 发生了什么?
Helm 遵循驼峰命名法,即对缩写词进行大写。我们在代码的其他地方也做了这件事,比如.Capabilities.APIVersions.Has
。在 Helm v3 中,我们纠正了.Chart.ApiVersion
以遵循这种模式,将其重命名为.Chart.APIVersion
。