Helm 高级特性:测试、安全与自定义资源管理
1. 向图表添加测试
测试是软件开发中不可或缺的一部分,Helm 提供了通过测试钩子和 Kubernetes 资源来测试图表的能力。这意味着测试可以在 Kubernetes 集群中与工作负载一起运行,并访问图表安装的组件。
1.1 Helm 测试
Helm 有一个
helm test
命令,用于在运行的图表实例上执行测试钩子。实现这些钩子的资源可以检查数据库访问、数据库模式是否正确就位、工作负载之间的连接是否正常以及其他操作细节。
如果测试失败,Helm 将以非零退出代码退出,并提供失败的 Kubernetes 资源的名称。非零退出代码在与一些自动测试系统配合使用时很有用,这些系统通过这种方式检测失败。当你获得 Kubernetes 资源的名称后,就可以查看日志以了解失败的原因。
测试通常存放在
templates
目录下的
tests
子目录中。将测试放在这个目录中可以实现有效的分离。这是一种约定,并非运行测试所必需的。
以下是一个测试示例,以
booster
图表为例。在
templates/tests
目录下的
test-connection.yaml
文件中有一个测试钩子:
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "booster.fullname" . }}-test-connection"
labels:
{{- include "booster.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "booster.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never
这个测试是在运行
helm create
时为 Nginx 默认创建的,它也适用于测试与
booster
应用程序的连接。这个简单的测试展示了测试的结构。
如果你查看一些现有图表中的测试,可能会发现它们使用的钩子是
test-success
而不是
test
。在 Helm 2 版本中,有一个名为
test-success
的钩子用于运行测试。Helm 3 版本提供了向后兼容性,会将这个钩子名称作为测试运行。
运行测试有两个步骤:
1. 安装图表,使其实例运行。可以使用
helm install
命令来完成。以下命令安装
booster
图表,并假设你从图表的根目录运行它:
$ helm install boost .
-
当图表实例运行后,运行
helm test命令来执行测试:
$ helm test boost
Helm 将在执行测试时输出测试状态,并在完成后提供有关测试和版本的信息。对于上述测试,它将返回:
Pod boost-booster-test-connection pending
Pod boost-booster-test-connection pending
Pod boost-booster-test-connection running
Pod boost-booster-test-connection succeeded
NAME: boost
LAST DEPLOYED: Tue Jul 21 06:47:05 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: boost-booster-test-connection
Last Started: Tue Jul 21 06:47:12 2020
Last Completed: Tue Jul 21 06:47:17 2020
Phase: Succeeded
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l
"app.kubernetes.io/name=booster,app.kubernetes.io/instance=boost"
-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
当图表有包含测试的依赖项时,这些测试也会运行。例如,如果运行本章前面使用的
rocket
图表中的测试,
booster
图表测试和
rocket
图表测试都会运行。
如果需要在测试中安装配置,可以将测试钩子放在 Kubernetes Secret 或 ConfigMap 上,使其与其他测试资源一起安装。
1.2 Chart 测试工具
Helm 项目提供了一个基于
helm test
的额外测试工具,它提供了更高级的测试功能。它包含的一些额外特性如下:
- 能够在安装图表时测试不同的、相互排斥的配置选项。
- 包含自定义模式规则的
Chart.yaml
模式验证。
- 包含可配置规则的额外 YAML 语法检查。例如,可以确保 YAML 文件中的缩进一致。
- 当源代码存储在 Git 中时,能够检查
Chart.yaml
文件中的版本属性是否已正确递增。
- 能够处理图表集合,并仅测试那些已更改的图表。
这个 Chart 测试工具是为在持续集成系统工作流中使用而设计的,其中一些特性直接针对这种情况。
1.2.1 Chart 测试的历史
在 Helm 的早期,项目维护者创建了一个包含一些图表的仓库,以展示如何使用图表。Helm 仓库从一开始就设计为分布式的,不同的组织运行自己的仓库,Helm 项目提供了一个如何实现的示例。
这个图表仓库逐渐发展,包含了许多图表,并成为一种中央仓库。为了帮助维护这些众多的图表,创建了自动化脚本,以自动为图表的拉取请求提供反馈。
这些自动化脚本被证明不仅对 Helm 项目有用。为了使其他托管的图表仓库也具有相同的测试能力,Helm 项目使用的脚本被分离成一个单独的工具,并以可移植性为目标进行了重写。
现在,Chart 测试工具被各种公司和组织用于帮助测试他们托管的图表。
1.2.2 使用方法
Chart 测试工具测试具有不同、相互排斥配置的图表的能力需要了解这些配置。这些配置被捆绑在图表的
ci
目录中。
在
ci
目录中,你可以为每个要测试的情况创建一个值文件。命名每个文件时,需要使用通配符命名模式
*-values.yaml
。例如,可以使用像
minimal-values.yaml
和
full-values.yaml
这样的文件名。
Chart 测试工具将分别测试这些配置。例如,在对图表进行语法检查时,每个情况将分别进行检查。自定义值将使用
--values
标志传递给
helm lint
。在对图表进行运行时测试时,同样的概念和标志也适用。这些值通过
--values
标志传递给 Helm,因为这是安装图表的最终用户提供自定义配置的方式。
如果你想使用各种配置进行测试,但不想将这些配置作为图表存档的一部分发布,可以将
ci
目录放在
.helmignore
文件中。当 Helm 打包图表时,
ci
目录将被忽略。
Chart 测试工具可以通过多种方式安装和使用。例如,你可以在开发系统上作为二进制应用程序使用,或者在持续集成系统的容器中使用。可以在项目页面上了解更多关于如何根据你的情况使用和设置它的信息。
1.3 安全考虑
一些最大、最受信任的技术组织的用户曾通过软件更新受到攻击。软件更改以及用于更新甚至安装软件的机制提供了攻击渠道。
Helm 提供了一种可选的方式来检查图表的来源和完整性。来源验证可以验证图表的来源,如公司或个人,而完整性检查可以确保你收到的图表没有被更改。此功能使你和使用你图表的人能够验证图表的来源以及内容是否未被更改。
为了实现这一点,Helm 使用了 Pretty Good Privacy (PGP)、哈希和与图表存档文件并存的来源文件。例如,如果你有一个名为
mylib-1.0.0.tgz
的图表存档,可以有一个名为
mylib-1.0.0.tgz.prov
的来源文件。
这个文件包含一个 PGP 消息,其中包含
Chart.yaml
文件的内容以及图表存档的哈希。Helm 可以为你生成这些文件。以下是
mylib-1.0.0.tgz
的来源文件示例:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
apiVersion: v2
description: an example library chart
name: mylib
type: library
version: 0.1.0
...
files:
mylib-0.1.0.tgz: sha256:d312aea39acf7026f39edebd315a11a52d29a9
6a8d68737ead110ac0c0a1163d
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCgAdFiEEcR8o1RDh4Ly9X2v+lDboC/ukaQkFAl8yiesACgkQlDboC/uk
aQkG2BAAlIEgGI7uu9Kr8j4ZIxDseLmgphhPM1kgnIMPriLieBxFXSJQxciN3+dx
OQpIfdsFQvW98EnJ4781Pm+leHY2iI/L08O1cQWUtzKhfPEWC65YQJPXkTKpHnC2
wXYVUVYWvhx6BJ77RiS/f+hoXiC+i1aBqqS0TAG+AqXuwARO2tY/L7cF6EHjsUwD
pPuTNpYZ/OEWqh1KEYZYVDvLm6uN6QjV4pNTFfAgnvMckfoDLQ+kOPQVqCeUWG3F
tZO3sBzUg+Ak2dDviSTOFQ7TCifc3tOOaWS1XtcooSOkUENmTeeWV56jZnhK1rT4
yaIGT16zXZIdmkZ1t5o9VccuAhQ1Us2FhipdGqpD8yDoJABVz/ee9d2zoX8anfR7
LZ7fwecgQ/THnj54RroyQlzf2aottFiL9ZV4MjUqs0CSoA9+SZ/CcJDd/rxBGI8C
yxRqo0VoNdjT8Kr9hha13krfwD8IpLH8bv4kWt3Ckh6rgphjUL19xyTHJY7w2toY
bAeZMl3Y05Ca76EA7XDdoltE57SUS1Zzd+wDRzRD0IZO8KVk+Z5/PzzvV4l9lnDJ
X63fptInbJpyk0xYKLMFquOY7Yy5mlI9de7424CScePo9Nua3GAakfi4zk3i4Auz
2eaoU/S5uXt605OydkSLLz99BAyJwmazzf/qPyYcPWMw/b+gHxw=
=pRcC
-----END PGP SIGNATURE-----
来源文件是一个具有特定结构的 PGP 签名消息。消息中的哈希用于 Helm 验证完整性,PGP 签名用于验证来源。
使用来源文件有两个步骤:
1.
生成来源文件
:要生成来源文件,你需要有一个 PGP 密钥对。在使用
helm package
命令创建包时,可以告诉 Helm 对包进行签名:
$ helm package --sign --key 'bugs@acme.example.com' \
--keyring path/to/keyring mychart
这些额外的标志将告诉 Helm 创建来源文件。
--sign
标志启用签名,
--key
标志指定要使用的私钥名称,
--keyring
标志指定包含用于签名的私钥的密钥环的位置。当 Helm 创建图表存档时,它还会在旁边创建
.prov
文件。
2.
上传和验证
:来源文件应与图表存档一起上传,并可从图表仓库下载。
验证过程与生成过程相反,它内置于
helm install
、
helm upgrade
和
helm pull
等命令中,也可以通过
helm verify
命令使用。
Helm 可以处理本地同时有存档和来源文件的情况,以及图表位于远程仓库的情况。
为了说明本地同时有两个文件的情况,我们可以使用
helm verify
命令:
$ helm verify --keyring path/to/keyring mychart-0.1.0.tgz
验证命令将告诉 Helm 检查哈希和签名。
--keyring
标志告诉 Helm 包含与图表签名时使用的私钥匹配的公钥的 PGP 密钥环的位置。这可以是密钥环或非 ASCII 装甲格式的公钥。Helm 将查找
mychart-0.1.0.tgz.prov
文件并使用它进行检查。
在
mylib
图表上运行验证命令如下:
$ helm verify mylib-0.1.0.tgz --keyring public.key
这将输出:
Signed by: Matthew Farina
Using Key With Fingerprint: 672C657BE06B4B30969C4A57461449C25E36B98E
Chart Hash Verified: sha256:d312aea39acf7026f39edebd315a11a52d29a96a8d68737ead11
0ac0c0a1163d
如果你在 Helm 仓库中有一个图表,Helm 在下载图表时会下载来源文件。例如:
$ helm install --verify --keyring public.key myrepo/mychart
当 Helm 获取图表存档时,它还会下载来源文件,验证签名,并验证哈希。
公钥应该通过与图表和来源文件不同的渠道共享。
如果在验证过程中出现问题,Helm 将提供错误信息并以非零退出代码退出。
1.4 GNU 隐私保护
从 GNU 隐私保护 (GPG) 2.1 版本开始,密钥以新的密钥盒格式存储。这种新格式与 PGP 规范和格式不兼容。这意味着如果你使用 GPG,在处理密钥时需要一些额外的步骤。以下命令为你在使用 GPG 时提供参考:
- 可以使用以下命令将你的秘密密钥从 GPG 导出为 PGP 格式:
gpg --export-secret-keys > secring.gpg
- 可以使用以下命令将公钥从 GPG 导出为 PGP 格式:
gpg --export > pubring.gpg
- 可以使用以下命令将 ASCII 装甲格式的公钥转换为二进制格式:
gpg --dearmor < pgp_key.asc > public.key
pgp_key.asc
是 ASCII 装甲密钥文件的名称,
public.key
是同一密钥的二进制格式名称。这个
public.key
文件可以作为密钥环传递给 Helm 进行验证。
如果你在使用 GPG 时使用了密码或硬件安全设备,可能无法导出私钥。在这种情况下,可以使用 Helm GPG 插件。它提供了命令和一种通过 GPG 直接处理来源文件的方法。
验证图表是否来自你期望的来源以及内容是否未更改是保障软件供应链安全的有用步骤。
1.5 自定义资源定义
Kubernetes 自定义资源定义 (CRDs) 提供了一种扩展 Kubernetes API 的方法,Helm 提供了将它们作为图表一部分进行安装的方法。
1.5.1 自定义资源定义、Kubernetes API 及一些注意事项
CRDs 为集群的所有用户提供了一种扩展 Kubernetes API 的方法。它们添加了新的资源类型,即自定义资源,可以与 Kubernetes 自带的资源类型一起上传到集群。CRDs 提供了一个模式,并可以描述同一资源的多个版本。它们是共享的全局资源。
集群中的 CRDs 可以更新以更改 API。这可以是更改或更新现有 API 版本的模式,或者为 API 添加新版本。Kubernetes 社区建议在 API 发生重大更改时增加 API 版本,但向后兼容的更改是可以接受的。Kubernetes 内部并没有强制执行这一建议。例如,向 API 添加可选字段是向后兼容的,但添加新的必需字段则不是。对 CRDs 的更改会影响集群的所有用户。
当从集群中删除一个 CRD 时,基于它的所有自定义资源也会被删除。这适用于集群的所有用户,因为 CRDs 是集群范围的资源。在多租户集群中,当一个租户删除一个 CRD 时,所有租户基于该 CRD 的自定义资源都会被删除。
CRDs 之所以这样工作,是因为它们被设计为集群级别的扩展。在对 CRDs 的回顾中,Kubernetes 的创始人之一 Brendan Burns 将它们的三个目标描述为:
1. 一种动态向 Kubernetes 添加新 API 类型的简单方法。
2. 在不显著增加 Kubernetes 集群操作员额外负担的情况下实现 API 可扩展性。
3. 为终端用户集群启用一个增值扩展的生态系统。
在开发 Kubernetes API 扩展时,还开发了另一种扩展 API 的方法,但这种方法需要集群操作员和扩展开发者做更多的工作。CRDs 简化了这一体验。
CRDs 在概念上类似于操作系统中的内核模块和扩展。
1.5.2 管理图表使用的 CRDs 的方法
有两种基于 Helm 的方法来管理图表使用的 CRDs。选择使用哪种方法通常取决于需要安装你的图表的人的需求和环境配置。
1.5.2.1 使用
crds
目录
crds
目录是一个特殊的目录,你可以将其添加到图表中以存放你的 CRDs。Helm 将在安装其他资源之前安装 CRDs。这确保了 CRDs 可供图表中可能利用它们的任何自定义资源或控制器使用。
crds
目录中的 CRDs 与 Helm 安装的其他资源不同。这些文件不是模板化的。这对于我们即将介绍的 CRD 管理工作流很有用。Helm 不会像处理其他资源那样升级或删除 CRDs。升级 CRDs 会更改集群中所有自定义资源实例的 API 表面,而删除 CRDs 会删除所有用户的所有自定义资源。在处理这些集群范围的更改时,你需要使用一个配套工具,如 Kubernetes 的命令行工具
kubectl
。
由于 CRDs 会更改 Kubernetes API,安装你的图表的人可能没有权限安装、升级或删除它们。如果你将应用程序打包分发给其他公司或公众,就会出现这种情况。一些集群管理员会限制对这些功能的访问,作为其安全访问控制的一部分。
crds
目录中的 CRDs 可以从图表中提取出来,并直接与
kubectl
等工具一起使用。这使得如果安装图表的人没有权限,可以将 CRDs 传递给有权限的人进行安装。提取的 CRDs 也可以用于使用其他工具升级集群中的 CRDs。
1.5.2.2 使用第二个图表
另一种基于 Helm 的方法是使用一个包含 CRDs 的第二个图表,同时提供一种在通过自定义资源使用 CRDs 之前安装它们的顺序。这种方法通过 Helm 提供了更细致的控制。
使用第二个图表可以让你:
1. 对 CRDs 使用 Helm 模板和正常的
templates
目录。
2. Helm 将管理 CRDs 的生命周期,包括卸载和升级。如果你希望在卸载图表后保留 CRD 安装,可以设置注解
"helm.sh/resource-policy": keep
来告诉 Helm 跳过卸载该资源。
3. 如果你在应用程序中遇到问题,并使用卸载和重新安装的方法来尝试解决问题,单独图表中的 CRDs 不会被删除。
这个第二个图表可以通过松散耦合(说明中告诉人们先安装它)或紧密耦合(将其设置为依赖项)的方式进行安装。如果包含 CRDs 的图表被设置为依赖项,使用场景应该是它只安装一次,因为它设置的是集群范围的资源。
当 Helm 管理 CRDs 时,在处理升级和删除情况时需要特别小心。例如,如果安装了两个版本的安装 CRDs 的图表,需要确保旧版本不会覆盖新版本,并且新版本不会破坏集群中使用旧版本的其他人的功能。这可能会在两个人安装不同版本的安装 CRDs 的图表时发生。在多租户集群中,不同的集群用户可能彼此不知情,因此确保一个集群用户不会破坏另一个集群用户的工作负载非常重要。
在安装和使用 CRDs 时,Helm 开发者建议在所有生命周期步骤中特别小心,以确保图表的用户不会遇到意外破坏生产工作负载的情况。
1.6 总结
Helm 图表不仅仅是模板的集合。它们处理依赖关系、可以包含模式、提供事件钩子机制、可以包含测试,并且具有安全功能。这些特性使 Helm 成为解决包管理问题的强大而可靠的解决方案。
2. Helm 高级特性的操作流程与对比
2.1 测试操作流程总结
为了更清晰地了解如何在 Helm 中进行测试,下面将测试操作流程以表格形式呈现:
| 步骤 | 操作命令 | 说明 |
| — | — | — |
| 1 |
helm install boost .
| 从图表根目录安装
booster
图表,使其实例运行 |
| 2 |
helm test boost
| 当图表实例运行后,执行测试,并输出测试状态和相关信息 |
同时,使用 mermaid 绘制测试操作的流程图如下:
graph LR
A[开始] --> B[安装图表]
B --> C{图表是否运行?}
C -- 是 --> D[执行测试]
C -- 否 --> B
D --> E[输出测试结果]
E --> F[结束]
2.2 安全验证操作流程
安全验证是 Helm 中保障图表来源和完整性的重要环节,其操作流程如下表所示:
| 步骤 | 操作命令 | 说明 |
| — | — | — |
| 1 |
helm package --sign --key 'bugs@acme.example.com' --keyring path/to/keyring mychart
| 使用
helm package
命令创建包并签名,生成
.prov
来源文件 |
| 2 | 将来源文件与图表存档一起上传到仓库 | 确保来源文件可从图表仓库下载 |
| 3 |
helm verify --keyring path/to/keyring mychart-0.1.0.tgz
(本地验证)或
helm install --verify --keyring public.key myrepo/mychart
(远程验证) | 执行验证操作,检查哈希和签名 |
对应的 mermaid 流程图如下:
graph LR
A[开始] --> B[生成来源文件]
B --> C[上传文件到仓库]
C --> D{选择验证方式}
D -- 本地 --> E[本地验证]
D -- 远程 --> F[远程验证]
E --> G[输出验证结果]
F --> G
G --> H[结束]
2.3 两种管理 CRDs 方法的对比
Helm 提供了两种管理图表使用的 CRDs 的方法,下面通过表格对这两种方法进行对比:
| 方法 | 使用
crds
目录 | 使用第二个图表 |
| — | — | — |
| 安装顺序 | 在安装其他资源之前安装 CRDs | 可通过松散或紧密耦合方式安装,确保在使用 CRDs 之前完成安装 |
| 模板化 | 文件不是模板化的 | 可对 CRDs 使用 Helm 模板和
templates
目录 |
| 生命周期管理 | Helm 不升级或删除 CRDs,需使用
kubectl
等工具处理 | Helm 管理 CRDs 的生命周期,可设置注解保留资源 |
| 应对问题能力 | 提取的 CRDs 可用于安装和升级 | 卸载和重新安装应用程序时,CRDs 不会被删除 |
2.4 总结与建议
通过对 Helm 高级特性的详细介绍,我们了解到测试、安全验证和自定义资源管理在 Helm 中的重要性。在实际应用中,建议开发者:
- 在开发图表时,积极添加测试用例,使用 Chart 测试工具进行全面测试,确保图表的稳定性和可靠性。
- 重视图表的安全验证,使用 PGP 签名和来源文件,保障软件供应链的安全。
- 根据实际需求和环境配置,选择合适的方法管理 CRDs,避免因操作不当影响集群中其他用户的工作负载。
总之,充分利用 Helm 的这些高级特性,可以使开发者更高效地管理和部署应用程序,提升软件的质量和安全性。
超级会员免费看
50

被折叠的 条评论
为什么被折叠?



