Istio,你是不是会心灵感应?Envoy与Istiod的秘密通信方式 🤫

大家好!今天,我们将深入探讨服务网格的代名词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代理的方式。

这为什么重要?我们将分步探讨这个过程。

  1. 变化检测 📡: Istiod持续监控Kubernetes API服务器。它会立即检测所有变化,例如新服务的部署、现有服务的Pod扩容,或VirtualService等路由规则的修改。
  2. 配置转换 ⚙️: 检测到变化后,Istiod会计算此变更会影响哪些Envoy代理。然后,它会为这些代理生成新的配置。
  3. 动态推送(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的响应

  1. Istiod通过Kubernetes API检测到上述VirtualService的创建。
  2. 它计算出此路由规则会影响所有将流量发送到“reviews”服务的Envoy代理。
  3. 它生成一个将传递给受影响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,请记住,这种无形的智能通信正在此刻发生!😉



Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注