排查 Config Connector 问题

本页介绍了可用于排查 Config Connector 的问题排查技巧,以及在使用该产品时可能会遇到的常见问题。

检查 Config Connector 状态和条件

检查 Config Connector 的版本

运行以下命令以获取已安装的 Config Connector 版本,并对照版本说明验证运行的版本是否支持您要使用的功能和资源:

kubectl get ns cnrm-system -o jsonpath='{.metadata.annotations.cnrm\.cloud\.google\.com/version}'

检查资源的状态和事件

通常,您可以通过检查 Kubernetes 中的资源状态来确定 Config Connector 资源的问题。检查资源的状态和事件对于确定 Config Connector 是否未能协调资源以及协调失败的原因尤其有用。

检查 Config Connector 是否正在运行

如需检查 Config Connector 是否正在运行,请验证其所有 Pod 是否均为 READY:

kubectl get pod -n cnrm-system

输出示例:

NAME                                            READY   STATUS    RESTARTS   AGE
cnrm-controller-manager-0                       1/1     Running   0          1h
cnrm-deletiondefender-0                         1/1     Running   0          1h
cnrm-resource-stats-recorder-77dc8cc4b6-mgpgp   1/1     Running   0          1h
cnrm-webhook-manager-58496b66f9-pqwhz           1/1     Running   0          1h
cnrm-webhook-manager-58496b66f9-wdcn4           1/1     Running   0          1h

如果您在命名空间模式下安装了 Config Connector,则每个命名空间都有一个控制器 (cnrm-controller-manager) Pod,负责管理该命名空间中的 Config Connector 资源。

您可以运行以下命令来检查负责特定命名空间的控制器 Pod 的状态:

kubectl get pod -n cnrm-system \
    -l cnrm.cloud.google.com/scoped-namespace=NAMESPACE \
    -l cnrm.cloud.google.com/component=cnrm-controller-manager

将 NAMESPACE 替换为命名空间的名称。

检查控制器日志

控制器 Pod 会记录与 Config Connector 资源协调相关的信息和错误。

您可以通过运行以下命令来查看控制器 Pod 的日志:

kubectl logs -n cnrm-system \
    -l cnrm.cloud.google.com/component=cnrm-controller-manager \
    -c manager

如果您在命名空间模式下安装了 Config Connector,则上述命令会显示所有控制器 Pod 的组合日志。您可以通过运行以下命令检查特定命名空间的控制器 Pod 的日志:

kubectl logs -n cnrm-system \
    -l cnrm.cloud.google.com/scoped-namespace=NAMESPACE \
    -l cnrm.cloud.google.com/component=cnrm-controller-manager \
    -c manager

将 NAMESPACE 替换为命名空间的名称。

详细了解如何检查和查询 Config Connector 的日志。

放弃并获取资源

在某些情况下,您可能需要更新资源中的不可变字段。由于您无法修改不可变字段,因此必须放弃资源,然后重新获取:

  1. 更新 Config Connector 资源的 YAML 配置,并将 cnrm.cloud.google.com/deletion-policy 注解设置为 abandon。
  2. 应用更新后的 YAML 配置,以更新 Config Connector 资源的删除政策。
  3. 放弃 Config Connector 资源。
  4. 更新 YAML 配置中需要更改的不可变字段。
  5. 应用更新后的 YAML 配置以获取废弃的资源。

按问题类型排查问题

请根据症状类型,使用下表排查问题。

问题类型 常见问题
对账
删除
权限
安装和升级
配置

协调

以下部分列出了与 Config Connector 协调资源相关的常见问题。

资源每 5-15 分钟更新一次

症状

您的 Config Connector 资源每 5-10 分钟就会从 UpToDate 状态切换到 Updating 状态。

原因

Config Connector 很可能检测到资源的预期状态与实际状态之间存在意外差异,从而导致 Config Connector 不断更新资源。

解决方法

首先,确认您没有任何外部系统会不断修改 Config Connector 或 Google Cloud 资源(例如 CI/CD 流水线、自定义控制器、Cron 作业等)。

如果该行为不是由外部系统引起的,请查看 Google Cloud 是否更改了 Config Connector 资源中指定的任何值。例如,在某些情况下, Google Cloud 会更改字段值的格式(例如,大写),从而导致资源的目标状态与实际状态之间存在差异。

使用 REST API(例如,对于 ContainerCluster)或 Google Cloud CLI 获取 Google Cloud 资源的状态。然后,将该状态与您的 Config Connector 资源进行比较。查找值不匹配的所有字段,然后更新 Config Connector 资源以使其匹配。尤其要注意 Google Cloud重新设置格式的所有值。例如,请参阅 GitHub 问题 #578 和 #294。

