返回归档
🩻istio

服务网格 | istio

文章目录

服务网格 (Service Mesh)

核心理念

在微服务架构中,把服务间通信相关的逻辑(流量治理、安全、可观测性)从业务代码里剥离出来,交给一个独立的基础设施层去做。

服务网格起源:2016 年,William Morgan 提出;2017 年 Linkerd、Istio 等service mesh项目推动落地。

本质:先是一种理念,后来才发展为产品和生态。

好处:无侵入、一致性、安全、可观测性、流量治理、解耦。

“让一个专门的网络层代理去处理服务间通信,把这些复杂性从应用里剥离出来” → 这就是 Service Mesh 的诞生, 就像 Kubernetes 把部署、调度、运维逻辑抽象出来,服务网格则是 把微服务的通信治理抽象出来。

Kubernetes Native Networking vs Service Mesh on Kubernetes

image

使用Service Mesh 的优势

  • kube-proxy的设置是全局的,而Service Mesh 支持「服务粒度」的控制
  • Sidecar proxy抽离了service的概念,所以能够支持更多的扩展

使用Service Mesh的挑战

  • 大量的配置分发,同步和最终一致性的问题
  • 更细粒度的抽象概念,增加了用户学习和使用的成本

istio的架构

image

Composition

  • 数据平面(Envoy):Sidecar 代理,负责服务间通信与流量治理

    Envoy 组成了一个安全的微服务网络,提供:

    • 服务发现
    • L7 级别路由
    • 熔断、重试、限流
    • 策略控制
    • 遥测采集与上报(可观测性)

服务网格不是一个叠加网络,它依赖底层平台(如 K8s CNI)的网络,只是对微服务间通信进行增强。

  • 控制平面(Istiod):统一管理配置、服务发现和证书。
    • Pilot:下发配置,负责动态配置 Envoy
    • Citadel:颁发和轮换证书,提供安全认证
    • Galley:验证、聚合和分发配置

Envoy

image

Envoy是一个已经在CNCF毕业的高性能开源边缘和服务代理。它被设计用于云原生应用,通常作为Service Mesh架构中的核心数据平面。

整体定位与设计哲学

Envoy 是一个为云原生应用设计的高性能网络代理,其核心设计理念体现在两个方面:

  • L7/L4 代理与通信总线:
    • 基础: 作为网络代理,能处理 L4 (TCP/UDP) 流量。
    • 核心: 能深入理解 L7 应用层协议 (HTTP/1.1, HTTP/2, gRPC),实现精细化的流量控制。
  • 进程外架构 (Out-of-Process):
    • 模式: 作为独立的 Sidecar 进程运行,与主应用程序分离。
    • 优势:
      • 语言无关: 可与任何语言编写的应用程序协同工作。
      • 业务解耦: 将网络通信的复杂性(如服务发现、熔断、重试)从业务逻辑中剥离,让开发者专注于业务。

高性能核心架构

Envoy 的高性能源于其精巧的线程模型和网络 I/O 设计

  • 单进程多线程模型:
    • 主线程 (Main Thread): 扮演“管理者”角色,负责配置加载、xDS 通信、信号处理等协调任务,不直接处理请求
    • 工作线程 (Worker Threads): 扮演“执行者”角色,每个线程独立运行一个非阻塞事件循环 (Event Loop),负责监听、接受和处理请求的完整生命周期。这种设计避免了线程间锁竞争,性能极高。
  • 非阻塞、事件驱动:
    • 基于事件驱动的网络模型,可以用极少的线程处理海量的并发连接,实现低延迟和低资源占用。

请求的处理流程

image

