Istio

通过负载均衡、服务间的身份验证、监控等方法,Istio 可以轻松地创建一个已经部署了服务的网络,而服务的代码只需很少更改甚至无需更改。通过在整个环境中部署一个特殊的 sidecar 代理为服务添加 Istio 的支持,而代理会拦截微服务之间的所有网络通信,然后使用其控制平面的功能来配置和管理 Istio,这包括:

  • 为 HTTP、gRPC、WebSocket 和 TCP 流量自动负载均衡。
  • 通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制。
  • 可插拔的策略层和配置 API,支持访问控制、速率限制和配额。
  • 集群内(包括集群的入口和出口)所有流量的自动化度量、日志记录和追踪。
  • 在具有强大的基于身份验证和授权的集群中实现安全的服务间通信。

Istio 为可扩展性而设计,可以满足不同的部署需求。

image-20220213215403816

image-20220219210538613

核心特性

Istio 以统一的方式提供了许多跨服务网络的关键功能:

流量管理

Istio 简单的规则配置和流量路由允许您控制服务之间的流量和 API 调用过程。Istio 简化了服务级属性(如熔断器、超时和重试)的配置,并且让它轻而易举的执行重要的任务(如 A/B 测试、金丝雀发布和按流量百分比划分的分阶段发布)。

有了更好的对流量的可视性和开箱即用的故障恢复特性,您就可以在问题产生之前捕获它们,无论面对什么情况都可以使调用更可靠,网络更健壮。

为了在网格中导流,Istio 需要知道所有的 endpoint 在哪和属于哪个服务。为了定位到service registry(服务注册中心),Istio 会连接到一个服务发现系统。例如,如果您在 Kubernetes 集群上安装了 Istio,那么它将自动检测该集群中的服务和 endpoint。

使用此服务注册中心,Envoy 代理可以将流量定向到相关服务。大多数基于微服务的应用程序,每个服务的工作负载都有多个实例来处理流量,称为负载均衡池。默认情况下,Envoy 代理基于轮询调度模型在服务的负载均衡池内分发流量,按顺序将请求发送给池中每个成员,一旦所有服务实例均接收过一次请求后,重新回到第一个池成员。

Istio 基本的服务发现和负载均衡能力为您提供了一个可用的服务网格,但它能做到的远比这多的多。在许多情况下,您可能希望对网格的流量情况进行更细粒度的控制。作为 A/B 测试的一部分,您可能想将特定百分比的流量定向到新版本的服务,或者为特定的服务实例子集应用不同的负载均衡策略。您可能还想对进出网格的流量应用特殊的规则,或者将网格的外部依赖项添加到服务注册中心。通过使用 Istio 的流量管理 API 将流量配置添加到 Istio,就可以完成所有这些甚至更多的工作。

虚拟服务(Virtual Service)目标规则(Destination Rule) 是 Istio 流量路由功能的关键拼图。虚拟服务让您配置如何在服务网格内将请求路由到服务,这基于 Istio 和平台提供的基本的连通性和服务发现能力。每个虚拟服务包含一组路由规则,Istio 按顺序评估它们,Istio 将每个给定的请求匹配到虚拟服务指定的实际目标地址。您的网格可以有多个虚拟服务,也可以没有,取决于您的使用场景。

您可以将虚拟服务视为将流量如何路由到给定目标地址,然后使用目标规则来配置该目标的流量。在评估虚拟服务路由规则之后,目标规则将应用于流量的“真实”目标地址。

安全

Istio 的安全特性解放了开发人员,使其只需要专注于应用程序级别的安全。Istio 提供了底层的安全通信通道,并为大规模的服务通信管理认证、授权和加密。有了 Istio,服务通信在默认情况下就是受保护的,可以让您在跨不同协议和运行时的情况下实施一致的策略——而所有这些都只需要很少甚至不需要修改应用程序。

Istio 是独立于平台的,可以与 Kubernetes(或基础设施)的网络策略一起使用。但它更强大,能够在网络和应用层面保护pod到 pod 或者服务到服务之间的通信。

请参考安全文档获取更多细节。

可观察性

Istio 健壮的追踪、监控和日志特性让您能够深入的了解服务网格部署。通过 Istio 的监控能力,可以真正的了解到服务的性能是如何影响上游和下游的;而它的定制 Dashboard 提供了对所有服务性能的可视化能力,并让您看到它如何影响其他进程。

Istio 的 Mixer 组件负责策略控制和遥测数据收集。它提供了后端抽象和中介,将一部分 Istio 与后端的基础设施实现细节隔离开来,并为运维人员提供了对网格与后端基础实施之间交互的细粒度控制。

所有这些特性都使您能够更有效地设置、监控和加强服务的 SLO。当然,底线是您可以快速有效地检测到并修复出现的问题。

请参考可观察性文档获取更多细节。

平台支持

