这篇文章已超过一年。较早的文章可能包含过时内容。请检查页面信息自发布以来是否已失效或不正确。
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:它没有服务器验证,也不会通过 validating admission controller。例如,Custom Resource 名称仅在服务器上验证,因此本地 dry-run 没有帮助。 - 由于多种原因,很难知道服务器将如何应用你的对象
- 默认值可能会将某些字段设置为潜在的非预期值,
- Mutating webhook 可能会设置字段或覆盖/更改某些值。
- Patch 和合并可能会产生意想不到的效果并导致意外的对象。例如,合并后很难知道列表的排序方式。
工作组已尝试解决这些问题。
APIServer dry-run
实现APIServer dry-run 是为了解决这两个问题
- 它允许将发送到 apiserver 的单个请求标记为 "dry-run",
- apiserver 保证 dry-run 请求不会持久化到存储,
- 请求仍然像典型请求一样被处理:字段会被默认赋值,对象会被验证,它会通过 validating admission 链和 mutating admission 链,然后最终对象会像正常情况一样返回给用户,而不会持久化。
尽管动态 admission controller 不应该对每个请求产生副作用,但只有当所有 admission controller 都明确声明它们没有 dry-run 副作用时,dry-run 请求才会被处理。
如何启用
服务器端 dry-run 通过一个 feature-gate 启用。由于该特性在 1.13 版本中是 Beta,它应该默认启用,但仍然可以通过使用 kube-apiserver --feature-gates DryRun=true
进行启用/禁用。
如果你有动态 admission controller,你可能需要修改它们以:
- 当 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”对象之间的差异。这使得只关注对象发生的变更、服务器如何合并这些变更以及 mutating 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
未来展望
工作组仍在忙于改进其中一些内容
- 服务器端 apply 正在尝试通过为字段添加所有者语义来改进 apply 场景!它还将改进对 CRD 和 unions 的支持!
- kubectl diff 缺少一些 kubectl apply 的特性,但可能很有用,比如按标签过滤或显示被修剪的资源。
- 最终,kubectl diff 将使用服务器端 apply!
注意
标志kubectl apply --server-dry-run
在 v1.18 中已弃用。请使用标志 --dry-run=server
在 kubectl apply
和其他子命令中使用服务器端 dry-run。