2. 控制平面启动故障:KubeFed Controller Manager 启动失败常见原因及排查步骤

KubeFed Controller Manager (KubeFed-CM) 是 Federation 控制平面的核心组件,负责监听联邦资源变化、协调成员集群状态。启动失败将直接导致联邦控制平面不可用。本章聚焦于三类最常见的原因:RBAC 缺失、CRD 未安装、证书过期,并提供系统化的排查步骤。

2.1 启动失败原因概览

故障类别 典型错误日志关键词 影响范围 修复优先级
RBAC 缺失 Forbidden、unauthorized、cannot list resource KubeFed-CM 无法访问 API Server 高
CRD 未安装 no matches for kind "FederatedDeployment"、unable to retrieve the complete list of server APIs 联邦资源类型无法注册 高
证书过期 certificate has expired、x509: certificate is valid for ... not ... TLS 握手失败,控制面通信中断 紧急

2.2 故障排查流程图

以下 SVG 展示了从发现 KubeFed-CM Pod 异常到定位根因的完整排查路径,涵盖三个主要分支。

KubeFed Controller Manager 启动故障排查流程图 KubeFed-CM 启动故障排查流程 KubeFed-CM Pod CrashLoopBackOff kubectl logs -n kube-federation-system 日志内容分析 RBAC: Forbidden / unauthorized 检查 ClusterRole / RoleBinding 确认 kube-federation-controller-manager SA CRD: no matches for kind kubectl get crd | grep kubefed 重新安装 helm chart 或 kubefedctl init 证书: certificate has expired 检查 secret 中 tls.crt 有效期 重新签发证书并更新 secret 修复后重启 Pod 验证 Pod Running & Ready

2.3 详细排查步骤

2.3.1 RBAC 缺失

KubeFed-CM 使用 ServiceAccount kube-federation-controller-manager 与宿主集群 API Server 通信。如果缺少必要的 ClusterRole 或 RoleBinding,API Server 会返回 403 Forbidden。

典型错误日志:
E0205 10:23:45.123456       1 controller.go:120] 
  Failed to list *v1.Namespace: namespaces is forbidden: 
  User "system:serviceaccount:kube-federation-system:kube-federation-controller-manager" 
  cannot list resource "namespaces" in API group "" at the cluster scope

排查步骤:

  1. 确认 ServiceAccount 存在:
    kubectl get sa -n kube-federation-system kube-federation-controller-manager
  2. 检查 ClusterRole 绑定:
    kubectl describe clusterrolebinding kube-federation-controller-manager:clusterrole

    确认 Subject 指向正确的 ServiceAccount 和命名空间。

  3. 验证权限是否覆盖:
    kubectl auth can-i --list --as=system:serviceaccount:kube-federation-system:kube-federation-controller-manager

    检查是否包含 list、watch、get、update 等核心资源权限。

  4. 修复方法: 重新应用 RBAC 清单或使用 Helm 升级:
    helm upgrade --install kubefed kubefed/kubefed --namespace kube-federation-system --create-namespace
避坑提示: 如果使用自定义命名空间部署 KubeFed,必须手动修改 ClusterRoleBinding 中的 namespace 字段,否则 RBAC 绑定会失效。

2.3.2 CRD 未安装

KubeFed 依赖一组自定义资源定义(CRD)来管理联邦资源类型。如果 CRD 未安装或安装不完整,KubeFed-CM 启动时会因无法找到资源类型而崩溃。

典型错误日志:
E0205 10:25:12.654321       1 fedresourcemanager.go:85] 
  unable to retrieve the complete list of server APIs: 
  the server could not find the requested resource (get federateddeployments.types.kubefed.io)

排查步骤:

  1. 列出已安装的 CRD:
    kubectl get crd | grep kubefed

    预期输出应包含 federateddeployments.types.kubefed.io、federatednamespaces.types.kubefed.io、clusterpropagatedversions.types.kubefed.io 等核心 CRD。

  2. 检查 CRD 状态:
    kubectl get crd federateddeployments.types.kubefed.io -o yaml | grep -A5 "conditions:"

    确认 Established 条件为 True,NamesAccepted 条件为 True。

  3. 重新安装 CRD:
    kubefedctl init --host-cluster-context=your-context --kubefed-namespace=kube-federation-system

    或使用 Helm 重新安装:

    helm upgrade --install kubefed kubefed/kubefed --namespace kube-federation-system --set crd.install=true