Istio 独立于平台,被设计为可以在各种环境中运行,包括跨云、内部环境、Kubernetes、Mesos 等等。您可以在 Kubernetes 或是装有 Consul 的 Nomad 环境上部署 Istio。Istio 目前支持:

  • Kubernetes 上的服务部署
  • 基于 Consul 的服务注册
  • 服务运行在独立的虚拟机上

整合和定制

Istio 的策略实施组件可以扩展和定制,与现有的 ACL、日志、监控、配额、审查等解决方案集成。

组件

Envoy

Istio 使用 Envoy 代理的扩展版本。Envoy 是用 C++ 开发的高性能代理,用于协调服务网格中所有服务的入站和出站流量。Envoy 代理是唯一与数据平面流量交互的 Istio 组件。

Envoy 代理被部署为服务的 Sidecar,在逻辑上为服务增加了 Envoy 的许多内置特性,例如:

  • 动态服务发现
  • 负载均衡
  • TLS 终端
  • HTTP/2 与 gRPC 代理
  • 熔断器
  • 健康检查
  • 基于百分比流量分割的分阶段发布
  • 故障注入
  • 丰富的指标

这种 Sidecar 部署允许 Istio 可以执行策略决策,并提取丰富的遥测数据,接着将这些数据发送到监视系统以提供有关整个网格行为的信息。

Sidecar 代理模型还允许您向现有的部署添加 Istio 功能,而不需要重新设计架构或重写代码。

由 Envoy 代理启用的一些 Istio 的功能和任务包括:

  • 流量控制功能:通过丰富的 HTTP、gRPC、WebSocket 和 TCP 流量路由规则来执行细粒度的流量控制。
  • 网络弹性特性:重试设置、故障转移、熔断器和故障注入。
  • 安全性和身份认证特性:执行安全性策略,并强制实行通过配置 API 定义的访问控制和速率限制。
  • 基于 WebAssembly 的可插拔扩展模型,允许通过自定义策略执行和生成网格流量的遥测。

流量拦截

sidecar基于iptables规则(由init容器在pod启动时候首先设置iptables规则),拦截应用容器Inbound/outbound流量。目前只拦截TCP流量,不能UDP。

inbound

  • init,envoy, app
    • inbound流量进入pod网络协议时首先被iptables规则拦截
    • iptables规则转发到数据包到envoy
    • envoy根据自身监听器配置,将流量转发给应用进程。(envoy转发到app也是经由iptables规则处理)

outbound

  • app, init,envoy,init
    • outbound由APP发出,被iptables规则
    • iptables规则将出口数据包转到envoy
    • envoy根据自身配置决定是否将流量转发到容器外

Istiod

在 Istio 1.5 中,更改了 Istio 的打包方式,将控制平面功能合并为一个被称为 istiod 的二进制文件

Istiod 提供服务发现、配置和证书管理。

Istiod 将控制流量行为的高级路由规则转换为 Envoy 特定的配置,并在运行时将其传播给 Sidecar。Pilot 提取了特定平台的服务发现机制,并将其综合为一种标准格式,任何符合 Envoy API 的 Sidecar 都可以使用。

Istio 可以支持发现多种环境,如 Kubernetes 或 VM。

您可以使用 Istio 流量管理 API 让 Istiod 重新构造 Envoy 的配置,以便对服务网格中的流量进行更精细的控制。

Istiod 安全通过内置的身份和凭证管理,实现了强大的服务对服务和终端用户认证。您可以使用 Istio 来升级服务网格中未加密的流量。使用 Istio,运营商可以基于服务身份而不是相对不稳定的第 3 层或第 4 层网络标识符来执行策略。此外,您可以使用 Istio 的授权功能控制谁可以访问您的服务。

Istiod 充当证书授权(CA),并生成证书以允许在数据平面中进行安全的 mTLS 通信。

流量管理

image-20221025145534857

istio所有资源对象最后都会转换成Envoy代理的配置,通过远程下发给pod里面的sidecar

image-20221025145851849

image-20221025150140603

VirtualService

可以配置一个虚拟服务处理特定命名空间中的所有服务。

通过对客户端请求的目标地址与真实响应请求的目标工作负载进行解耦来实现。虚拟服务同时提供了丰富的方式,为发送至这些工作负载的流量指定不同的路由规则

  • 您的路由规则可以指定为“对这些 monolith.com 的 URI 调用转到microservice A”等等。
  • 网关整合并配置流量规则来控制出入流量。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts: # 即用户指定的目标或是路由规则设定的目标 IP 地址、DNS 名称,或者依赖于平台的一个简称(例如 Kubernetes 服务的短名称),隐式或显式地指向一个完全限定域名(FQDN)。您也可以使用通配符(“*”)前缀
  - reviews
  http:
  - match: # 路由规则 用来描述匹配条件和路由行为,把流量发送到 hosts 字段指定的目标。一个路由规则包含了指定的请求要流向哪个目标地址,具有 0 或多个匹配条件,取决于您的使用场景。
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v3