请注意,由于 Config Connector 和Google Cloud 资源模型不同,因此这种方法并不完美,但应该能够让您发现大多数意外差异。

如果您无法解决问题,请参阅其他帮助。

由于字段自动更新,协调失败或循环

当 Google Cloud 自动更新使用 cnrm.cloud.google.com/state-into-spec: merge 注解的资源中的字段时,会出现此问题。

症状

在 Google Cloud 自动更新 YAML 清单中未指定的字段后,Config Connector 资源进入 UpdateFailed 状态或反复 切换到 Updating 状态。

例如,在 Cloud SQL 对 SQLInstance 资源执行自动维护更新后,协调可能会失败,并显示类似于以下内容的错误:

Update call failed: error updating: patching SQLInstance ... maintenanceVersion failed: googleapi: Error 400: Invalid request: The requested maintenance version is not an available maintenance version to upgrade. Please refer to the availableMaintenanceVersions on the instance resource to see the available maintenance versions.., invalid

原因

该资源具有 cnrm.cloud.google.com/state-into-spec: merge 注解。 对于在 1.113.0 及更早版本中添加的 CustomResourceDefinitions (CRD),此注解是 Config Connector 1.123.1 版之前创建的资源的默认注解。如果您的 ConfigConnector 或 ConfigConnectorContext 自定义资源 (CR) 中的 spec.stateIntoSpec 字段设置为 Merge,则您的资源也可能具有此注解。

当 cnrm.cloud.google.com/state-into-spec 注解设置为 merge 时,Config Connector 会在初始协调期间将未指定的字段(例如 spec.maintenanceVersion 字段)填充到 Kubernetes 资源 spec 字段中。当 Google Cloud 稍后自动更新底层资源上的该字段时,Config Connector 会将存储在 spec 字段中的旧值视为目标状态,并尝试还原更改。如果 Google Cloud API 拒绝降级(如 Cloud SQL 对 spec.maintenanceVersion 字段所做的那样),则调解会失败。

解决方法

如需解决此问题,请将资源从 Merge 行为迁移到 Absent 行为,以便 Config Connector 停止将未指定的字段填充到 spec 字段中:

  1. 在资源 YAML 清单中,省略自动更新的字段(例如 spec.maintenanceVersion 字段),并将 cnrm.cloud.google.com/state-into-spec 注解设置为 absent。
  2. 按照将资源从 Merge 迁移到 Absent 中的步骤放弃 Kubernetes 资源,然后使用更新后的 YAML 清单重新获取该资源。

资源没有状态

症状

您的资源没有 status 字段。

原因

Config Connector 可能未正常运行。

解决方法

检查 Config Connector 是否正在运行。

KNV2005:同步器过度更新资源

症状

您正在使用 Config Sync,并且看到 Config Connector 资源出现 KNV2005 错误,类似于以下内容:

KNV2005: detected excessive object updates, approximately 6 times per
minute. This may indicate Config Sync is fighting with another controller over
the object.

原因

很可能是 Config Sync 和 Config Connector 正在争夺资源。

如果 Config Sync 和 Config Connector 不断将同一字段更新为不同的值,则称它们在“争夺”资源。一个的更新会触发另一个采取行动并更新资源,这会导致另一个采取行动并更新资源,然后不断重复。

在大多数领域,打斗都不是问题。Config Connector 不会更改 Config Sync 中指定的字段。同样,Config Sync 会忽略未在 Config Sync 中指定且由 Config Connector 默认设置的字段。因此,对于大多数字段,Config Sync 和 Config Connector 不需要更新同一字段。

列表字段是一个例外。与 Config Connector 可能会默认对象字段中的子字段类似,Config Connector 也可能会默认列表内对象中的子字段。但是,由于 Config Connector 资源中的列表字段是原子字段,因此子字段的默认设置会被视为完全更改列表的值。

因此,如果 Config Sync 设置了列表字段,而 Config Connector 默认设置了该列表中的任何子字段,则 Config Sync 和 Config Connector 将“争夺”资源。

解决方法

如需解决此问题,您可以选择以下任一方案:

  1. 更新 Config Sync 代码库中的资源清单,以匹配 Config Connector 尝试将资源设置的值。

    一种方法是暂时停止同步配置,等待 Config Connector 完成资源协调,然后更新资源清单以匹配 Kubernetes API 服务器上的资源。

  2. 通过将注解 client.lifecycle.config.k8s.io/mutation 设置为 ignore,阻止 Config Sync 响应 Kubernetes API 服务器上的资源更新。详细了解如何让 Config Sync 忽略对象突变。

  3. 通过将资源上的注解 cnrm.cloud.google.com/state-into-spec 设置为 absent,阻止 Config Connector 完全更新资源的规范。并非所有资源都支持此注解。如需查看您的资源是否支持该注解,请参阅相应的资源参考页面。详细了解注解。

