# 基础概念
服务网格(Service Mesh)通常用于应用程序的微服务网络以及应用之间的交互.
它的需求包括服务发现、负载均衡、故障恢复、指标收集和监控以及更加复杂的运维需求.
![image.png](https://blog.zs-fighting.cn/upload/2022/08/image-e47dd7aff69946c6a58a67b15dc659d4.png)
istio是Service Mesh的一种实现,istio包括`控制平面`、`数据平面`.
每个Pod 中包含2个 Container.一个是业务Container,一个是Envoy.所有进出Pod 的流量,都会由经过 Envoy 处理.
istio的各种功能,就是在Envoy 中实现.
istiod 进程中有各种informer, 会监听K8s 对象,把监听到的变更进行聚合,生成 Envoy配置文件, 然后下发到每个 Envoy中生效.
**常用对象介绍:**
- **VirtualService**: 可以理解为更高级的K8s Service对象,具备配置路由、流量管理、故障处理、故障注入等功能.
- **DestinationRule**: VirtualService路由生效后,配置应用与请求的策略集.通常定义子集、负载均衡策略、断路器等,供 VirtualService使用.
- **Gateway**: 对外暴露的入口,南北流量走Gateway.
- **ServiceEntry**: 通常用于在istio 服务网格之外的服务,加入到Envoy cluster中.
**istio架构**
![image.png](https://blog.zs-fighting.cn/upload/2022/08/image-8a858aa06d5b4d1cbed384ab68b7a904.png)
# xDS
- **xDS是一类发现服务的总称,包含LDS, RDS, CDS, EDS, SDS, HDS, ADS。**
- **Envoy通过xDS API可以动态获取Listener(监听器),Route(路由), Cluster(集群), Endpoint(集群成员)以及Secret(证书)配置, Health(健康检查), Aggregated(一致性)。**
**发现模型如下:**
![image.png](https://blog.zs-fighting.cn/upload/2022/08/image-24fdc67a21074e789abf6e28e860f645.png)
**Listener Discovery Service(LDS)**
>简单理解,Listener是Envoy打开的一个监听端口,用于接收来自Downstream(客户端)连接。Envoy可以支持复数个Listener。多个Listener之间几乎所有的配置都是隔离的。Listener配置中核心包括监听地址、Filter链等。
**Route Discovery Service(RDS)**
>Listener可以接收来自下游的连接,Cluster可以将流量发送给具体的上游服务,而Router则决定Listener在接收到下游连接和数据之后,应该将数据交给哪一个Cluster处理.它定义了数据分发的规则.Router中最核心配置包含匹配规则和目标Cluster,此外,也可能包含重试、分流、限流等等.
**Cluster Discovery Service(CDS)**
>在Envoy中,每个Upstream上游服务都被抽象成一个Cluster.Cluster包含该服务的连接池、超时时间、endpoints地址、端口、类型(类型决定了Envoy获取该Cluster具体可以访问的endpoint方法)等等.
**Endpoint Discovery Service(EDS)**
>Envoy 通过 EDS API 可以更加智能地动态获取上游 Endpoint.在 Envoy 中用来获取集群成员.集群成员在 Envoy 的术语中被称为“终端”.
**Secret Discovery Service(SDS)**
>Secret 发现服务,用于在运行时动态获取 TLS 证书.在使用 SDS 后,集中式的 SDS 服务器将证书分发给所有的 Envoy 实例.
**Health Discovery Service(HDS,使用较少)**
>支持管理服务器对其管理的 Envoy 实例进行高效的端点健康发现.发起主动健康检查,单个 Envoy 实例通常会收到 HDS 指令,以检查所有端点的子集(subset).
**Aggregated Discover Service(ADS)**
>Envoy 的设计是最终一致的,将 xDS 所有的协议都聚合到一起,即上文提到的 CDS、EDS、LDS 和 RDS 等.可以通过单一的 gRPC 服务流支持所有的资源类型,借助于有序的配置分发,从而解决资源更新顺序的问题,CDS->EDS->LDS->RDS。
envoy配置如下:
![image.png](https://blog.zs-fighting.cn/upload/2022/08/image-a5230949b1ff4279a04948a70d03d5a7.png)
**DiscoveryRequest/DiscoveryResponse:**
![image.png](https://blog.zs-fighting.cn/upload/2022/08/image-ec90dab03ead435286a7c7d4d182fee4.png)
https://github.com/envoyproxy/envoy/blob/release/v1.22/api/envoy/api/v2/discovery.proto
# 流量管理
🌊
**istio的流量劫持机制**
`istio Init Container`会修改 Pod 的Iptables,达到流量劫持的效果.
以下命令可以观察:
```shell
# 查看Pod Iptables规则
nsenter -t $Pid -n iptables-save
# 查看listener配置
istioctl pc listener -nsidecar toolbox-68f79dd5f8-9mr5g -ojson
# 查看route配置
istioctl pc route -nsidecar toolbox-68f79dd5f8-9mr5g --name 80 -ojson
# 查看cluster、endpoint
istioctl pc cluster -nsidecar toolbox-68f79dd5f8-9mr5g -ojson
istioctl pc endpoint -nsidecar toolbox-68f79dd5f8-9mr5g -ojson
```
- **使用默认的REDIRECT模式来重定向流量,将所有出战流量都重定向到Envoy代理,转发到Envoy的15001端口.**
- **Envoy 0.0.0.0:15001上的监听器接受进出Pod的所有流量,然后将请求移交给虚拟监听器.**
- **每一个虚拟监听器对应一个listener,里面包含对应的router、cluster、endpoint.是通过xDS协议watch K8s Api获取的.**
- **Envoy使用 istio-proxy 用户身份运行, UID为1337,所有从Envoy出去的流量都会直接 return.**
如下图:
![image.png](https://blog.zs-fighting.cn/upload/2022/08/image-f67caf28e11045408fdf31cdbd49fb97.png)
# istio组件交互
🧱
- K8s informers watch 对象的变化,然后将变更的对象推送到全局唯一的 pushChannel.
- 每隔一段时间会运行Debobuce方法,合并请求和构建基于PushQueue的连接 (conn作为队列元素).
- XDSServer.doSendPush 并将env放入所有基于客户端的推送通道,每个sidecar 对应一个Connection.
- ADSServer建立与对等体的连接,从pushChannel中出列元素,通过cds → eds → lds → rds → sds (由PushOrder定义) 生成Envoy配置并发送到Envoy.
![image.png](https://blog.zs-fighting.cn/upload/2022/08/image-702132409e5a41ebb646b755be77258d.png)
# 需要注意的问题
⚠️
- **Envoy在匹配路由规则时,会按照 VirtualService 中的顺序进行匹配,列表中第一规则具有最高优先级.通常把 / 匹配放到最下方,也可以通过匹配Request header或K8s label来避免.**
- 如果服务注册发现使用etcd的话,是无法匹配Envoy规则的,因为请求的是Pod ip,无法匹配domain.
- **tracing的时候,依赖HTTP header,需要应用程序把当前的HTTP header原封不动带上,继续调用下游,Envoy 才能收到并上报给 jaeger,形成链路追踪.依赖的HTTP header如下:**
- x-request-id
- x-b3-traceid
- x-b3-spanid
- x-b3-parentspanid
- x-b3-sampled
- x-b3-flags
- x-ot-span-context
- 配置一致性检查,要做一定的监控,确保所有Envoy都收到配置.`istioctl ps`查看同步状态.
- K8s Endpoint的健康检查,istio完全依赖K8s 的检查机制.
- **记得为客户端添加超时时间,快速失败,避免客户端傻等.**
![image.png](https://blog.zs-fighting.cn/upload/2022/08/image-2fe8694957bc43e4a30efe9e1172ac5d.png)
- **记得加默认的断路器规则,通过限流保护后端程序.**
![image.png](https://blog.zs-fighting.cn/upload/2022/08/image-f0782296cf1641539dfcd9b7549958f7.png)
# 扩展
**Service Mesh涉及的网络栈**
![image.png](https://blog.zs-fighting.cn/upload/2022/08/image-5435d9a8108e40169de6d37b319468f0.png)
**Cilium 数据平面加速**
通过`eBPF`技术,不在走内核协议栈,减少kernel处理数据包的开销,提高了性能.
业界使用的效果:百度提升20%,腾讯提升5-10%.具体提升见仁见智,如果数据包很大,提升明显.
![image.png](https://blog.zs-fighting.cn/upload/2022/08/image-3b30ab9494894314b9cd6ee558ecd824.png)
云原生训练营:基于istio的流量管理