3. 网格拓扑基础:服务注册、服务发现、流量路由规则、VirtualService 与 DestinationRule
在 Istio 网格中,服务间的通信并非直接由 Pod IP 或 Service ClusterIP 驱动,而是通过一套抽象的控制平面组件与数据平面代理协同完成。理解网格拓扑,首先需要掌握服务如何被注册、发现,以及流量如何被规则引导。本章将拆解这四个核心概念,并重点分析 VirtualService 与 DestinationRule 的协作关系。
3.1 服务注册与发现:网格的“通讯录”
传统 Kubernetes 中,服务发现依赖 kube-proxy 和 ClusterIP。在 Istio 网格中,Pilot 组件接管了这一职责,构建出更精细的“服务注册中心”。
| 组件/概念 | 角色说明 | 数据来源 |
|---|---|---|
| Pilot | 网格控制平面核心,负责服务发现与配置下发 | Kubernetes API Server + Service/Endpoint |
| Service Registry | Pilot 内部维护的服务与实例映射表 | 自动同步自 K8s Service & Pod |
| Envoy (Sidecar) | 数据平面代理,通过 xDS 协议从 Pilot 拉取发现结果 | Pilot 下发的 LDS/CDS/EDS |
| ServiceEntry | 手动注册外部服务到网格的 CRD | 用户 YAML 定义 |
关键理解: 网格内的服务发现粒度是 Pod 级别 的。Envoy 拿到的是后端 Pod 的 IP:Port 列表,而非 Service ClusterIP。这使得 L7 路由和灰度发布成为可能。
3.2 流量路由规则:VirtualService 与 DestinationRule
流量路由是 Istio 最核心的运维能力。它通过两个 CRD 解耦了“路由逻辑”与“后端策略”:
- VirtualService:定义“流量怎么走”。匹配来源、路径、Header,然后转发到指定 Host。
- DestinationRule:定义“后端怎么处理”。配置负载均衡、连接池、熔断、TLS 以及子集(Subset)划分。
常见误区: VirtualService 中
host 字段指向的是 K8s Service 的 DNS 名称,而非 Pod IP。DestinationRule 中的 host 必须与 VirtualService 中 host 或 destination.host 完全匹配,否则规则不生效。
3.3 VirtualService 深度解析
VirtualService 是网格流量的“交通指挥员”。它支持丰富的匹配条件和流量操作。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: reviews-vs
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
weight: 80
- destination:
host: reviews
subset: v3
weight: 20
上述配置的关键点:
- hosts:监听 reviews 服务的流量。
- match:如果 Header
end-user等于jason,则路由到subset: v2。 - weight:其余流量按 80/20 比例分发到 v1 和 v3。
3.4 DestinationRule 与 Subset 定义
DestinationRule 负责定义后端实例的分组(Subset)以及流量策略。Subset 通常基于 Pod 的标签(如 version: v1)进行选择。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: reviews-dr
spec:
host: reviews
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
connectionPool:
tcp:
maxConnections: 100
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
协作关系: VirtualService 中的
subset: v2 必须对应 DestinationRule 中定义的 subsets[0].name: v2。如果 DestinationRule 未定义 v2,VirtualService 引用 v2 会导致路由失败。
3.5 网格拓扑与路由规则的关系图
下图展示了从客户端请求到后端 Pod 的完整拓扑路径,以及 VirtualService 和 DestinationRule 在其中的作用位置。
3.6 服务发现与路由的完整数据流
为了更清晰地理解控制平面与数据平面的交互,下图展示了 Pilot 如何将 Service、VirtualService、DestinationRule 转化为 Envoy 可理解的配置。
3.7 故障排查要点
当网格拓扑出现流量中断或路由异常时,按以下顺序排查:
- 检查 Service 是否存在:
kubectl get svc reviews,确认 Selector 匹配到 Pod。 - 检查 VirtualService 是否生效:
istioctl proxy-status确认 Sidecar 已收到配置。 - 检查 DestinationRule Subset 标签:
kubectl get pod -l version=v2,确认 Pod 存在且标签正确。 - 检查 Envoy 路由表:
istioctl proxy-config route <pod-name>查看实际路由条目。 - 检查 Pilot 日志:
kubectl logs -n istio-system deployment/istiod搜索reviews相关错误。
核心原则: 网格拓扑的故障 90% 源于 VirtualService 的
host 与 DestinationRule 的 host 不匹配,或者 Subset 标签与 Pod 标签不一致。始终从“两端对齐”的角度入手。