由 Config Connector 删除的资源

症状

您的集群中删除了某个资源,并且您怀疑是 Config Connector 删除了该资源。

原因

Config Connector 绝不会在没有外部原因的情况下删除您的资源。例如,运行 kubectl delete、使用 Argo CD 等配置管理工具或使用自定义 API 客户端都可能会导致资源删除。

一个常见的误解是,Config Connector 已启动并删除了集群中的某些资源。例如,如果您使用的是 Config Connector,则可能会从容器日志消息或 Kubernetes 集群审核日志中注意到 Config Connector 控制器管理器针对某些资源的删除请求。这些删除请求是由外部触发器引起的,Config Connector 正在尝试协调这些删除请求。

解决方法

如需确定资源被删除的原因,您需要查看发送到相应资源的第一个删除请求。调查此问题的最佳方法是检查 Kubernetes 集群审核日志。

例如,如果您使用的是 GKE,则可以使用 Cloud Logging 查询 GKE 集群审核日志。例如,如果您想在 my-namespace 命名空间中查找名为 my-dataset 的 BigQueryDataset 资源的初始删除请求,请运行如下查询:

resource.type="k8s_cluster"
resource.labels.project_id="my-project-id"
resource.labels.cluster_name="my-cluster-name"
protoPayload.methodName="com.google.cloud.cnrm.bigquery.v1beta1.bigquerydatasets.delete"
protoPayload.resourceName="bigquery.cnrm.cloud.google.com/v1beta1/namespaces/my-namespace/bigquerydatasets/my-dataset"

使用此查询,您可以查找第一个删除请求,然后检查相应删除日志消息的 authenticationInfo.principalEmail,以确定删除原因。

控制器 Pod 因内存不足而终止

症状

您在 Config Connector 控制器 Pod 上看到 OOMKilled 错误。Pod 的状态可能会显示为 OOMKilled 或 Terminating。

原因

容器或整个 Pod 已终止,因为它们使用的内存超出了允许的范围。 您可以通过运行 kubectl describe 命令来验证这一点:

kubectl describe pod POD_NAME -n cnrm-system

将 POD_NAME 替换为您要排查问题的 Pod。

此外,仔细检查 Pod 的事件日志可以发现任何与 OOM 相关的事件。

解决方法

如需解决此问题,您可以使用 ControllerResource 自定义资源来增加 Pod 的内存请求和内存限制。

删除

以下部分列出了与用户发起的删除操作相关的常见问题,这些问题可能会导致与 Config Connector 发生冲突。

命名空间删除操作卡在“正在终止”状态

症状

删除命名空间的操作卡在 Terminating 阶段。

原因

如果您在命名空间模式下安装了 Config Connector,并且在删除该命名空间中的所有 Config Connector 资源之前删除了该命名空间的 ConfigConnectorContext,则可能会发生此问题。删除命名空间的 ConfigConnectorContext 后,系统会为该命名空间停用 Config Connector,从而防止删除该命名空间中任何剩余的 Config Connector 资源。

解决方法

如需解决此问题,您必须执行强制清理,然后手动删除底层 Google Cloud 资源。

为了防止日后出现此问题,请仅在从 Kubernetes 中删除其命名空间中的所有 Config Connector 资源后再删除 ConfigConnectorContext。请不要在删除命名空间中的所有 Config Connector 资源之前就删除整个命名空间,因为系统可能会先删除 ConfigConnectorContext。

项目删除后,资源删除操作卡在“DeleteFailed”状态

症状

删除 Config Connector 资源失败,状态为 DeleteFailed。

原因

如果 Google Cloud 项目在资源之前被删除,则可能会出现此问题。

解决方法

如需解决此问题,请在Google Cloud上恢复项目,以允许 Config Connector 从 Kubernetes 中删除剩余的子资源。或者,您也可以执行强制清理。

为防止将来出现此问题,请仅在从 Kubernetes 中删除 Google Cloud 项目的所有子 Config Connector 资源后,再删除该项目。避免删除可能同时包含 Project 资源及其子 Config Connector 资源的整个命名空间,因为 Project 资源可能会先被删除。

权限和身份验证

以下部分列出了与权限和身份验证相关的常见问题。

未定义 Compute Engine 元数据

症状

您的 Config Connector 资源具有 UpdateFailed 状态,并显示一条消息,指出未定义 Compute Engine 元数据,类似于以下错误:

