本页面介绍如何解决控制器争夺问题。此类争夺会消耗大量资源并降低性能。控制器争夺也称为资源争用。
Config Sync 会监控它在集群上应用的对象,并还原对可靠来源中声明的值进行的更改。如果这些更改是由另一个控制器进行,则资源可能会在竞争控制器所需的状态之间来回切换。此行为的一个表现是 metadata.generation
和 metadata.resourceVersion
字段快速增加。因此,如果某个托管式对象每分钟更新 5 次以上,则 Config Sync 会检测争夺情况,记录偏移,并报告 RootSync
或 RepoSync
对象状态的错误。
Config Sync 具有特殊逻辑来检测多个 RootSync
和 RepoSync
对象之间进行的争夺。对于 RepoSync
对象,如果协调器发现对象已由另一个协调器管理,则会跳过进一步的更新。对于 RootSync
对象,协调器会尝试采用它配置为进行管理的任何对象,除非它由另一个 RootSync
对象管理。这样可以防止 Config Sync 协调器本身之间发生争夺,并报告所涉及的所有 RootSync
和 RepoSync
对象的状态错误。
识别控制器争夺
您可以使用 nomos status
命令或是通过检查 RootSync
或 RepoSync
对象中的状态字段来查看争夺错误。
如果您没有安装 nomos
命令行工具,可以通过运行以下命令来查看 RootSync
协调器的日志:
kubectl logs -n config-management-system \
--selector "app=reconciler,configsync.gke.io/sync-name=root-sync" \
--container reconciler
如需过滤特定的 RepoSync
协调器,请运行以下命令:
kubectl logs -n config-management-system \
--selector "app=reconciler,configsync.gke.io/sync-namespace=NAMESPACE" \
--container reconciler
将 NAMESPACE
替换为您在其中创建了命名空间级可靠来源的命名空间。
如果您在结果中看到 KNV2005
,则表明存在控制器争夺。
以下错误消息是您可能会在日志中看到的错误类型的示例:
KNV2005: detected excessive object updates, approximately 6 times per
minute. This may indicate Config Sync is fighting with another controller over
the object.
调查控制器争夺
如需查找有关任何控制器争夺的更多信息,请运行以下命令,以监控对资源的 YAML 文件进行的更新:
kubectl get RESOURCE OBJECT_NAME \
--namespace NAMESPACE \
--watch -o yaml
请替换以下内容:
RESOURCE
:所争夺的资源的种类。OBJECT_NAME
:所争夺的对象的名称。NAMESPACE
:所争夺的资源所在的命名空间。
日志结果指定您需要添加的资源、对象名称和命名空间。
此命令会在更新应用到 API 服务器后返回资源的状态流。可使用文件比较工具来比较输出内容。
解决控制器争夺
您可以通过多种方式解决控制器争夺。请选择最适合您的 Config Sync 设置的方法:
- 更新来源中的资源清单,以匹配另一个控制器所需的值。
- 从来源中移除相关字段,让另一个控制器管理它。
- 停用或卸载另一个控制器。
- 从来源中移除资源,并通过手动方式或使用可容忍特定更改或协同管理的自定义控制器来管理它。
- 如果您拥有导致资源争用的控制器,并且所更改的字段不在可靠来源中,请更新您的控制器以执行修补,而不是进行更新。这样,Config Sync 便会允许更改,不会还原更改。
还有一些资源应属于其他控制器(例如,有些操作器会安装或维护 CRD)。这些其他控制器会自动移除 Config Sync 特有的任何元数据。如果 Kubernetes 集群中的其他组件会移除 Config Sync 元数据,请停止使用 Config Sync 管理相应资源。如需了解如何执行此操作,请参阅停止管理托管式对象。
或者,如果您不希望 Config Sync 还原对集群中托管式对象进行的更改,则可以将 client.lifecycle.config.k8s.io/mutation: ignore
注解添加到您希望 Config Sync 忽略变更的对象。如需了解如何执行此操作,请参阅忽略对象变更。
后续步骤
- 如果您仍然遇到问题,请检查您的问题是否为已知问题。