大家好!今天,我们将深入探讨服务网格的代名词Istio的内部工作原理。🧐
在运营微服务架构(MSA)时,控制、应用策略和监控众多服务之间的流量会变得异常复杂。Istio正是为了解决这个问题而出现的。Istio由与服务一起部署的“Sidecar代理” Envoy,以及集中管理这些代理的“控制平面” Istiod组成。
这里产生了一个疑问。
“Istiod是如何实时地向如此多的Envoy代理下达命令并更新配置的呢?”
现在,我们将揭示这种惊人通信方式的秘密,它就像一个中央控制塔与数百架飞机实时通信一样!

🏛️ 首先看全貌:控制平面 vs 数据平面
在深入了解通信方式之前,我们首先需要理解整体架构。
- 控制平面 (Control Plane – Istiod) 🧠
- 充当服务网格的“大脑”。
- 管理所有配置和策略,并汇总服务发现信息。
- 解析开发人员编写的VirtualService、DestinationRule等YAML文件,并将其转换为Envoy可以理解的配置。
- 数据平面 (Data Plane – Envoy Proxies) 💪
- 充当服务网格的“手脚”。
- 以Sidecar形式附加在每个应用程序容器旁边,拦截所有网络流量(入站/出站)。
- 根据从控制平面接收到的配置,执行流量路由、负载均衡、安全策略应用等实际工作。
核心在于“大脑”(Istiod)如何实时控制“手脚”(Envoy)。
🚀 核心是“Push”模型:实时更新的秘密
简而言之,Istiod采用当发生变更时,将所需配置推送(Push)给Envoy代理的方式。
这为什么重要?我们将分步探讨这个过程。
- 变化检测 📡: Istiod持续监控Kubernetes API服务器。它会立即检测所有变化,例如新服务的部署、现有服务的Pod扩容,或VirtualService等路由规则的修改。
- 配置转换 ⚙️: 检测到变化后,Istiod会计算此变更会影响哪些Envoy代理。然后,它会为这些代理生成新的配置。
- 动态推送(Push) ⚡️: Istiod会立即将新生成的配置推送给受影响的Envoy代理。此时,它不会发送完整的配置,而是传递关于变更部分的优化信息。
所有这些过程都通过一个名为xDS (Discovery Service) API的标准协议,在高效的gRPC流上进行。这使得非常快速和稳定的实时更新成为可能。
🗣️ 他们使用的语言:xDS API和gRPC
Istiod和Envoy并非随意对话。它们使用一种名为“xDS”的标准化语言。xDS是各种“发现服务”的总称。
- LDS (Listener Discovery Service): 关于Envoy应在哪个端口监听以及接收何种流量的配置 👂
- RDS (Route Discovery Service): 关于根据特定规则将接收到的流量发送到何处的路由配置 🗺️
- CDS (Cluster Discovery Service): 关于流量将发送到的目标服务(Cluster)组的信息 🏢
- EDS (Endpoint Discovery Service): 属于每个服务(Cluster)的实际Pod的IP地址和端口列表 📍
这些信息通过gRPC流,在持续连接的通道上实时传输。
通过简单示例理解
假设开发人员部署了一个VirtualService,将“reviews”服务的流量分别以90%和10%的比例分配给v1和v2版本。
1. 开发人员应用的VirtualService(输入)
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 90
- destination:
host: reviews
subset: v2
weight: 10
2. Istiod的响应
- Istiod通过Kubernetes API检测到上述VirtualService的创建。
- 它计算出此路由规则会影响所有将流量发送到“reviews”服务的Envoy代理。
- 它生成一个将传递给受影响Envoy的RDS更新。
3. Envoy接收到的配置(概念性原始数据)
Envoy通过xDS接收到如下所示的转换配置。(这是为了便于理解而简化的格式。)
# RDS (路由发现服务) 响应的一部分 (概念性表示)
# Istiod生成并向Envoy推送此类信息。
{
"name": "http.8080",
"virtual_hosts": [
{
"name": "reviews:8080",
"domains": ["reviews", "reviews:8080", ...],
"routes": [
{
"match": { "prefix": "/" },
"route": {
"cluster": "outbound|8080|v1|reviews.default.svc.cluster.local",
"weighted_clusters": {
"clusters": [
{
"name": "outbound|8080|v1|reviews.default.svc.cluster.local",
"weight": 90 // 👈 90% 流量权重
},
{
"name": "outbound|8080|v2|reviews.default.svc.cluster.local",
"weight": 10 // 👈 10% 流量权重
}
]
}
}
}
]
}
]
}
因此,Envoy开始按照开发人员的意图,精确地将流量以90:10的比例分配。所有这些过程都在几秒钟内自动发生!
🤔 纠正常见误解
在讨论Istio的通信方式时,经常会出现一些常见的误解。让我们看看为什么这些是错误的。
- “Envoy不是周期性地询问吗?(Pull方式)” ❌
- 为什么不是?: 想象一下,如果Envoy每10秒就问Istiod“有没有新配置?”。即使没有变化,大量的代理也会产生不必要的网络流量。此外,如果发生重要的策略变更,可能会有长达10秒的延迟。这不适用于需要实时响应的MSA环境。
- “不是每隔固定时间批量接收吗?(Fixed Interval)” ❌
- 为什么不是?: 这也与Pull方式有类似的缺点。即使没有变化,到固定时间也会发生通信;如果发生变化,也必须等到下一个周期。与事件驱动的Push方式相比,这种方式效率低得多,速度也慢。
总而言之,Istio的“事件驱动型推送”方式在效率、实时性和可扩展性方面都是最优秀的架构。
✨ 总结
今天,我们探讨了Istio的核心大脑Istiod如何与数据平面中的Envoy代理进行“心灵感应”般的通信。
总结核心要点,即Istiod实时检测变更,并通过xDS API,利用gRPC流,动态地将最新配置“推送”给所需的Envoy。
正是由于这种智能高效的通信方式,我们才能在复杂的微服务环境中自由控制流量并迅速应用策略。如果您正在使用Istio,请记住,这种无形的智能通信正在此刻发生!😉
发表回复