Update call failed: error fetching live state: error reading underlying
resource: summary: Error when reading or editing SpannerInstance
"my-project/my-spanner- instance": Get
"https://spanner.googleapis.com/v1/projects/my-project/instances/my-spanner-instance?alt=json":
metadata: Compute Engine metadata "instance/service-accounts/default/token?
scopes=https%!A(MISSING)%!F(MISSING)%!F(MISSING)www.googleapis.com%!F(MISSING)auth%!F(MISSING)compute%!C(MISSING)https%!A(MISSING)%!F(MISSING)%!F(MISSING)www.googleapis.com%!F(MISSIN
G)auth%!F(MISSING)cloud-platform%!C(MISSING)https%!A(MISSING)%!F(MISSING)%!F(MISSING)www.googleapis.com%!F(MISSING)auth%!F(MISSING)cloud-identity%!C(MISSING)https%!A(MISSING)%!F(MISS
ING)%!F(MISSING)www.googleapis.com%!F(MISSING)auth%!F(MISSING)ndev.clouddns.readwrite%!C(MISSING)https%!A(MISSING)%!F(MISSING)%!F(MISSING)www.googleapis.com%!F(MISSING)auth%!F(MISSIN
G)devstorage.full_control%!C(MISSING)https%!A(MISSING)%!F(MISSING)%!F(MISSING)www.googleapis.com%!F(MISSING)auth%!F(MISSING)userinfo.email%!C(MISSING)https%!A(MISSING)%!F(MISSING)%!F
(MISSING)www.googleapis.com%!F(MISSING)auth%!F(MISSING)drive.readonly" not
defined, detail:

原因

Config Connector 使用的 IAM 服务账号可能不存在。

解决方法

要解决此问题,请确保 Config Connector 使用的 IAM 服务账号已存在。

为了防止日后出现此问题,请务必遵循 Config Connector 安装说明操作。

错误 403:请求的身份验证范围不足

症状

您的 Config Connector 资源具有 UpdateFailed 状态,并显示一条消息,指示由于身份验证范围不足而导致 403 错误,类似于以下错误:

Update call failed: error fetching live state: error reading underlying
resource: summary: Error when reading or editing SpannerInstance
"my-project/my-spanner-instance": googleapi: Error 403: Request had
insufficient authentication scopes.

原因

您的 GKE 集群可能未启用 Workload Identity Federation for GKE。

如需确认 Workload Identity Federation for GKE 未启用,请完成以下步骤:

  1. 将以下 Pod 配置保存为 wi-test.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: workload-identity-test
      namespace: cnrm-system
    spec:
      containers:
      - image: google/cloud-sdk:slim
        name: workload-identity-test
        command: ["sleep","infinity"]
      serviceAccountName: cnrm-controller-manager
    

    如果您使用命名空间模式安装了 Config Connector,则 serviceAccountName 应为 cnrm-controller-manager-NAMESPACE。将 NAMESPACE 替换为您在安装期间使用的命名空间。

  2. 在 GKE 集群中创建 Pod:

    kubectl apply -f wi-test.yaml
    
  3. 在 Pod 中打开交互式会话:

    kubectl exec -it workload-identity-test \
        --namespace cnrm-system \
        -- /bin/bash
    
  4. 列出您的身份:

    gcloud auth list
    
  5. 验证所列身份是否与绑定到您资源的 Google 服务账号一致。

    如果您看到的是 Compute Engine 默认服务账号,则表示您的 GKE 集群和/或节点池未启用 Workload Identity Federation for GKE。

  6. 退出交互式会话,然后从 GKE 集群中删除 Pod:

    kubectl delete pod workload-identity-test \
        --namespace cnrm-system
    

解决方法

如需解决此问题,请确保在集群上启用 Workload Identity Federation for GKE。

如果您仍然看到相同的错误,请确保您还在集群的节点池上启用了 Workload Identity Federation for GKE。

403 禁止访问:调用方无权限

症状

您的 Config Connector 资源具有 UpdateFailed 状态,并显示一条消息,指示由于 Workload Identity Federation for GKE 而出现 403 错误,类似于以下错误:

