You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cloud Kubernetes跨命名空间服务发现异常排查

跨命名空间服务发现问题排查与解决

问题背景

在Kubernetes的welcoming和default两个命名空间中运行Spring Boot应用,服务配置如下:

SPRING_CLOUD_KUBERNETES_DISCOVERY_NAMESPACES_0: welcoming
SPRING_CLOUD_KUBERNETES_DISCOVERY_NAMESPACES_1: default
SPRING_CLOUD_KUBERNETES_ENABLED: true
SPRING_CLOUD_KUBERNETES_LOADBALANCER_MODE: SERVICE
SPRING_CLOUD_KUBERNETES_RELOAD_ENABLED: true
SPRING_CLOUD_LOADBALANCER_CACHE_ENABLED: true

当welcoming命名空间的retail-onboarding服务通过RestTemplate调用default命名空间的audit-service时,抛出服务实例找不到的错误,尽管日志显示Kubernetes发现客户端已列出该服务:

2024-07-08T08:51:59.290Z DEBUG [retail-onboarding,,] 1 --- [nio-8080-exec-3] .c.k.f.d.Fabric8DiscoveryServicesAdapter : searching in namespaces : [welcoming, default] with filter : null 

2024-07-08T08:51:59.336Z DEBUG [retail-onboarding,,] 1 --- [io-8080-exec-10] o.s.c.k.f.d.KubernetesDiscoveryClient    : will return services : [retail-onboarding, audit-service, ingress-nginx-controller, ingress-nginx-controller-admission, kubernetes,]

2024-07-08T08:52:22.099Z ERROR [retail-onboarding,,] 1 --- [nio-8080-exec-9] c.b.f.i.a.RunWithoutAuthorizationAspect  : Exception thrown when invoking join point

com.backbase.audit.client.exceptions.InternalServerErrorException: java.lang.IllegalArgumentException: Service Instance cannot be null, serviceId: audit-service                                                                                                                         Caused by: java.lang.IllegalArgumentException: Service Instance cannot be null, serviceId: audit-service

切换为SPRING_CLOUD_KUBERNETES_DISCOVERY_ALL_NAMESPACES: true后,服务调用恢复正常。已配置跨命名空间服务发现的ClusterRole和ClusterRoleBinding:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cross-namespace-service-discovery
rules:
- apiGroups: [""]
  resources: ["pods", "services", "endpoints"]
  verbs: ["get", "list", "watch"]

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cross-namespace-service-discovery-binding
subjects:
- kind: ServiceAccount
  name: default
  namespace: welcoming
roleRef:
  kind: ClusterRole
  name: cross-namespace-service-discovery
  apiGroup: rbac.authorization.k8s.io

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cross-namespace-service-discovery-binding
subjects:
- kind: ServiceAccount
  name: default
  namespace: default
roleRef:
  kind: ClusterRole
  name: cross-namespace-service-discovery
  apiGroup: rbac.authorization.k8s.io

问题原因分析

  1. 配置格式不兼容:SPRING_CLOUD_KUBERNETES_DISCOVERY_NAMESPACES_0/1这种索引式配置属于旧版Spring Boot绑定规则,在较新的Spring Cloud Kubernetes版本中无法被正确解析,导致指定的命名空间未被实际扫描。
  2. RBAC配置冲突:两个ClusterRoleBinding使用了相同的名称cross-namespace-service-discovery-binding,后创建的绑定会覆盖前一个,导致welcoming命名空间的ServiceAccount未获得跨命名空间访问权限。
  3. 负载均衡缓存干扰:启用缓存后,若初始配置未生效,缓存中会保留旧的服务发现数据,即使后续配置修正,也无法立即获取跨命名空间的服务实例。
  4. 实例元数据缺失:虽然Discovery Client能列出服务,但可能因权限问题未拉取到default命名空间的endpoints元数据,导致负载均衡器找不到可用实例。

解决方案

1. 修正命名空间配置格式

改用逗号分隔的标准配置格式,确保新旧版本都能正确解析:

SPRING_CLOUD_KUBERNETES_DISCOVERY_NAMESPACES: welcoming,default

2. 修复RBAC绑定冲突

修改ClusterRoleBinding的名称,避免覆盖:

# welcoming命名空间的绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cross-namespace-service-discovery-binding-welcoming
subjects:
- kind: ServiceAccount
  name: default
  namespace: welcoming
roleRef:
  kind: ClusterRole
  name: cross-namespace-service-discovery
  apiGroup: rbac.authorization.k8s.io

---

# default命名空间的绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cross-namespace-service-discovery-binding-default
subjects:
- kind: ServiceAccount
  name: default
  namespace: default
roleRef:
  kind: ClusterRole
  name: cross-namespace-service-discovery
  apiGroup: rbac.authorization.k8s.io

3. 清理并优化负载均衡缓存

  • 重启retail-onboarding服务清除本地缓存;
  • 配置合理的缓存过期时间,避免旧数据干扰:
SPRING_CLOUD_LOADBALANCER_CACHE_TTL: 30s

4. 验证权限与服务状态

  • 检查welcoming命名空间的ServiceAccount权限:
kubectl config set-context --current --namespace=welcoming
kubectl auth can-i list endpoints --namespace=default

返回yes则权限正常。

  • 确认audit-service的endpoints存在可用实例:
kubectl get endpoints audit-service -n default

总结

核心问题是配置格式不兼容和RBAC绑定名称冲突,修正这两点后配合缓存清理,即可实现跨命名空间服务的可靠发现与调用。

内容的提问来源于stack exchange,提问作者Tarun Bharti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 12:07:04