您如何确保 Kubernetes (K8s) 集群的稳定性?您如何知道您的清单在语法上是有效的?您确定您没有任何无效的数据类型吗?是否有任何必填字段缺失?
通常,我们只有在最糟糕的时候才会意识到这些错误配置:当我们尝试部署新的清单时。
专业的工具和“左移”方法使得在 Kubernetes schema 应用到集群之前对其进行验证成为可能。本文讨论了如何避免错误配置以及哪些工具是最佳选择。
TL;DR(太长不看)
运行 schema 验证测试非常重要,而且越早越好。如果所有机器(例如,本地开发环境、持续集成 [CI] 等)都可以访问您的 Kubernetes 集群,请在每次代码更改时以服务器模式运行
kubectl --dry-run
。如果这不可行,并且您想离线执行 schema 验证测试,请将 kubeconform 与策略执行工具一起使用,以获得最佳的验证覆盖率。
Schema 验证工具
验证 Kubernetes 清单的状态似乎是一项微不足道的任务,因为 Kubernetes 命令行界面 (CLI) kubectl 可以在资源应用到集群之前对其进行验证。您可以使用 dry-run 标志 (--dry-run=client/server
) 在指定 kubectl create
或 kubectl apply
命令时验证 schema;这些命令将执行验证,而不会将 Kubernetes 资源应用到集群。
但我可以向您保证,实际上它更加复杂。运行中的 Kubernetes 集群必须获取要验证的资源集的 schema。因此,当将清单验证纳入 CI 流程时,您还必须管理连接和凭据才能执行验证。当处理多个环境(例如,生产环境、开发环境等)中的多个微服务时,这变得更具挑战性。
Kubeval 和 kubeconform 是 CLI 工具,开发用于验证 Kubernetes 清单,而无需运行 Kubernetes 环境。由于 kubeconform 的灵感来自 kubeval,因此它们的操作方式类似;验证是针对从 OpenAPI 规范 (swagger.json) 为每个 Kubernetes 版本创建的预生成 JSON schema 执行的。所有剩下的 要运行 schema 验证测试的就是将工具可执行文件指向单个清单、目录或模式。