Update call failed: error fetching live state: error reading underlying
resource: summary: Error when reading or editing SpannerInstance
"my-project/my-spanner- instance": Get
"https://spanner.googleapis.com/v1/projects/my-project/instances/my-spanner-instance?alt=json":
compute: Received 403 `Unable to generate access token; IAM returned 403
Forbidden: The caller does not have permission
This error could be caused by a missing IAM policy binding on the target IAM
service account.
For more information, refer to the Workload Identity documentation:
  https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity#creating_a_relationship_between_ksas_and_gsas

原因

Config Connector 的 Kubernetes 服务账号缺少适当的 IAM 权限,无法以 Workload Identity Federation for GKE 用户的身份模拟您的 IAM 服务账号。

解决方法

要解决此问题并防止日后出现此问题,请参阅 Config Connector 安装说明。

错误 403:调用方缺少 IAM 权限

症状

您的 Config Connector 资源具有 UpdateFailed 状态,并显示一条消息,指出调用者缺少 IAM 权限,类似于以下错误:

Update call failed: error fetching live state: error reading underlying
resource: summary: Error when reading or editing SpannerInstance
"my-project/my-spanner- instance": googleapi: Error 403: Caller is missing IAM
permission spanner.instances.get on resource
projects/my-project/instances/my-spanner-instance., detail:

原因

Config Connector 使用的 IAM 服务账号缺少管理 Google Cloud 资源所需的消息中所述的 IAM 权限。

解决方法

如果您在为 IAM 服务账号授予适当的 IAM 权限后仍然看到相同的错误,请检查该资源是否已在正确的项目中创建。检查 Config Connector 资源的 spec.projectRef 字段(如果资源不支持 spec.projectRef 字段,则检查其 cnrm.cloud.google.com/project-id 注释),并验证资源是否引用了正确的项目。请注意,如果资源和命名空间都未指定目标项目,则 Config Connector 会将命名空间名称用作项目 ID。详细了解如何为项目范围内的资源配置目标项目。

如果您仍然看到相同的错误,请检查 Workload Identity Federation for GKE 是否已在您的 GKE 集群上启用。

为了防止日后出现此问题,请务必遵循 Config Connector 安装说明操作。

IAMPolicy、IAMPartialPolicy 和 IAMPolicyMember 的更新错误

症状

您会看到 UpdateFailed 状态,其中包含一条出错提示,指出由于服务账号不存在而出现 400 错误:

Update call failed: error setting policy member: error applying changes: summary: Request `Create IAM Members roles/[MYROLE] serviceAccount:[NAME]@[PROJECT_ID]. for project \"projects/[PROJECT_ID]\"` returned error: Error applying IAM policy for project \"projects/[PROJECT_ID]\": Error setting IAM policy for project \"projects/[PROJECT_ID]\": googleapi: Error 400: Service account [NAME]@[PROJECT_ID]. does not exist., badRequest

原因

如果您在清理依赖于服务账号的 IAMPolicy、IAMPartialPolicy 和 IAMPolicyMember 资源之前删除 IAMServiceAccount Config Connector 资源,则 Config Connector 在协调期间无法找到这些 IAM 资源中引用的服务账号。

解决方法

如需解决此问题,请检查您的服务账号,看看这些 IAM 资源所需的服务账号是否已被删除。如果服务账号被删除,请一并清理相关的 IAM Config Connector 资源。对于 IAMPolicyMember,请删除整个资源。对于 IAMPolicy 和 IAMParitialPolicy,仅移除涉及已删除服务账号的绑定。但是,此类清理不会立即移除Google Cloud 角色绑定。由于已删除的服务账号具有保留期,因此 Google Cloud 角色绑定会保留 60 天。如需了解详情,请参阅有关删除服务账号的 Google CloudIAM 文档。

为避免此问题,您应始终在删除引用的 IAMServiceAccount 之前清理 IAMPolicy、IAMPartialPolicy、IAMPolicyMember Config Connector 资源。

ServiceIdentity 资源失败并显示 Invalid service producer

症状

您的 ServiceIdentity 资源的状态为 UpdateFailed,并显示类似于以下内容的出错提示:

Update call failed: error applying desired state: summary: Error creating Service Identity: Invalid service producer: ...

原因

此错误表示指定资源不支持按需创建服务身份。

解决方法

ServiceIdentity 资源只能为受支持的服务生成服务身份。如需验证服务是否支持按需创建服务身份,请在应用配置之前运行以下命令:

gcloud beta services identity create --service SERVICE_NAME.googleapis.com

将 SERVICE_NAME 替换为服务的名称,例如 spanner。

如果该命令成功执行,Config Connector 就可以为该服务创建身份。如果该命令失败,则表示 Config Connector 无法为该服务创建身份。

安装和升级

以下部分列出了与安装或升级 Config Connector 版本相关的常见问题。

Config Connector 插件安装不支持该版本

症状

如果您无法成功启用 Config Connector 插件,系统会显示以下出错提示:Node version 1.15.x-gke.x s unsupported。

如果停用了 Workload Identity Federation for GKE 或 GKE 监控,也会显示此出错提示。

原因

GKE 集群的版本不符合要求,或所需功能已停用。

解决方法