Listener -> Filter Chain -> Route -> Cluster

  • Listener:请求的入口,Envoy 会监听一个或多个端口(例如 15001)。当 host A 的请求到达这个端口时,Listener 负责接收它
  • Filter Chains:请求的“处理流水线”。Listener 接收到流量后,会把它交给一个预定义的过滤器链
  • Route:决定请求的最终去向。通常在 http_connection_manager 过滤器内部,Envoy 会根据请求的特征(如 Host、URL 路径、Header 等)匹配路由规则
    • Route action
      • route: 将请求转发给一个上游集群 (Cluster)
      • redirect: 返回一个重定向响应
      • direct_response: 直接返回一个预设的响应(例如 403 Forbidden
  • Cluster:一个逻辑上的上游服务组。路由规则不会指向具体的 IP 地址,而是指向一个 Cluster,例如一个service 下的多个pod,envoy最终会从其中选择一个健康的实例来发送请求

同时,还有一些其他重要组件

  • Admin: 提供一个管理端口(默认为 9901),可以通过 HTTP API 查看 Envoy 的实时状态、配置、统计数据等,是调试和排错的重要工具
  • Stats (统计): Envoy 会产生海量且极其细致的统计指标,覆盖了网络、HTTP、上游集群等方方面面
  • Tracing (追踪): 内置支持分布式追踪,可以与 Jaeger, Zipkin, OpenTelemetry 等系统集成

Envoy 的灵魂 (xDS)

这是 Envoy 与传统代理(如 Nginx)最核心的区别。

  • 核心思想: Envoy 本身是一个**“无状态”的数据平面**,它所有的配置(Listener、Filter、Route、Cluster)都不是写死在本地的
  • 实现方式: 它通过一套名为 xDS (Discovery Service) 的 API 协议,从一个集中的控制平面 (Control Plane)(例如 Istio 的 Istiod)动态地“发现”自己的全部配置。
  • 核心 xDS 服务:
    • LDS (Listener Discovery Service): 告诉 Envoy 监听哪个端口
    • RDS (Route Discovery Service): 告诉 Envoy 路由规则是什么
    • CDS (Cluster Discovery Service): 告诉 Envoy 有哪些上游服务集群
    • EDS (Endpoint Discovery Service): 告诉 Envoy 每个集群里有哪些具体的 IP 地址和端口

总结

Envoy 是一个运行在服务旁边的 Sidecar 代理。它拦截所有进出应用的流量,并基于从控制平面通过 xDS 动态获取的配置,智能地管理和路由从 Downstream (下游) 到 Upstream (上游) 的所有网络请求。

一个来自下游 (Downstream) 的请求,首先被 Listener 捕获,然后流经一系列过滤器 (Filter Chain) 进行处理。其中,http_connection_manager 过滤器会根据路由 (Route) 规则,决定将请求转发给哪个上游集群 (Cluster)。而所有这些配置(Listener, Route, Cluster 等)都不是静态的,而是通过 xDS API 从一个集中的控制平面动态获取的。同时,Envoy 会通过 StatsTracing 模块,为整个过程提供丰富的可观测性数据

istio中的流量管理

Istio example BookInfo

image

  • Productpage(Python):入口页面,渲染书籍信息。
  • Details(Ruby):提供书籍的详细描述。
  • Reviews(Java,三种版本):展示用户评论。
    • v1:只有评论文字。
    • v2:评论 + 黑星。
    • v3:评论 + 红星。
  • Ratings(Node.js):为评论打分。

调用关系

  • 用户访问 Productpage。
  • Productpage 会:
    • 调用 Details 获取书籍详情;
    • 调用 Reviews 获取评论。
  • Reviews v2/v3 又会调用 Ratings 获取星级分数。

核心问题(没有 Istio 时):

  • Productpage 直接调用 Reviews(v1/v2/v3),但是无法做 流量控制(比如灰度发布、按比例分流)。
  • 如果 Reviews v2 依赖 Ratings,但 Ratings 挂了,就会影响整个调用链。
  • 没有安全、监控、熔断等能力。

https://istio.io/latest/docs/examples/bookinfo/

https://istio.io/latest/docs/tasks/traffic-management/

重点需要关注的CRD CR

➜  dp k get crd | grep istio.io
authorizationpolicies.security.istio.io                  2025-08-16T06:23:08Z
destinationrules.networking.istio.io2025-08-16T06:23:08Z
envoyfilters.networking.istio.io                         2025-08-16T06:23:08Z
gateways.networking.istio.io2025-08-16T06:23:08Z
peerauthentications.security.istio.io                    2025-08-16T06:23:09Z
proxyconfigs.networking.istio.io                         2025-08-16T06:23:08Z
requestauthentications.security.istio.io                 2025-08-16T06:23:09Z
serviceentries.networking.istio.io                       2025-08-16T06:23:08Z
sidecars.networking.istio.io                             2025-08-16T06:23:08Z
telemetries.telemetry.istio.io                           2025-08-16T06:23:09Z
virtualservices.networking.istio.io2025-08-16T06:23:08Zwasmplugins.extensions.istio.io                          2025-08-16T06:23:08Z
workloadentries.networking.istio.io                      2025-08-16T06:23:08Z
workloadgroups.networking.istio.io                       2025-08-16T06:23:08Z

Gateway

定义服务网格的入口点,配置外部流量如何进入网格

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: api-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 443
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: api-tls-cert
    hosts:
    - api.company.com

VirtualService

定义流量如何路由到服务,支持复杂的路由逻辑。

基于 Header 的路由

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: header-based-routing
spec:
  hosts: ["api.company.com"]
  http:
  # VIP 用户路由到高性能实例
  - match:
    - headers:
        x-user-tier: {exact: "vip"}
        x-api-version: {prefix: "v2"}
    route:
    - destination:
        host: api-service
        subset: high-performance

  # 移动端流量特殊处理
  - match:
    - headers:
        user-agent: {regex: ".*Mobile.*"}
    route:
    - destination:
        host: api-service
        subset: mobile-optimized

流量分割和金丝雀发布

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: canary-deployment
spec:
  hosts: ["api-service"]
  http:
  # 内部测试流量到新版本
  - match:
    - headers:
        x-canary: {exact: "true"}
    route:
    - destination:
        host: api-service
        subset: v2-canary

  # 生产流量逐步切换
  - route:
    - destination:
        host: api-service
        subset: v1-stable
      weight: 80  # 80% 旧版本
    - destination:
        host: api-service
        subset: v2-canary
      weight: 20  # 20% 新版本

故障注入和流量镜像

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: chaos-testing
spec:
  hosts: ["api-service"]
  http:
  # 混沌工程:注入故障
  - match:
    - headers:
        x-test-chaos: {exact: "true"}
    fault:
      delay:
        percentage: {value: 30.0}
        fixedDelay: 3s
      abort:
        percentage: {value: 10.0}
        httpStatus: 503
    route:
    - destination:
        host: api-service

  # 生产流量镜像到测试环境
  - route:
    - destination:
        host: api-service
    mirror:
      host: api-service-test
    mirrorPercentage: {value: 5.0}  # 镜像 5% 流量

DestinationRule

定义服务的网络策略,包括负载均衡、连接池、熔断等。

通常 和 VirtualService 搭配使用

  • VirtualService 决定请求怎么路由;
  • DestinationRule 定义路由后 目标服务的子集和策略

负载均衡和连接池

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: service-policies
spec:
  host: "api-service"
  trafficPolicy:
    # 负载均衡策略
    loadBalancer:
      simple: LEAST_CONN  # 最少连接

    # 连接池配置
    connectionPool:
      tcp:
        maxConnections: 100
        connectTimeout: 10s
      http:
        http1MaxPendingRequests: 50
        http2MaxRequests: 1000
        maxRequestsPerConnection: 10
        idleTimeout: 60s

熔断器配置

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: circuit-breaker
spec:
  host: "external-api-service"
  trafficPolicy:
    outlierDetection:
      consecutiveGatewayErrors: 5    # 连续网关错误
      consecutive5xxErrors: 5        # 连续 5xx 错误
      interval: 30s                  # 检测间隔
      baseEjectionTime: 30s          # 隔离时长
      maxEjectionPercent: 50         # 最多隔离 50% 实例
      minHealthPercent: 30           # 至少保持 30% 健康实例

用户粘性负载均衡

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: user-sticky-lb
spec:
  host: "session-service"
  trafficPolicy:
    loadBalancer:
      consistentHash:
        # 基于用户 ID 的粘性
        httpHeaderName: "x-user-id"

        # 或基于 Cookie 的粘性
        # httpCookie:
        #   name: "session-id"
        #   ttl: 3600s

        # 或基于客户端 IP 的粘性
        # useSourceIp: true

基于 Wasm 扩展 Envoy

Ref