本文发布时间已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。

APIServer dry-run 和 kubectl diff

声明式配置管理,也称为配置即代码,是 Kubernetes 的关键优势之一。它允许用户提交集群的期望状态,并跟踪不同的版本,通过 CI/CD 管道改进审计和自动化。“Apply 工作组”正在努力解决一些差距,并很高兴地宣布 Kubernetes 1.13 将服务端干运行和 kubectl diff 提升为 Beta 版。这两个功能是对 Kubernetes 声明式模型的重大改进。

挑战

为了获得 Kubernetes 的无缝声明式体验,仍然缺少一些部分,我们试图解决其中的一些问题

  • 虽然编译器和 linter 在检测代码的拉取请求中的错误方面做得很好,但 Kubernetes 配置文件缺少良好的验证。现有的解决方案是运行 kubectl apply --dry-run,但这会运行与服务器不通信的本地干运行:它没有服务器验证,也不会通过验证准入控制器。例如,自定义资源名称仅在服务器上验证,因此本地干运行不会有帮助。
  • 由于多种原因,可能很难知道服务器将如何应用你的对象
    • 默认设置会将某些字段设置为可能意外的值,
    • 修改 Webhook 可能会设置字段或覆盖/更改某些值。
    • Patch 和合并可能会产生令人惊讶的效果,并导致意外的对象。例如,很难知道列表在合并后将如何排序。

工作组试图解决这些问题。

APIServer 干运行

实施了 APIServer 干运行来解决这两个问题

  • 它允许将对 apiserver 的单个请求标记为“干运行”,
  • apiserver 保证干运行请求不会持久保存到存储中,
  • 该请求仍然像典型的请求一样处理:字段被设置为默认值,对象被验证,它通过验证准入链和修改准入链,然后将最终对象返回给用户,就像通常一样,而不会被持久保存。

虽然动态准入控制器不应在每个请求上产生副作用,但只有当所有准入控制器明确声明它们没有任何干运行副作用时,才会处理干运行请求。

如何启用它

服务端干运行通过功能门启用。现在该功能在 1.13 中为 Beta 版,它应该默认启用,但仍然可以使用 kube-apiserver --feature-gates DryRun=true 启用/禁用。

如果你有动态准入控制器,你可能需要修复它们,以便

  • 当在 Webhook 请求上指定干运行参数时,删除任何副作用,
  • admissionregistration.k8s.io/v1beta1.Webhook 对象的 sideEffects 字段中指定,以指示该对象在干运行(或根本没有)上没有副作用。

如何使用它

你可以通过使用 kubectl apply --server-dry-run 从 kubectl 触发该功能,这将使用 dryRun 标志修饰请求,并返回它将应用的对象,或者如果它将失败,则返回一个错误。

Kubectl diff

APIServer 干运行很方便,因为它让你看到对象将如何处理,但是如果对象很大,则可能很难准确识别更改的内容。kubectl diff 通过显示当前“活动”对象和新的“干运行”对象之间的差异,准确地执行你想要的操作。它使你非常方便地专注于仅对对象进行的更改、服务器如何合并这些更改以及修改 Webhook 如何影响输出。

如何使用它

kubectl diff 的目的是尽可能与 kubectl apply 相似:kubectl diff -f some-resources.yaml 将显示 yaml 文件中资源的差异。甚至可以使用 KUBECTL_EXTERNAL_DIFF 环境变量来使用他们选择的差异程序,例如

KUBECTL_EXTERNAL_DIFF=meld kubectl diff -f some-resources.yaml

下一步

工作组仍在忙于尝试改进其中一些内容

  • 服务端应用正在尝试通过向字段添加所有者语义来改进应用场景!它还将改进对 CRD 和联合的支持!
  • diff 中缺少一些 kubectl apply 功能,这些功能可能很有用,例如按标签过滤或显示修剪的资源。
  • 最终,kubectl diff 将使用服务端应用!