如需解决此错误,请验证 GKE 集群的版本是否符合版本和功能要求。确保已启用 Workload Identity Federation for GKE 和 GKE Monitoring。

如需获取集群的所有有效版本,请运行以下命令:

gcloud container get-server-config --format "yaml(validMasterVersions)" \
    --zone ZONE

将 ZONE 替换为 Compute Engine 区域。

从列表中选择符合要求的版本。

failed calling webhook

症状

您无法卸载 Config Connector,并收到类似于以下内容的错误:

error during reconciliation: error building deployment objects: error finalizing the deletion of Config Connector system components deployed by ConfigConnector controller: error waiting for CRDs to be deleted: error deleting CRD accesscontextmanageraccesslevels.accesscontextmanager.cnrm.cloud.google.com: Internal error occurred: failed calling webhook "abandon-on-uninstall.cnrm.cloud.google.com": failed to call webhook: Post "https://abandon-on-uninstall.cnrm-system.svc:443/abandon-on-uninstall?timeout=3s": service "abandon-on-uninstall" not found

原因

如果使用 Config Connector 插件,并且在移除 Config Connector CRD 之前停用 Config Connector,则可能会出现此问题。

解决方法

如需解决此错误,您必须先手动删除 webhook:

kubectl delete validatingwebhookconfiguration abandon-on-uninstall.cnrm.cloud.google.com --ignore-not-found --wait=true
kubectl delete validatingwebhookconfiguration validating-webhook.cnrm.cloud.google.com --ignore-not-found --wait=true
kubectl delete mutatingwebhookconfiguration mutating-webhook.cnrm.cloud.google.com --ignore-not-found --wait=true

然后,您可以继续卸载 Config Connector。

PodSecurityPolicy 阻止升级

症状

在从 Config Connector 插件切换到手动安装并将 Config Connector 升级到新版本后,cnrm Pod 无法更新。

原因

使用 PodSecurityPolicy 可能会阻止 cnrm Pod 更新。

如需确认 PodSecurityPolicy 是否阻止了升级,请检查 config-connector-operator 的事件,并查找类似于以下内容的错误:

create Pod configconnector-operator-0 in StatefulSet configconnector-operator failed error: pods "configconnector-operator-0" is forbidden: PodSecurityPolicy: unable to admit pod: [pod.metadata.annotations[seccomp.security.alpha.kubernetes.io/pod]: Forbidden: seccomp may not be set pod.metadata.annotations[container.seccomp.security.alpha.kubernetes.io/manager]: Forbidden: seccomp may not be set]

解决方法

如需解决此问题,您必须在 PodSecurityPolicy 上指定与错误中提及的注解相对应的注解。在前面的示例中,注解为 seccomp.security.alpha.kubernetes.io。

配置

以下部分列出了与配置资源相关的常见问题。

无法更改不可变字段

Config Connector 会在准入时拒绝不可变字段的更新。

例如,使用 kubectl apply 更新不可变字段会导致命令立即失败。

这意味着如果持续重新应用资源的工具(例如 GitOps)不处理准入错误的话,则在更新资源时这些工具可能会遇到问题。

由于 Config Connector 不允许更新不可变字段,因此执行此类更新的唯一方法是删除并重新创建资源。

在没有更新时更新不可变字段时出错

在使用 Config Connector 创建或获取 Google Cloud 资源后不久,您可能会在 Config Connector 资源的状态中看到以下错误:

  • Update call failed: error applying desired state: infeasible update: ({true \<nil\>}) would require recreation (示例)

  • Update call failed: cannot make changes to immutable field(s) (示例)

这可能并不意味着您实际更新了资源,但原因可能是 Google Cloud API 更改了您在 Config Connector 资源中管理的不可变字段。这导致不可变字段的所需状态与实际状态不匹配。

您可以通过更新 Config Connector 资源中这些不可变字段的值来匹配实时状态,从而解决此问题。为此,您应完成以下步骤:

  1. 更新 Config Connector 资源的 YAML 配置,并将 cnrm.cloud.google.com/deletion-policy 注解设置为 abandon。
  2. 应用更新后的 YAML 配置,以更新 Config Connector 资源的删除政策。
  3. 放弃 Config Connector 资源。
  4. 使用 gcloud CLI 打印相应 Google Cloud 资源的实时状态。
  5. 找出 gcloud CLI 输出与 Config Connector 资源的 YAML 配置之间的不匹配之处,并在 YAML 配置中更新这些字段。
  6. 应用更新后的 YAML 配置,以获取废弃的资源。

没有与类型“RESOURCE_KIND”相符的结果

症状

您会看到错误 No matches for kind "RESOURCE_KIND"。