(Eyar Zilberman,CC BY-SA 4.0)
工具比较
现在您已经了解了可用于 Kubernetes schema 验证的工具,让我们比较一下一些核心能力——错误配置覆盖率、速度测试、对不同版本的支持、自定义资源定义支持和文档——在
- kubeval
- kubeconform
- kubectl dry-run 客户端模式
- kubectl dry-run 服务器模式
错误配置覆盖率
我戴上 QA 的帽子,生成了一些(基本的)Kubernetes 清单文件,其中包含一些有意为之的错误配置,然后针对所有四种工具运行它们。
错误配置/工具 |
kubeval / |
kubectl dry-run |
kubectl dry-run |
---|---|---|---|
API 弃用 | ✅ 已捕获 | ✅ 已捕获 | ✅ 已捕获 |
无效的 Kind 值 | ✅ 已捕获 | ❌ 未捕获 | ✅ 已捕获 |
无效的标签值 | ❌ 未捕获 | ❌ 未捕获 | ✅ 已捕获 |
无效的协议类型 | ✅ 已捕获 | ❌ 未捕获 | ✅ 已捕获 |
无效的 Spec 键 | ✅ 已捕获 | ✅ 已捕获 | ✅ 已捕获 |
缺少镜像 | ❌ 未捕获 | ❌ 未捕获 | ✅ 已捕获 |
错误的 K8s 缩进 | ✅ 已捕获 | ✅ 已捕获 | ✅ 已捕获 |
总结:所有错误配置都由 kubectl
dry-run 服务器模式捕获。
一些错误配置被所有工具捕获
- 无效的 Spec 键:被所有工具成功捕获!
- API 弃用:被所有工具成功捕获!
- 错误的 k8s 缩进:被所有工具成功捕获!
但是,一些工具的结果喜忧参半
- 无效的 Kind 值:被 Kubeval / Kubeconform 捕获,但被 Kubectl 客户端遗漏。
- 无效的协议类型:被 Kubeval / Kubeconform 捕获,但被 Kubectl 客户端遗漏。
- 无效的标签值:被 Kubeval / Kubeconform 和 Kubectl 客户端都遗漏。
- 缺少镜像:被 Kubeval / Kubeconform 和 Kubectl 客户端都遗漏。
结论:运行 kubectl dry-run 服务器模式捕获了所有错误配置,而 kubeval/kubeconform 遗漏了其中两个。有趣的是,运行 kubectl dry-run 客户端模式几乎没用,因为它遗漏了一些明显的错误配置,并且还需要连接到正在运行的 Kubernetes 环境。
- 所有 schema 验证测试都是针对 Kubernetes 1.18.0 版本执行的。
- 由于 kubeconform 基于 kubeval,因此当针对包含错误配置的文件运行时,它们提供相同的结果。
- kubectl 是一种工具,但每种模式(客户端或服务器)都会产生不同的结果(如您从表格中看到的)。
基准速度测试
我使用 hyperfine 来基准测试每个工具的执行时间。首先,我针对所有包含错误配置的文件(总共七个文件)运行它。然后,我针对 100 个 Kubernetes 文件(所有文件都包含相同的配置)运行它。
针对七个包含不同 Kubernetes schema 错误配置的文件运行工具的结果
针对 100 个包含有效 Kubernetes schema 的文件运行工具的结果
结论:虽然 kubeconform (#1)、kubeval (#2) 和 kubectl --dry-run=client
(#3) 在两个测试中都提供了快速结果,但 kubectl --dry-run=server
(#4) 速度较慢,尤其是在评估 100 个文件时。但在我看来,60 秒生成结果仍然是一个不错的结果。
Kubernetes 版本支持
kubeval 和 kubeconform 都接受 Kubernetes schema 版本作为标志。虽然这两种工具很相似(如前所述,kubeconform 基于 kubeval),但关键区别之一是每种工具都依赖于自己的一组预生成的 JSON schema
- Kubeval: instrumenta/kubernetes-json-schema(上次提交:133f848,于 2020 年 4 月 29 日)
- Kubeconform: yannh/kubernetes-json-schema(上次提交:a660f03,于 2021 年 5 月 15 日)
截至 2021 年 5 月,kubeval 仅支持高达 1.18.1 的 Kubernetes schema 版本,而 kubeconform 支持最新的 Kubernetes schema 版本 1.21.0。对于 kubectl,情况有点棘手。我不知道哪个版本的 kubectl 引入了 dry run,但我使用 Kubernetes 1.16.0 版本尝试过,它仍然有效,所以我知道它在 Kubernetes 1.16.0–1.18.0 版本中可用。
如果您想迁移到新的 Kubernetes 版本,则支持的 Kubernetes schema 的多样性尤其重要。使用 kubeval 和 kubeconform,您可以设置版本并开始评估哪些配置必须更改才能支持集群升级。
结论:kubeconform 拥有所有不同 Kubernetes 版本可用的所有 schema,并且也不需要 Minikube 设置(kubectl 需要),这使其在比较这些功能与其替代方案时成为更出色的工具。
其他需要考虑的事项
自定义资源定义 (CRD) 支持
kubectl dry-run 和 kubeconform 都支持 CRD 资源类型,而 kubeval 不支持。根据 kubeval 的文档,您可以传递一个标志给 kubeval,告诉它忽略缺失的 schema,这样在测试一堆清单时,即使只有部分清单是 CRD 资源类型,它也不会失败。
文档
Kubeval 是一个比 kubeconform 更受欢迎的项目;因此,它的社区和文档更加广泛。Kubeconform 没有官方文档,但它有一个 写得很好的 README 文件,其中很好地解释了其功能。有趣的是,尽管 Kubernetes 原生工具(如 kubectl)通常文档齐全,但真的很难找到理解 dry-run
标志的工作原理及其局限性所需的信息。
结论:尽管 kubeconform 不如 kubeval 那么出名,但在我看来,CRD 支持和足够好的文档使其成为赢家。
使用这些工具验证 Kubernetes schema 的策略
现在您已经了解了每种工具的优缺点,以下是在 Kubernetes 生产规模开发流程中利用它们的一些最佳实践
- ⬅️ 左移:如果可能,最好的设置是在每次代码更改时运行
kubectl --dry-run=server
。您可能无法做到这一点,因为您不能允许组织中的每个开发人员或 CI 机器都连接到您的集群。因此,第二好的方法是运行 kubeconform。 - ❓ 因为 kubeconform 没有覆盖所有常见的错误配置,所以建议在每次代码更改时将其与策略执行工具一起运行,以填补覆盖率的空白。
- ❓ 购买 vs. 构建:如果您喜欢 工程开销,那么 kubeconform + conftest 是获得良好覆盖率的工具的绝佳组合。或者,有一些工具可以为您提供开箱即用的体验,以帮助您节省时间和资源,例如 Datree(其 schema 验证由 kubeconform 提供支持)。
- ❓ 在 CD 步骤中,连接到您的集群应该不是问题,因此您应该始终在部署新代码更改之前运行
kubectl --dry-run=server
。 - ❓ 在服务器模式下使用 kubectl dry-run 的另一种选择是在不连接到 Kubernetes 环境的情况下运行 Minikube +
kubectl --dry-run=server
。这种技巧的缺点是您还必须像生产环境一样设置 Minikube 集群(即,相同的卷、命名空间等),否则在尝试验证 Kubernetes 清单时会遇到错误。
感谢 Yann Hamon 创建了 kubeconform——它太棒了!没有您,这篇文章是不可能完成的。感谢您的所有指导。
本文最初出现在 Datree.io 上,并经许可转载。
评论已关闭。