排查 Config Sync 问题

本页可帮助您排查 Config Sync 安装问题。

尽管我们一直努力为您提供 Config Sync 始终可用的体验,但在某些情况下,您可能遇到需要排查安装问题的情况。本指南将介绍一些可以帮助您解决所遇到的常见问题的常见机制。

一般最佳做法

nomos status 是你的朋友

我们投入了大量精力尝试通过 nomos status 命令确保您可以轻松获得尽可能多的数据。nomos status 为您提供汇总数据和错误,帮助您了解 Config Sync 安装发生的情况。以下信息可通过 nomos status 获得:

  • 每个集群的安装状态
  • 同步错误(从 Git 读取和协调更改)

用于高级使用的 kubectl get KRM 资源

Config Sync 由多个自定义资源组成,可以使用 kubectl 单独查询以确切了解每个对象的状态。

有关 Config Sync 管理的 Kubernetes 资源的一些要点:

  • config-management-system 是用于运行 Config Sync 所有核心系统组件的命名空间
  • configmanagement.gke.io/v1configsync.gke.io 是我们用于所有自定义资源的版本前缀。

通过运行以下命令,您可以获取自定义资源的完整列表:

kubectl api-resources | grep -E "configmanagement.gke.io|configsync.gke.io"

通过运行 kubectl get RESOURCE -o yaml,可以使用各个自定义资源。

例如,您可以在下一个命令的输出中检查 RootSync 对象:

kubectl get rootsync -n config-management-system -o yaml

如需了解详情,请参阅探索 RootSync 和 RepoSync 对象

使用审核日志

审核日志是一种有用的调试工具。

如果您使用 Cloud Console 或 gcloud 命令行工具安装了 Config Sync,请完成以下步骤,以使用审核日志调查 Config Sync。

控制台

  1. 启用 GKE Connect/Hub API 审核日志。

    1. 在 Cloud Console 中,转到 IAM 审核日志页面。

      转到“审核日志”页面

    2. 在表格中,选中 GKE Connect/Hub API 复选框。

    3. 选中以下复选框:

      • 管理员读取
      • 数据读取
      • 数据写入
    4. 点击保存

  2. 转到日志浏览器页面。

    转到“日志浏览器”页面

  3. 查询构建器文本框中,添加以下过滤条件:

    resource.type="audited_resource" resource.labels.service="gkehub.googleapis.com"
    
  4. 点击运行查询

  5. 查询结果部分中,选择相关条目以详细了解事件。

CPU 不足

kubectl get events 的输出可能包含类型为 FailedScheduling 的事件。事件类似如下示例:

LAST SEEN   TYPE      REASON              OBJECT                                       MESSAGE
9s          Warning   FailedScheduling    pod/config-management-operator-74594dc8f6    0/1 nodes are available: 1 Insufficient cpu.

要修复此错误,请选择以下选项之一:

  • 将节点添加到现有 GKE 节点池
  • 创建具有更大节点的节点池。

有效但不正确的 ConfigManagement 对象

如果 ConfigManagement 对象有问题(不是因为 YAML 或 JSON 语法错误所致),从而导致安装失败,则 ConfigManagement 对象可能已在集群中实例化,但运行不正常。在这种情况下,您可以使用 nomos status 命令检查 ConfigManagement 对象中的错误。

对于没有问题的有效安装,其状态为 PENDINGSYNCED

对于无效的安装,其状态为 NOT CONFIGURED,并且系统会列出以下错误之一:

  • missing git-creds Secret
  • missing required syncRepo field
  • git-creds Secret is missing the key specified by secretType

为解决此问题,请更正配置错误。根据错误类型,您可能需要将 ConfigManagement 清单重新应用到集群。

如果问题的原因是您忘记创建 git-creds Secret,则 Config Sync 会在您创建该 Secret 后立即检测到它,这样您就无需重新应用配置。

ResourceGroup 字段不断变化

对于同步到集群的 Git 代码库,所有资源的协调状态会汇总到一个名为 ResourceGroup 的资源中。对于每个 RootSync 或 RepoSync 对象,系统会生成一个 ResourceGroup 来捕获应用于集群的资源集,并汇总其状态。

有时,您的 ResourceGroup 可以循环更新 ResourceGroup 的 spec。如果发生这种情况,您可能会注意到以下问题:

  • ResourceGroup 的 metadata.generation 在短时间内不断增长。
  • ResourceGroup spec 不断在变化。
  • ResourceGroup spec 不包含同步到集群的资源的 status.resourceStatuses

如果您观察到这些问题,则意味着您的 Git 代码库中有部分资源未能应用到集群。造成这些问题的原因是您缺少应用这些资源所需的权限。

您可以通过获取 RepoSync 资源状态来验证是否缺少这些权限:

kubectl get reposync repo-sync -n NAMESPACE -o yaml

NAMESPACE 替换为在其中创建了命名空间代码库的命名空间。

此外,您也可以使用 nomos status

如果您在状态中看到以下消息,则表示 NAMESPACE 中的协调器缺少应用资源所需的权限:

errors:
  - code: "2009"
    errorMessage: |-
      KNV2009: deployments.apps "nginx-deployment" is forbidden: User "system:serviceaccount:config-management-system:ns-reconciler-     default" cannot get resource "deployments" in API group "apps" in the namespace "default"

      For more information, see https://g.co/cloud/acm-errors#knv2009

如需解决此问题,您需要声明一个 RoleBinding 配置,向 ns-reconciler-NAMESPACE 服务帐号授予管理该命名空间中失败资源的权限。如需详细了解如何添加 RoleBinding,请参阅配置从命名空间代码库同步部分。

Git 代码库中有大量资源

当 RepoSync 或 RootSync 对象同步的 Git 代码库包含数千个资源的配置时,可能会导致 ResourceGroup 超过 etcd 对象的大小限制。发生这种情况时,您无法查看 Git 代码库中资源的汇总状态。您将无法查看汇总状态,您的代码库仍在同步。如果您在 RepoSync 或 RootSync 对象中没有看到任何错误,则表示 Git 代码库已成功同步到集群。

如需检查 ResourceGroup 资源是否超过 etcd 对象大小限制,您需要检查 ResourceGroup 资源状态和 ResourceGroup 控制器的日志:

  1. 使用以下命令检查 ResourceGroup 状态:

    • 要检查 RootSync,请运行以下命令。
     kubectl get resourcegroup.kpt.dev root-sync -n config-management-system
    
    • 要检查 RepoSync,请运行以下命令。
    # For the RepoSync:
    kubectl get resourcegroup.kpt.dev repo-sync -n NAMESPACE
    

    您应该会看到类似于以下示例的输出:

    NAME        RECONCILING   STALLED   AGE
    root-sync   True          False     35m
    

    如果 RECONCILING 列中的值为 True,则意味着 ResourceGroup 资源仍在协调。

  2. 使用以下命令检查 ResourceGroup 控制器的日志:

    kubectl logs deployment/resource-group-controller-manager -c manager -n resource-group-system
    

    如果您在输出中看到以下错误,则表示 ResourceGroup 资源过大,超出了 etcd 对象的大小限制:

    "error":"etcdserver: request is too large"
    

如需防止 ResourceGroup 过大,请减少 Git 代码库中的资源数量。例如,拆分代码库并使用一个包含多个 RepoSync 对象的 RootSync 对象,而不是仅使用一个 RootSync 对象来同步所有资源。

与 Git 代码库不同步

如果新提交内容被推送到您的 Git 代码库,但集群的 Config Sync 状态仍是 Synced 到旧提交内容(时间长于 spec.git.period),则您需要检查 git-sync 容器的日志:

# check git-sync logs for a root reconciler
kubectl logs -n config-management-system deployment/root-reconciler -c git-sync

# check git-sync logs for a namespace reconciler
kubectl logs -n config-management-system deployment/ns-reconciler-NAMESPACE -c git-sync

有可能 git-sync 无法从 Git 代码库同步,但 Reconciler 会继续从先前同步的提交同步。以下示例输出表明您遇到了 git-sync 问题:

"msg"="unexpected error syncing repo, will retry" "error"="Run(git fetch -f --tags --depth 1 origin develop): exit status 128: { stdout: "", stderr: "fatal: couldn't find remote ref develop\n" }"

这是 Config Sync 1.8.1 版及更低版本的已知问题。为解决此问题,您需要按照日志中的错误消息进行操作。您可能需要更新 Git 代码库或 RootSync 或 RepoSync 对象中的 spec.git 字段。

admission-webhook.configsync.gke.io 会拒绝更新/删除由已删除的 RootSync/RepoSync 管理的资源的请求

删除 RootSync 或 RepoSync 对象不会清理 Config Sync 注解和标签,并且如果集群中仍启用 Config Sync,Config Sync 准入网络钩子会拒绝尝试修改或删除这些资源的请求。

如果要保留这些代管式资源,您可以先针对在 Git 代码库中声明的每个代管式资源将 configmanagement.gke.io/managed 注释设置disabled 以取消管理这些资源。这将从代管式资源中移除 Config Sync 注释和标签,但不会删除这些资源。同步完成后,您可以移除 RootSync 或 RepoSync 对象。

如果意图删除这些代管式资源,您可以首先通过修改 RootSync 或 RepoSync 对象从空的 Git 目录进行同步来删除代管式资源。同步完成后,您可以移除 RootSync 或 RepoSync 对象。

