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

迁移Kubernetes服务时,使用Istio ServiceEntry实现跨GKE集群访问内部Kubernetes FQDN的故障排查求助

问题分析

你的核心困扰在于Istio对Kubernetes集群原生域名(.svc.cluster.local后缀)的默认处理逻辑——Istio会优先把这类域名的解析请求交给集群DNS,而不是通过你配置的ServiceEntry来路由。哪怕你手动把ServiceEntry的location设为MESH_EXTERNAL,Istio的内置规则还是会优先走K8s DNS,导致你的配置没起作用。另外,你的Pod里用的是短名serviceA,如果不做额外配置,这个短名的请求可能也没被Istio正确拦截。

解决方案

这里有几个逐步推进的方案,优先推荐第一个,因为它更灵活且不影响全局配置:

方案1:用自定义虚拟域名实现路由

这个思路是绕开集群原生域名,用一个自定义域名来映射旧集群的ILB,再通过VirtualService把短名serviceA的请求转发过去。

第一步:创建指向旧集群ILB的ServiceEntry

用一个非.svc.cluster.local的域名,比如serviceA.remote,来定义外部服务:

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: serviceA-remote
  namespace: default
spec:
  hosts:
  - serviceA.remote
  location: MESH_EXTERNAL
  ports:
  - number: 50051
    name: grpc
    protocol: GRPC
  resolution: STATIC
  endpoints:
  - address: 'XX.XX.XX.XX' # 替换成旧集群内部负载均衡器的IP

第二步:配置VirtualService映射短名到虚拟域名

让Istio拦截serviceA和serviceA.default.svc.cluster.local这两个主机名的请求,转发到上面定义的serviceA.remote:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: serviceA-route
  namespace: default
spec:
  hosts:
  - serviceA
  - serviceA.default.svc.cluster.local
  gateways:
  - mesh
  http:
  - timeout: 5s
    route:
    - destination:
        host: serviceA.remote

第三步:验证配置

应用完配置后,在新集群的Pod里测试一下:

# 用Istio兼容的curl镜像测试GRPC连接
kubectl run -it --rm --image=curlimages/curl curl-test -- sh
curl -v --http2-prior-knowledge http://serviceA:50051/your/grpc/method

如果有grpcurl工具,也可以直接用它来验证GRPC服务的可用性。

方案2:调整Sidecar配置(可选)

如果你的Sidecar设置了严格的出站规则,可能需要允许访问serviceA.remote,或者放开默认出站流量:

apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
  name: default-sidecar
  namespace: default
spec:
  egress:
  - hosts:
    - "*/*" # 允许所有出站流量,也可以精确指定"default/serviceA.remote"

方案3:修改Istio全局配置(不推荐)

如果你一定要用.svc.cluster.local后缀,可以修改Istio的MeshConfig,让它忽略特定集群域名的默认DNS解析:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    serviceDiscovery:
      ignoreHosts:
      - serviceA.default.svc.cluster.local

然后重新部署Istio控制平面。不过这个方案会影响全局配置,风险较高,只作为备选。

为什么你的原始配置没生效?
  1. Istio的域名优先级规则:.svc.cluster.local是Kubernetes集群的原生服务域名,Istio默认会把这类请求交给集群DNS处理,跳过ServiceEntry的路由逻辑。新集群里没有serviceA服务,DNS解析失败或超时,就会出现你看到的upstream request timeout错误。
  2. VirtualService的主机名覆盖不全:你的VirtualService只匹配了serviceA.default.svc.cluster.local,但Pod里用的是短名serviceA,如果K8s DNS无法解析这个短名,请求可能根本没进入Istio的路由流程。

内容的提问来源于stack exchange,提问作者sc-leeds

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 01:37:45