原因

您的 Kubernetes 集群未安装 RESOURCE_KIND 资源种类的 CRD。

解决方法

验证该种类是否为 Config Connector 支持的资源种类。

如果该种类受支持,则意味着您的 Config Connector 安装已过时或无效。

如果您使用 GKE 插件安装了 Config Connector,则安装应自动升级。如果您手动安装了 Config Connector,则必须执行手动升级。

检查 GitHub 代码库,以确定哪些 Config Connector 版本支持哪些资源种类(例如,这里列出 Config Connector v1.44.0 支持的种类)。

标签不会传播到 Google Cloud 资源

症状

YAML 中的标签未显示在 Google Cloud 资源上。

原因

并非所有 Google Cloud 资源都支持标签。

解决方法

Config Connector 会将 metadata.labels 中的标签传播到基础Google Cloud 资源。查看资源的 REST API 文档(例如,PubSubTopic 的 API 文档),了解它们是否支持标签。

资源名称中包含特殊字符导致出错

症状

您会看到与 metadata.name 中的无效字符相关的错误:

a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')

原因

特殊字符在 Kubernetes metadata.name 字段中无效。

解决方法

如果您想为资源指定一个不是有效 Kubernetes 名称但属于有效 Google Cloud 资源名称的名称,则可以使用 resourceID 字段,如以下示例所示:

apiVersion: sql.cnrm.cloud.google.com/v1beta1
kind: SQLUser
metadata:
  name: 'test'
spec:
  instanceRef:
    name: sqlinstance-sample-postgresql
  host: "%"
  type: CLOUD_IAM_USER
  resourceID: test.example@example-project.iam

此配置会导致 Config Connector 使用 resourceID 而不是 metadata.name 作为资源的名称。

无法从资源规范中移除字段

症状

从 Config Connector 资源的规范中移除某个字段并不会将其从资源中移除。

原因

从由 Config Connector 管理的资源的规范中移除某个字段不会使该字段变为空或恢复为默认值。而是会导致该字段由外部管理。

解决方法

如果您想将底层Google Cloud 资源中某个字段的值更改为空或默认值,则必须在 Config Connector 资源规范中将该字段清零:

  • 对于列表类型字段,请使用 [] 将该字段设置为空列表。

    以下示例显示了我们要移除的 targetServiceAccounts 字段:

    spec:
      targetServiceAccounts:
        - external: "example-sa-1@example-project."
        - external: "example-sa-2@example-project."
    

    如需移除此字段,请将值设置为空:

    spec:
      targetServiceAccounts: []
    
  • 对于基本类型字段,请使用以下方法之一将该字段设置为空:

    类型 空值
    字符串 ""
    布尔值 "false"
    整数 0

    以下示例显示了我们要移除的 identityNamespace 字段:

    spec:
      workloadIdentityConfig:
        identityNamespace: "example-project."
    

    如需移除此字段,请将值设置为空:

    spec:
      workloadIdentityConfig:
        identityNamespace: ""
    
  • 对于对象类型字段,您可以尝试按照上一部分中的指导将对象类型的子字段设置为空或默认值,并验证其是否有效。不过,这不一定有效。

state-into-spec 注解的值“merge”无效

当资源使用 cnrm.cloud.google.com/state-into-spec: merge 注解,但资源种类或 Config Connector 版本拒绝 merge 值时,就会出现此问题。

症状

您的 Config Connector 资源无法协调,并显示类似于以下内容的出错提示:

Update call failed: error applying desired state: invalid value "merge" for "cnrm.cloud.google.com/state-into-spec" annotation

原因

发生此错误是由以下某种原因造成的:

  • 资源种类不支持 Merge 行为,但资源具有 cnrm.cloud.google.com/state-into-spec: merge 注解。此注解可以直接在资源上设置,也可以从 ConfigConnector 或 ConfigConnectorContext CR 中的 spec.stateIntoSpec: Merge 设置继承。Config Connector 1.114.0 版及更高版本中添加的 CRD 仅支持 Absent 行为。
  • 您已升级到 Config Connector 1.134.0 或 1.134.1 版,并且有一个现有 SQLInstance 资源,该资源默认具有早期版本的 cnrm.cloud.google.com/state-into-spec: merge 注解。1.134.0 和 1.134.1 版本存在一个已知问题,即拒绝 SQLInstance 资源上的 merge 值。

解决方法