VirtualService 描述满足什么条件的流量被哪个后端处理。

  • 蓝绿,金丝雀(流量切换,分配)

DestinationRule描述的是这个请求到达某个后端后怎么去处理,定义满足路由规则的流量到达后端后的访问策略。

  • 熔断,负载均衡

网关

在网格边缘接收外部访问,将流量转发到网格内服务。配置外部访问端口,协议以及内部服务映射关系。可以配合VirtualService使用

Gateway定义服务从外面怎样访问,VirtualService定义匹配到外部服务怎样流转。

网格来管理入站和出站流量,网关配置被用于运行在网格边界的独立 Envoy 代理,而不是服务工作负载的 sidecar 代理。

您可以这么做的原因是 Istio 的网关资源可以配置 4-6 层的负载均衡属性,如对外暴露的端口、TLS 设置等。作为替代应用层流量路由(L7)到相同的 API 资源,您绑定了一个常规的 Istio 虚拟服务到网关

image-20220401171421767

服务入口ServiceEntry

把网格外的服务加入Istio的服务发现,像网格内的服务一样进行管理。

使用服务入口(Service Entry) 来添加一个入口到 Istio 内部维护的服务注册中心。添加了服务入口后,Envoy 代理可以向服务发送流量,就好像它是网格内部的服务一样。配置服务入口允许您管理运行在网格外的服务的流量,它包括以下几种能力:

  • 为外部目标 redirect 和转发请求,例如来自 web 端的 API 调用,或者流向遗留老系统的服务。
  • 为外部目标定义重试超时故障注入策略。
  • 添加一个运行在虚拟机的服务来扩展您的网格

监控

istio通过Adapter机制来实现

sidecar代理上报监控数据到APM,存在问题

  • 每当APM服务端发生改变,sidecar作为数据采集端随之变更。
  • 提高APM能力,APM数量上升,网络拓扑乱

Istio引入服务端组件Mixer,作为APM和采集端的解耦,Istio数据面代理无需修改

  • APM协议改变,只需修改Mixer对接的Adapter的对应接口。
  • APM上报数据格式改变,只需修改Adapter的数据定义
  • 对接新APM,只需基于Mixer的Adapter机制开发对应的Adapter

Service Mesh架构对比

image-20221024154807321

目前架构

sidecar模式

image-20221024155219833

数据平面结构

image-20221024162102429

image-20221024155331405

  • init容器最先启动用来拦截进出pod流量,在pod里面创建Iptables规则

  • envoy代理使用xDS协议向控制平面获取代理配置

    image-20221024163925345

proxy less

image-20221024161114368

不需要pod的sidecar注入Envoy代理,提升应用性能,降低网络延迟。

Sidecar 注入、透明流量劫持及流量路由过程详解

https://jimmysong.io/blog/sidecar-injection-iptables-and-traffic-routing/

多集群模式

多控制面

每个集群分别部署自己独立Istio控制面,管理各自endpoints

  • 共享root ca,支持集群间TLS双向认证
  • 不要求共享网络,跨集群访问通过Istio gateway转发,gateway 通过VIP供集群外部访问。
  • cidr可以重叠,Istio控制面只管理各自endpoints
  • 同一集群内服务访问,和单机一样
  • 跨集群使用ServiceEntry规则,将remote集群服务暴露到local,依赖remote集群的gateway做流量转发

默认带.global的服务走私有域,修改coredns配置,指向istiocoredns服务(每个集群部署的组件)。

  • 为支持的Remote集群的foot服务的访问创建对应ServiceEntry
  • local集群访问foot.ns.global,进行DNS解析,送到kube-dns,根据配置转发到istiocoredns(私有dns服务器)
  • istiocoredns通过api-server获取ServiceEntry来得到对应域名IP

集群感知服务路由单控制面

使用单个控制面,istio控制面需要连接所有k8s的api-server, 依赖集群感知或者水平分割EDS(endpoint discovery service)

Split HorizonEDS模型在同一个内部请求转发与单集群模型一样,跨集群访问通过目标集群被用来转发服务请求。

转发请求使用SNI路由

  • Split HorizonEDS要求istio必须打开双TLS
  • Gateway转发需要配置规则,接受并转发有.global后缀的服务的请求。

流量过程

  • 请求会被sidecar拦截,根据路由算法选择合适后端(local 集群pod IP 或者 remote 集群的Gateway IP),把请求转发出去。
  • 跨集群转发,Gateway解析TLS证书的SNI,根据SNI选择合适路由

核心技术就是让sidecar生成EDS配置,将EDS配置ClusterLoadAssignment中的LbEndpoint地址转换为remote集群的GatewayIP

Pilot需要连接所有集群的kube-apiserver,在控制面上的集群中Pilot通过内置pod凭证连接local集群,其他集群则通过特殊的secret(包含集群ID和对应的kubeconfig),为每个集群创建一个控制器,监视集群内所有服务和相关资源对象。