如果在取消管理或删除代管式资源之前删除了 RootSync 或 RepoSync 对象,您可以重新添加回 RootSync 或 RepoSync 对象,取消管理或删除代管式资源,然后再次删除 RootSync 或 RepoSync 对象。

对错误消息进行问题排查

错误:权限遭拒

如果您在尝试配置 Config Sync 时收到类似于以下示例的错误,则您可能没有 GKE Hub Admin 角色:

Permission 'gkehub.features.create' denied on 'projects/PROJECT_ID/locations/global/features/configmanagement'

为确保您拥有所需的权限,请查看准备权限

错误:准许 Webhook 拒绝了请求

如果您在尝试对 Config Sync 管理的字段应用更改时收到以下错误,则表明您可能进行了有冲突的更改:

error: OBJECT could not be patched: admission webhook "v1.admission-webhook.configsync.gke.io"
denied the request: fields managed by Config Sync can not be modified

如果您在配置中声明字段并且代码库已同步到集群,Config Sync 将管理该字段。您尝试对该字段进行的任何更改都是有冲突的更改。

例如,如果带有 environment:prod 标签的代码库中有 Deployment 配置,并且尝试将该标签更改为集群中的 environment:dev,则会出现有冲突的更改,并且您将会收到之前的错误消息。但是,如果您向 Deployment 添加新标签(例如 tier:frontend),则不会发生冲突。

如果您希望 Config Sync 忽略对对象所做的任何更改,则可以添加忽略对象变更中所述的注释。

错误:准许网络钩子请求 i/o 超时

如果在协调器将配置应用于集群时收到以下错误:

KNV2009: Internal error occurred: failed calling webhook "v1.admission-webhook.configsync.gke.io": Post https://admission-webhook.config-management-system.svc:8676/admission-webhook?timeout=3s: dial tcp 10.1.1.186:8676: i/o timeout

这可能是由于防火墙屏蔽的网络钩子端口 8676 进入了控制平面网络。要解决此问题,请添加防火墙规则以允许端口 8676,Config Sync 准许 webhook 使用此端口来防止出现偏移。

错误:准入网络钩子连接遭拒

如果在协调器将配置应用于集群时收到以下错误:

KNV2009: Internal error occurred: failed calling webhook "v1.admission-webhook.configsync.gke.io": Post "https://admission-webhook.config-management-system.svc:8676/admission-webhook?timeout=3s": dial tcp 10.92.2.14:8676: connect: connection refused

这意味着“准许网络钩子”尚未就绪。您在引导 Config Sync 时可能会遇到暂时性错误。

如果问题仍然存在,请查看准许网络钩子部署,以查看其 Pod 是否可安排且运行状况良好。

kubectl describe deploy admission-webhook -n config-management-system

kubectl get pods -n config-management-system -l app=admission-webhook

错误:无法装载 Git Secret

如果您在 git-sync 容器尝试将代码库与 Secret 同步时收到以下错误:

KNV2004: unable to sync repo Error in the git-sync container: ERROR: can't configure SSH: can't access SSH key: stat /etc/git-secret/ssh: no such file or directory: lstat /repo/root/rev: no such file or directory

这意味着 Git Secret 未成功装载到 git-sync 容器。这可能是由于您的 Git 代码库身份验证类型从 nonegcenodegcpserviceaccount 切换到需要 Secret 的其他类型引起的。如要解决此问题,请运行以下命令来重启 Reconciler Manager 和 Reconciler:

# Stop the reconciler-manager Pod. The reconciler-manager Deployment will spin
# up a new Pod which can pick up the latest `spec.git.auth`.
kubectl delete po -l app=reconciler-manager -n config-management-system

# Delete the reconciler Deployments. The reconciler-manager will recreate the
# reconciler Deployments with correct volume mount.
kubectl delete deployment -l app=reconciler -n config-management-system

reconciler 和/或 git-sync 容器发生 OOMKilled

在 Anthos Config Management 1.8.2 版及更高版本中,使用 kubectl 配置从多个代码库同步时,您可以替换根代码库或命名空间代码库的 CPU 和/或内存限制。如需替换这些值,请使用 RootSync 或 RepoSync 对象的 spec.override.resources 字段

以下示例展示了如何替换 reconciler 容器的 CPU 和内存限制以及根协调器的 git-sync 容器的内存限制。只允许替换 git-syncreconciler 容器。允许部分替换:如果未提供资源限制的替换值,则使用默认资源限制。

apiVersion: configsync.gke.io/v1beta1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-management-system
spec:
  sourceFormat: "unstructured"
  override:
    resources:
    - containerName: "reconciler"
      cpuLimit: "888m"
      memoryLimit: "444Mi"
    - containerName: "git-sync"
      memoryLimit: "333Mi"
  git:
     ...

运行以下命令以验证新资源限制生效:

kubectl get deployment.apps/root-reconciler -n config-management-system -o yaml

您可以通过类似的方法替换命名空间协调器的资源限制。

KNV2004:git-sync 容器中的无法同步代码库错误(git fetch 失败,发生 remote did not send all necessary objects 错误)

Config Sync 会创建 Git 代码库的浅层克隆。在极少数情况下,它可能无法从浅层克隆中找到提交,并且需要增加要提取的 Git 提交的次数。

在 Anthos Config Management 1.8.2 版及更高版本中,您可以通过设置 RootSync 或 RepoSync 对象中的 spec.override.gitSyncDepth 字段来设置要提取的 Git 提交次数:

  • 如果未提供此字段,Config Sync 会自动进行配置。
  • 如果此字段为 0,Config Sync 将执行完整克隆;如果此字段大于 0,将执行浅层克隆。
  • 不允许将此字段设为负值。

以下示例将要提取的 Git 提交数量设置为 88

apiVersion: configsync.gke.io/v1beta1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-management-system
spec:
  override:
    gitSyncDepth: 88
  git:
    ...

运行以下命令以验证更改生效(在 root-reconciler-git-sync ConfigMap 的 data 字段中,GIT_SYNC_DEPTH 应被设置为 88):

kubectl get cm root-reconciler-git-sync -n config-management-system -o yaml

您可以通过类似的方法替换命名空间协调器中要提取的 Git 提交次数。

错误:协调器部署升级失败

将 Config Sync 从 1.6.2 到 1.7.0 之间的版本升级至 1.7.x 到 1.8.x 之间的版本时,协调器 Deployment 的映像版本可能无法更新。这是由于 Deployment 模板的 .spec.selector.labels 字段发生更改导致的。我们在 1.6.2 中新增了一个 matchLabel,但是该标签之后又在 1.7.0 中被移除。标签选择器是不可变的,因此导致协调器管理器无法升级协调器。

您可以通过检查协调器管理器日志来验证该错误:

kubectl logs -n config-management-system deployment/reconciler-manager -c reconciler-manager

以下是日志中该错误的一个示例:

Deployment.apps "root-reconciler" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"reconciler"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable

要解决此问题,请删除当前的协调器:

kubectl delete deployment -n config-management-system -l app=reconciler

错误:命名空间卡在 Terminating 阶段

卡在 Terminating 阶段的命名空间应具有以下条件:

    message: 'Failed to delete all resource types, 1 remaining: admission webhook
      "v1.admission-webhook.configsync.gke.io" denied the request: system:serviceaccount:kube-system:namespace-controller
      is not authorized to delete managed resource "_configmap_bookstore_cm1"'
    reason: ContentDeletionFailed
    status: "True"
    type: NamespaceDeletionContentFailure

如果您尝试从根代码库中删除命名空间,但命名空间下的某些对象仍由命名空间协调器主动管理,就会发生这种情况。删除命名空间时,服务帐号为 system:serviceaccount:kube-system:namespace-controller命名空间控制器将尝试删除该命名空间中的所有对象。但是,Config Sync 准入网络钩子只允许根协调器或命名空间协调器删除这些对象,并拒绝命名空间控制器删除这些对象。

解决方法是删除 Config Sync 准入网络钩子:

kubectl delete deployment.apps/admission-webhook -n config-management-system

Config Management Operator 将重新创建 Config Sync 准入网络钩子。

如果此解决方法不起作用,您可能需要重新安装 Config Sync。

为避免再次遇到此错误,您应先确保已移除命名空间代码库(此处介绍了有关如何移除命名空间代码库),然后再移除命名空间。

错误:在 ValidatingWebhookConfiguration 中找不到 webhooks 字段

如果您在运行 kubectl logs -n config-management-system -l app=admission-webhook 时发现 Config Sync 准入网络钩子日志中存在以下错误:

cert-rotation "msg"="Unable to inject cert to webhook." "error"="`webhooks` field not found in ValidatingWebhookConfiguration" "gvk"={"Group":"admissionregistration.k8s.io","Version":"v1","Kind":"ValidatingWebhookConfiguration"} "name"="admission-webhook.configsync.gke.io"
controller-runtime/manager/controller/cert-rotator "msg"="Reconciler error" "error"="`webhooks` field not found in ValidatingWebhookConfiguration" "name"="admission-webhook-cert" "namespace"="config-management-system"

这意味着 root-reconciler 尚未将任何资源同步到集群。这可能是因为 root-reconciler 尚未就绪,或者没有要从 Git 代码库同步的任何内容(例如,同步目录为空)。如果问题仍然存在,您应检查 root-reconciler 的运行状况:

kubectl get pods -n config-management-system -l configsync.gke.io/reconciler=root-reconciler

如果 root-reconciler 是崩溃循环或 OOMKilled,您应提高其资源限制