如需解决此问题,请完成适用于您的情况的步骤:

  • 您的资源种类不支持 Merge 行为:在资源 YAML 清单中设置 cnrm.cloud.google.com/state-into-spec: absent 注解,并在 ConfigConnector 或 ConfigConnectorContext CR 中将 spec.stateIntoSpec 字段设置为 Absent。如需验证您的资源种类是否支持 Merge 行为,请参阅支持 Merge 的种类。如果集群中的现有资源上已存在该注解,请按照将资源从 Merge 迁移到 Absent 中的步骤操作。
  • 您在 Config Connector 版本 1.134.0 或 1.134.1 中使用现有的 SQLInstance 资源:将 Config Connector 升级到版本 1.134.2 或更高版本。或者,按照将资源从 Merge 迁移到 Absent 中的步骤,将 SQLInstance 资源迁移到 cnrm.cloud.google.com/state-into-spec: absent 注解。

Config Connector 无法在基于 Arm 的节点上启动

如果您的集群包含使用 Arm 架构(例如 C4A、N4A 或 Tau T2A 机器系列)的节点池,则 Config Connector 组件可能无法运行。这是一个已知限制,因为 Config Connector 不支持基于 Arm 的系统。

表现

如果您的 Config Connector 实例受到此问题的影响,您可能会遇到以下症状:

  • cnrm-system 命名空间中的 Pod 仍处于 Pending 状态。
  • Pod 可能会显示 CrashLoopBackOff,并在日志中显示类似于以下内容的出错提示:exec user process caused "exec format error"。
  • 描述 Pod 可揭示调度失败或架构不匹配问题。

解决方法

如需解决此问题,请确保在具有 x86 架构的节点上调度 Config Connector 组件:

  • 添加 x86 节点池:如果您的集群仅包含 Arm 节点,请添加至少一个使用 x86 机器类型(例如 e2-standard-2)的节点池,以托管 Config Connector 控制器 Pod。
  • 验证节点污点:GKE Arm 节点通常带有 kubernetes.io/arch=arm64:NoSchedule 污点,以防止仅支持 x86 的工作负载调度到这些节点上。确保您未向 Config Connector 部署添加容忍度,以便它们在这些节点上运行。

强制清理

如果您的 Config Connector 资源卡在删除阶段,并且您只想将其从 Kubernetes 集群中移除,则可以通过删除其终结器来强制删除这些资源。

您可以通过以下方式删除资源的终结器:使用 kubectl edit 修改资源,删除 metadata.finalizers 字段,然后保存文件以将更改保留到 Kubernetes API 服务器。

由于删除资源的终结器会使资源立即从 Kubernetes 集群中删除,因此 Config Connector 可能(但不一定)没有机会完成底层Google Cloud 资源的删除。这意味着,您可能需要在之后手动删除 Google Cloud 资源。

监控

监控 Config Connector 并探索其日志有助于您确定问题的来源,并更好地了解意外行为。

指标

您可以使用 Prometheus 从 Config Connector 中收集和显示指标。

日志记录

所有 Config Connector Pod 都会输出 JSON 格式的结构化日志。

控制器 Pod 的日志对调试资源协调问题特别有用。

您可以通过过滤日志消息中的以下字段来查询日志中的特定资源:

  • logger:包含资源的种类(以小写形式)。例如,PubSubTopic 资源的 logger 为 pubsubtopic-controller。
  • resource.namespace:包含资源的命名空间。
  • resource.name:包含资源的名称。

使用 Logging 进行高级日志查询

如果您使用的是 GKE,则可以通过以下查询使用 Cloud Logging 查询日志中的特定资源:

# Filter to include only logs coming from the controller Pods
resource.type="k8s_container"
resource.labels.container_name="manager"
resource.labels.namespace_name="cnrm-system"
labels.k8s-pod/cnrm_cloud_google_com/component="cnrm-controller-manager"

# Filter to include only logs coming from a particular GKE cluster
resource.labels.cluster_name="GKE_CLUSTER_NAME"
resource.labels.location="GKE_CLUSTER_LOCATION"

# Filter to include only logs for a particular Config Connector resource
jsonPayload.logger="RESOURCE_KIND-controller"
jsonPayload.resource.namespace="RESOURCE_NAMESPACE"
jsonPayload.resource.name="RESOURCE_NAME"

请替换以下内容:

  • 将 GKE_CLUSTER_NAME 替换为运行 Config Connector 的 GKE 集群的名称
  • 将 GKE_CLUSTER_LOCATION 替换为运行 Config Connector 的 GKE 集群的位置。例如 us-central1。
  • 将 RESOURCE_KIND 替换为小写的资源种类。例如 pubsubtopic。
  • 将 RESOURCE_NAMESPACE 替换为资源的命名空间。
  • 将 RESOURCE_NAME 替换为资源的名称。

更多帮助

如需更多帮助,您可以在 GitHub 上提交问题或与 Google Cloud 支持团队联系。