经验法则: 在升级 KubeFed 版本时,务必先检查 CRD 的 API 版本兼容性。v1 CRD 与 v1beta1 CRD 不兼容,会导致启动失败。

2.3.3 证书过期

KubeFed-CM 与成员集群通信时使用 TLS 证书。如果证书过期或 SAN(Subject Alternative Name)不匹配,TLS 握手会失败,导致控制平面无法启动。

典型错误日志:
E0205 10:26:34.987654       1 transport.go:45] 
  Failed to dial: remote error tls: bad certificate
  x509: certificate has expired or is not yet valid

排查步骤:

  1. 定位证书 Secret:
    kubectl get secret -n kube-federation-system | grep tls

    通常名为 kubefed-serving-cert 或 kubefed-client-cert。

  2. 解码并检查证书有效期:
    kubectl get secret kubefed-serving-cert -n kube-federation-system -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates

    输出示例:

    notBefore=Feb  1 00:00:00 2024 GMT
    notAfter=Feb  1 00:00:00 2025 GMT

    如果 notAfter 已过期,则需要重新签发。

  3. 检查 SAN 是否匹配:
    kubectl get secret kubefed-serving-cert -n kube-federation-system -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -text | grep -A1 "Subject Alternative Name"

    确保 SAN 包含 KubeFed-CM 的 Service DNS 名称(如 kube-federation-controller-manager.kube-federation-system.svc)。

  4. 修复方法: 删除旧 Secret 并触发证书重新签发:
    kubectl delete secret kubefed-serving-cert -n kube-federation-system
    kubectl delete pod -n kube-federation-system -l app=kube-federation-controller-manager

    如果使用 cert-manager,检查 Certificate 资源状态并手动续期:

    kubectl certificate renew kubefed-serving-cert -n kube-federation-system

2.4 综合排查清单

步骤 命令/操作 预期结果
1. 检查 Pod 状态 kubectl get pods -n kube-federation-system Pod 状态为 Running,READY 为 1/1
2. 查看日志 kubectl logs -n kube-federation-system deployment/kube-federation-controller-manager 无 ERROR 或 FATAL 级别日志
3. 验证 RBAC kubectl auth can-i --list ... 返回权限列表,无 Forbidden
4. 验证 CRD kubectl get crd | grep kubefed 至少 5 个核心 CRD 状态为 Established
5. 验证证书 openssl x509 -noout -dates notAfter 在当前时间之后
6. 重启 Pod kubectl rollout restart deployment -n kube-federation-system kube-federation-controller-manager 新 Pod 启动成功,无 CrashLoopBackOff

2.5 故障案例:证书 SAN 不匹配

真实案例: 某团队在将 KubeFed 从 v0.8 升级到 v0.10 后,KubeFed-CM 持续 CrashLoopBackOff。日志显示 x509: certificate is valid for kubefed-controller-manager, not kube-federation-controller-manager。原因是新版本 Service 名称从 kubefed-controller-manager 变更为 kube-federation-controller-manager,但旧证书的 SAN 未包含新名称。解决方案是删除旧 Secret 并让 Helm 重新生成证书。

2.6 预防性建议

  • RBAC: 使用 Infrastructure as Code 管理 RBAC 资源,每次变更后执行 kubectl auth can-i 验证。
  • CRD: 在 CI/CD 管道中加入 CRD 版本检查步骤,确保与 KubeFed 版本匹配。
  • 证书: 部署 cert-manager 并配置自动续期策略(如 renewBefore: 720h),避免证书过期。
  • 监控: 对 KubeFed-CM 的启动延迟和重启次数设置 Prometheus 告警,阈值建议为 5 分钟内重启超过 3 次。