本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
APIServer dry-run 和 kubectl diff
声明式配置管理,又称配置即代码,是 Kubernetes 的主要优势之一。它允许用户提交集群的期望状态,并跟踪不同版本,通过 CI/CD 流水线改进审计和自动化。Apply 工作组正在努力弥补一些不足,并很高兴地宣布 Kubernetes 1.13 将服务器端 Dry-Run 和 kubectl diff
提升到 Beta 阶段。这两个功能是 Kubernetes 声明式模型的重大改进。
挑战
为了在 Kubernetes 中获得无缝的声明式体验,仍缺少一些部分,我们试图解决其中一些问题
- 虽然编译器和 linter 在检测代码拉取请求中的错误方面做得很好,但 Kubernetes 配置文件缺少良好的验证。现有的解决方案是运行
kubectl apply --dry-run
,但这会运行一个**本地** Dry-Run,它不与服务器通信:它没有服务器验证,也不会通过验证准入控制器。例如,自定义资源名称只在服务器上进行验证,因此本地 Dry-Run 无济于事。 - 由于多种原因,可能很难知道服务器将如何应用您的对象
- 默认值会设置一些可能意想不到的值,
- 变更 Webhook 可能会设置字段或覆盖/更改某些值。
- 补丁和合并可能会产生令人惊讶的效果,并导致意想不到的对象。例如,很难知道列表在合并后将如何排序。
工作组已尝试解决这些问题。
APIServer Dry-Run
APIServer Dry-Run 旨在解决这两个问题
- 它允许将对 apiserver 的单个请求标记为“Dry-Run”,
- apiserver 保证 Dry-Run 请求不会持久化到存储中,
- 请求仍然像典型的请求一样处理:字段被默认设置,对象被验证,它通过验证准入链和变更准入链,然后最终对象像往常一样返回给用户,而不会被持久化。
尽管动态准入控制器不应该对每个请求产生副作用,但只有当所有准入控制器明确声明它们没有任何 Dry-Run 副作用时,Dry-Run 请求才会处理。
如何启用它
服务器端 Dry-Run 通过功能门启用。现在该功能在 1.13 中处于 Beta 阶段,它应该默认启用,但仍然可以使用 kube-apiserver --feature-gates DryRun=true
启用/禁用。
如果您有动态准入控制器,您可能需要修复它们以
- 当 Webhook 请求中指定了 Dry-Run 参数时,删除所有副作用,
- 在
admissionregistration.k8s.io/v1beta1.Webhook
对象的sideEffects
字段中指定该对象在 Dry-Run 时没有副作用(或根本没有副作用)。
如何使用它
您可以通过使用 kubectl apply --server-dry-run
从 kubectl 触发该功能,这将用 dryRun 标志装饰请求,并返回应用后的对象,如果失败则返回错误。
Kubectl diff
APIServer Dry-Run 很方便,因为它允许您查看对象将如何处理,但如果对象很大,则很难准确识别更改了什么。kubectl diff
通过显示当前“活动”对象和新的“Dry-Run”对象之间的差异来精确地实现您想要的功能。它使得只关注对对象所做的更改、服务器如何合并这些更改以及变更 Webhook 如何影响输出变得非常方便。
如何使用它
kubectl diff
旨在尽可能类似于 kubectl apply
:kubectl diff -f some-resources.yaml
将显示 yaml 文件中资源的差异。甚至可以使用 KUBECTL_EXTERNAL_DIFF 环境变量使用自己选择的 diff 程序,例如
KUBECTL_EXTERNAL_DIFF=meld kubectl diff -f some-resources.yaml
接下来
工作组仍在努力改进其中一些功能
- 服务器端应用正在通过为字段添加所有权语义来改进应用场景!它还将改进对 CRD 和联合的支持!
diff
中缺少一些kubectl apply
功能,但可能很有用,例如按标签过滤或显示修剪资源的能力。- 最终,kubectl diff 将使用服务器端应用!
说明
标志kubectl apply --server-dry-run
在 v1.18 中已弃用。请使用标志 --dry-run=server
在 kubectl apply
和其他子命令中使用服务器端 Dry-Run。