Istio 对 Golang 服务的流量控制本质是 Envoy Sidecar 接管流量,而非代码侵入;Golang 服务需监听 0.0.0.0、使用 FQDN 调用、正确配置 subsets 和 VirtualService,否则所有策略失效。

Istio 对 Golang 服务的流量控制不是靠“学 Go 时加个库”实现的,而是靠部署时让 Envoy Sidecar 接管网络流量——Golang 代码本身几乎不用改,但监听地址、调用方式、健康探针这些细节稍有偏差,所有 VirtualService 和 DestinationRule 都会失效。
Go 服务监听地址必须是 0.0.0.0,不能是 127.0.0.1
Envoy 的 iptables 规则只劫持发往 Pod IP 的流量,127.0.0.1 请求完全绕过代理, inbound 流量直接进 Go 进程,VirtualService 路由、超时、重试全部不生效。
- 错误写法:
http.ListenAndServe("127.0.0.1:8080", handler) - 正确写法:
http.ListenAndServe(":8080", handler)或http.ListenAndServe("0.0.0.0:"+os.Getenv("PORT"), handler) - 如果用了
net/http.Server,务必设置Addr为":8080",而非带 IP 的字符串 -
livenessProbe和readinessProbe可继续用http://127.0.0.1:8080/healthz——这是 Istio 显式放行的例外路径
出向调用必须用 Kubernetes FQDN,不能用短服务名
现象是 http.Get("http://orders:8080/api") 报 dial tcp: lookup orders on 10.96.0.10:53: no such host,本质是 DNS 查询成功了,但流量根本没进 istio-proxy ——因为短名解析后可能直连 ClusterIP,跳过了 Envoy outbound 劫持。
- 必须用全限定域名:
http.Get("http://orders.default.svc.cluster.local:8080/api") - 跨命名空间时,FQDN 更不可省略,例如
orders.prod.svc.cluster.local - 避免在客户端设置
http.Transport.Proxy,否则会绕过 Envoy - gRPC 客户端需用
dns:///orders.default.svc.cluster.local格式(注意三个斜杠)
DestinationRule 的 subsets 必须存在且标签匹配,否则权重路由无效
VirtualService 的 weight 不是按 Deployment 或 Service 分,而是按 DestinationRule 里定义的 subsets 分。漏配 subsets 或标签对不上,所有流量都会 fallback 到默认子集(通常是第一个),灰度完全不生效。
立即学习“go语言免费学习笔记(深入)”;
-
subsets的labels必须和对应 Deployment 的 Pod labels 完全一致,比如version: v2 -
subsets名称要简短、小写、无特殊字符(如v2),VirtualService中引用时大小写敏感 - 若用 gRPC,
port.name在 Deployment 中必须设为grpc,否则 Envoy 可能无法识别协议并降级为 HTTP -
weight总和必须严格等于 100,Istio 不做归一化;70 + 25 = 95 → 剩余 5% 流量走默认目标,不是按比例分配
验证流量是否真被 Envoy 劫持,不能只看 2/2 状态
kubectl get pod 显示 2/2 只代表两个容器都启动了,不代表 Envoy 正在转发流量。必须三步验证:
- 查状态:
kubectl describe pod <name>确认istio-proxy容器Ready为true,且无CrashLoopBackOff - 看日志:
kubectl logs <name> -c istio-proxy | grep "started"应输出transport: listening on 15001(inbound)和admin: listening on 15090 - 抓包(最关键):
kubectl exec -it <name> -c istio-proxy -- tcpdump -i any port 15001 or port 15006 -c 2,再从另一 Podcurl该服务,必须看到命中15001或15006的包
没抓到包?90% 是监听地址或 FQDN 写错了,而不是 Istio 没装好。


















