原文链接:请求都去哪了?

通过前几篇文章的学习与实践,我们对 Gateway、VirtualService 和 Destinationrule 的概念和原理有了初步的认知,本篇将对这几个对象资源的配置文件进行深度地解析,具体细节将会深入到每一个配置项与 Envoy 配置项的映射关系。

在开始之前,需要先搞清楚我们创建的这些对象资源最后都交给谁来处理了,负责处理这些资源的就是 pilot。

1. pilot总体架构

首先我们回顾一下 pilot 总体架构,上面是官方关于pilot的架构图,因为是 old_pilot_repo 目录下,可能与最新架构有出入,仅供参考。所谓的 pilot 包含两个组件:pilot-agentpilot-discovery。图里的 agent 对应 pilot-agent 二进制,proxy 对应 Envoy 二进制,它们两个在同一个容器中,discovery service 对应 pilot-discovery 二进制,在另外一个跟应用分开部署的单独的 Deployment 中。

  • discovery service : 从 Kubernetes apiserver list/watch serviceendpointpodnode 等资源信息,监听 istio 控制平面配置信息(如VirtualService、DestinationRule等), 翻译为 Envoy 可以直接理解的配置格式。
  • proxy : 也就是 Envoy,直接连接 discovery service,间接地从 Kubernetes 等服务注册中心获取集群中微服务的注册情况。
  • agent : 生成 Envoy 配置文件,管理 Envoy 生命周期。
  • service A/B : 使用了 Istio 的应用,如 Service A/B,的进出网络流量会被 proxy 接管。

简单来说 Istio 做为管理面,集合了配置中心和服务中心两个功能,并把配置发现和服务发现以一组统一的 xDS 接口提供出来,数据面的 Envoy 通过 xDS 获取需要的信息来做服务间通信和服务治理。

2. pilot-discovery 为 Envoy 提供的 xds 服务

所谓 xds

pilot-discovery 为数据面(运行在 sidecar 中的 Envoy 等 proxy 组件)提供控制信息服务,也就是所谓的 discovery service 或者 xds 服务。这里的 x 是一个代词,类似云计算里的 XaaS 可以指代 IaaS、PaaS、SaaS 等。在 Istio 中,xds 包括 cds(cluster discovery service)、lds(listener discovery service)、rds(route discovery service)、eds(endpoint discovery service),而 ads(aggregated discovery service) 是对这些服务的一个统一封装。

以上 cluster、endpoint、route 等概念的详细介绍和实现细节可以参考 Envoy 在社区推广的 data plane api(github.com/envoyproxy/…),这里只做简单介绍:

  • endpoint : 一个具体的“应用实例”,对应 ip 和端口号,类似 Kubernetes 中的一个 Pod。
  • cluster : 一个 cluster 是一个“应用集群”,它对应提供相同服务的一个或多个 endpoint。cluster 类似 Kubernetes 中 Service 的概念,即一个 Kubernetes Service 对应一个或多个用同一镜像启动,提供相同服务的 Pod。
  • route : 当我们做灰度发布、金丝雀发布时,同一个服务会同时运行多个版本,每个版本对应一个 cluster。这时需要通过 route 规则规定请求如何路由到其中的某个版本的 cluster 上。

以上这些内容实际上都是对 Envoy 等 proxy 的配置信息,而所谓的 cluster discovery service、route discovery service 等 xxx discovery service 就是 Envoy 等从 pilot-discovery 动态获取 endpoint、cluster 等配置信息的协议和实现。为什么要做动态配置加载,自然是为了使用 istioctl 等工具统一、灵活地配置 service mesh。至于如何通过 istioctl 来查看 xds 信息,下文将会详细介绍。

而为什么要用 ads 来“聚合”一系列 xds,并非仅为了在同一个 gRPC 连接上实现多种 xds 来省下几个网络连接,ads 还有一个非常重要的作用是解决 cdsrds 信息更新顺序依赖的问题,从而保证以一定的顺序同步各类配置信息,这方面的讨论可以详见 Envoy官网。

如何查看 xds

pilot-discovery 在初始化阶段依次 init 了各种模块,其中 discovery service 就是 xDS 相关实现。envoy API reference 可以查到 v1 和 v2 两个版本的 API 文档。envoy control plane 给了 v2 grpc 接口相关的数据结构和接口。

那么如何查看 xds 的信息呢?虽然 v2 是 grpc 的接口,但是 pilot 提供了 InitDebug,可以通过 debug 接口查询服务和 routes 等服务和配置信息。

查看 eds

首先找到 Service istio-pilot 的 Cluster IP

$ export PILOT_SVC_IP=$(kubectl -n istio-system get svc istio-pilot -o go-template='{{.spec.clusterIP}}')
复制代码

然后查看 eds:

$ curl http://$PILOT_SVC_IP:8080/debug/edsz
复制代码
[{"clusterName": "outbound|9080||reviews.nino.svc.cluster.local","endpoints": [{"lbEndpoints": [{"endpoint": {"address": {"socketAddress": {"address": "10.244.0.56","portValue": 9080}}}}, {"endpoint": {"address": {"socketAddress": {"address": "10.244.0.58","portValue": 9080}}}}, {"endpoint": {"address": {"socketAddress": {"address": "10.244.2.25","portValue": 9080}}}}]}]
}, {"clusterName": "outbound|9080|v3|reviews.nino.svc.cluster.local","endpoints": [{"lbEndpoints": [{"endpoint": {"address": {"socketAddress": {"address": "10.244.0.58","portValue": 9080}}}}]}]
}]
复制代码

查看 cds

$ curl http://$PILOT_SVC_IP:8080/debug/cdsz
复制代码
[{"node": "sidecar~172.30.104.45~fortio-deploy-56dcc85457-b2pkc.default~default.svc.cluster.local-10", "addr": "172.30.104.45:43876", "connect": "2018-08-07 06:31:08.161483005 +0000 UTC m=+54.337448884","Clusters":[{"name": "outbound|9080||details.default.svc.cluster.local","type": "EDS","edsClusterConfig": {"edsConfig": {"ads": {}},"serviceName": "outbound|9080||details.default.svc.cluster.local"},"connectTimeout": "1.000s","circuitBreakers": {"thresholds": [{}]}
},
...
{"name": "outbound|9090||prometheus-k8s.monitoring.svc.cluster.local","type": "EDS","edsClusterConfig": {"edsConfig": {"ads": {}},"serviceName": "outbound|9090||prometheus-k8s.monitoring.svc.cluster.local"},"connectTimeout": "1.000s","circuitBreakers": {"thresholds": [{}]}
},
{"name": "BlackHoleCluster","connectTimeout": "5.000s"
}]}
]
复制代码

查看 ads

$ curl http://$PILOT_SVC_IP:8080/debug/adsz
复制代码

3. Envoy 基本术语回顾

为了让大家更容易理解后面所讲的内容,先来回顾一下 Envoy 的基本术语。

  • Listener : 监听器(listener)是服务(程序)监听者,就是真正干活的。 它是可以由下游客户端连接的命名网络位置(例如,端口、unix域套接字等)。Envoy 公开一个或多个下游主机连接的侦听器。一般是每台主机运行一个 Envoy,使用单进程运行,但是每个进程中可以启动任意数量的 Listener(监听器),目前只监听 TCP,每个监听器都独立配置一定数量的(L3/L4)网络过滤器。Listenter 也可以通过 Listener Discovery Service(LDS)动态获取。
  • Listener filter : Listener 使用 listener filter(监听器过滤器)来操作链接的元数据。它的作用是在不更改 Envoy 的核心功能的情况下添加更多的集成功能。Listener filter 的 API 相对简单,因为这些过滤器最终是在新接受的套接字上运行。在链中可以互相衔接以支持更复杂的场景,例如调用速率限制。Envoy 已经包含了多个监听器过滤器。
  • Http Route Table : HTTP 的路由规则,例如请求的域名,Path 符合什么规则,转发给哪个 Cluster。
  • Cluster : 集群(cluster)是 Envoy 连接到的一组逻辑上相似的上游主机。Envoy 通过服务发现发现集群中的成员。Envoy 可以通过主动运行状况检查来确定集群成员的健康状况。Envoy 如何将请求路由到集群成员由负载均衡策略确定。

更多详细信息可以参考 Envoy 的架构与基本术语,本文重点突出 ListenerRouteCluster 这三个基本术语,同时需要注意流量经过这些术语的先后顺序,请求首先到达 Listener,然后通过 Http Route Table 转到具体的 Cluster,最后由具体的 Cluster 对请求做出响应。

4. Gateway 和 VirtualService 配置解析

还是拿之前 Istio 流量管理 这篇文章中的例子来解析吧,首先创建了一个 Gateway,配置文件如下:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
复制代码

然后又创建了一个 VirtualService

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "*"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
        host: productpage
        port:
          number: 9080
复制代码

VirtualService 映射的就是 Envoy 中的 Http Route Table,大家可以注意到上面的 VirtualService 配置文件中有一个 gateways 字段,如果有这个字段,就表示这个 Http Route Table 是绑在 ingressgatewayListener 中的;如果没有这个字段,就表示这个 Http Route Table 是绑在 Istio 所管理的所有微服务应用的 Pod 上的。

为了分清主次,我决定将本文拆分成两篇文章来讲解,本篇主要围绕 ingressgateway 来解析 Gateway 和 VirtualService,而微服务应用本身的 VirtualService 和 DestinationRule 解析放到下一篇文章再说。

显而易见,上面这个 VirtualService 映射的 Http Route Table 是被绑在 ingressgateway 中的,可以通过 istioctl 来查看,istioctl 的具体用法请参考:调试 Envoy 和 Pilot。

首先查看 Listener 的配置项:

$ istioctl -n istio-system pc listeners istio-ingressgateway-b6db8c46f-qcfks --port 80 -o json
复制代码
[{"name": "0.0.0.0_80","address": {"socketAddress": {"address": "0.0.0.0","portValue": 80}},"filterChains": [{"filters": [{"name": "envoy.http_connection_manager","config": {..."rds": {"config_source": {"ads": {}},"route_config_name": "http.80"},...}}]}]}
]
复制代码

通过 rds 配置项的 route_config_name 字段可以知道该 Listener 使用的 Http Route Table 的名字是 http.80

查看 Http Route Table 配置项:

$ istioctl -n istio-system pc routes istio-ingressgateway-b6db8c46f-qcfks --name http.80 -o json
复制代码
[{"name": "http.80","virtualHosts": [{"name": "bookinfo:80","domains": ["*"],"routes": [{"match": {"path": "/productpage"},"route": {"cluster": "outbound|9080||productpage.default.svc.cluster.local","timeout": "0.000s","maxGrpcTimeout": "0.000s"},...},...{"match": {"prefix": "/api/v1/products"},"route": {"cluster": "outbound|9080||productpage.default.svc.cluster.local","timeout": "0.000s","maxGrpcTimeout": "0.000s"},...},...]}],"validateClusters": false}
]
复制代码
  • VirtualService 中的 hosts 字段对应 Http Route Table 中 virtualHosts 配置项的 domains 字段。这里表示可以使用任何域名来通过 ingressgateway 访问服务(也可以直接通过 IP 来访问)。
  • VirtualService 中的 exact 字段对应 Http Route Table 中 routes.match 配置项的 path 字段。
  • VirtualService 中的 prefix 字段对应 Http Route Table 中 routes.match 配置项的 prefix 字段。
  • VirtualService 中的 route.destination 配置项对应 Http Route Table 中 routes.route 配置项的 cluster 字段。

关于 Envoy 中的 HTTP 路由解析可以参考我之前的文章:HTTP 路由解析。

查看 Cluster 配置项:

$ istioctl -n istio-system pc clusters istio-ingressgateway-b6db8c46f-qcfks --fqdn productpage.default.svc.cluster.local --port 9080 -o json
复制代码
[{"name": "outbound|9080||productpage.default.svc.cluster.local","type": "EDS","edsClusterConfig": {"edsConfig": {"ads": {}},"serviceName": "outbound|9080||productpage.default.svc.cluster.local"},"connectTimeout": "1.000s","circuitBreakers": {"thresholds": [{}]}}
]
复制代码

可以看到,Cluster 最终将集群外通过 ingressgateway 发起的请求转发给实际的 endpoint,也就是 Kubernetes 集群中的 Service productpage 下面的 Pod(由 serviceName 字段指定)。

实际上 istioctl 正是通过 pilot 的 xds 接口来查看 Listener 、Route 和 Cluster 等信息的。

好了,现在请求已经转交给 productpage 了,那么接下来这个请求将会如何走完整个旅程呢?请听下回分解!

5. 参考

  • Service Mesh深度学习系列(三)| istio源码分析之pilot-discovery模块分析(中)
  • 调试 Envoy 和 Pilot
  • Envoy 的架构与基本术语

转载于:https://juejin.im/post/5ca09524f265da30d561e8a4

Istio 网关中的 Gateway 和 VirtualService 配置深度解析相关推荐

  1. autosar中bsw架构组成_AUTOSAR架构深度解析

    AUTOSAR的分层式设计,用于支持完整的软件和硬件模块的独立性(Independence),中间RTE(Runtime Environment)作为虚拟功能总线VFB(Virtual Functio ...

  2. .net core在网关中统一配置Swagger

    最近在做微服务的时候,由于我们是采用前后端分离来开发的,提供给前端的直接是Swagger,如果Swagger分布在各个API中,前端查看Swagger的时候非常不便,因此,我们试着将Swagger集中 ...

  3. 网关Spring Cloud Gateway的配置和使用

    文章目录 1. 什么是Spring Cloud Gateway? 2. Gateway与zuul的区别 3. Gateway的配置和使用 ①:常用的路由断言工厂 ②:常用的过滤器工厂(GatewayF ...

  4. 微服务中自定义gateway网关过滤器

    在学习spring Cloud时,gateway作为服务统一入口,经常需要对来历不明的请求做一些筛选. 官方提供了一些常用的过滤器 filters:- AddRequestHeader=name,zs ...

  5. 如何在gateway网关中聚合swagger

    前言 由于项目原因,需要将网关从zuul升级到gateway网关,由于 gateway网关底层是基于webflux的,导致原先在网关中集成的swagger不可用. 那么如何在gateway网关中整合s ...

  6. Istio 网关之南北向流量管理(内含服务网格专家亲自解答)

    作者 | 王夕宁  阿里巴巴高级技术专家 参与阿里巴巴云原生公众号文末留言互动,有机会获得赠书福利! 本文摘自于由阿里云高级技术专家王夕宁撰写的<Istio 服务网格技术解析与实践>一书, ...

  7. Istio 网关之南北向流量管理

    作者 | 王夕宁  阿里巴巴高级技术专家 参与阿里巴巴云原生公众号文末留言互动,有机会获得赠书福利! 本文摘自于由阿里云高级技术专家王夕宁撰写的<Istio 服务网格技术解析与实践>一书, ...

  8. 阿里高专王夕宁:Istio网关之南北向流量管理

    王夕宁 读完需要 8 分钟 速读仅需 3 分钟 作者简介:王夕宁 阿里云高级技术专家,阿里云服务网格产品ASM及Istio on Kubernetes技术负责人,专注于Kubernetes.云原生.服 ...

  9. 从0开始构建你的api网关--Spring Cloud Gateway网关实战及原理解析

    API 网关 API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题 ...

最新文章

  1. vivo检测自启动权限_VIVO手机不如苹果?那是你不知道还有这几个功能,用了就离不开...
  2. 【2017-02-20】C#基础 - 运算符//表格,示例,代码巩固练习
  3. JAVA运行时异常及检查式异常
  4. java二叉树生成器_JAVA实现二叉树生成
  5. vue2.0 $router和$route的区别
  6. platform Builder导出SDK
  7. linux设备资源分配,基于Linux 简化 AMP 配置使其更方便更动态地分配资源
  8. 《TensorFlow 2.0深度学习算法实战教材》学习笔记(四、TensorFlow 进阶)
  9. IntelliJ IDEA 设置主题背景
  10. 你的喜爱——软件测试方法和技术
  11. Win7桌面为什么变黑了?Win10未激活
  12. python数据分析-numpy学习
  13. 电子产品销售数据分析及RFM用户价值分析
  14. python3 使用相对路径 import模块
  15. MySQL中的uuid函数是什么东西
  16. 【游戏开发实战】Unity循环复用列表,支持不规则尺寸(对象池 | UGUI | ScrollRect | Demo源码)
  17. SPSS(十七)SPSS之判别分析进阶(图文+数据集)
  18. 路由器 静态、动态路由的配置
  19. 为什么看P1dB压缩,而不是2dB,3dB压缩
  20. 边学边赚,未来是否存在一份边学习边赚钱的工作?构建一个诞生未来职业的“种植果园”...

热门文章

  1. BZOJ-1024 生日快乐 DFS+一丝sb的数学思考
  2. get;get属性器
  3. Hadoop 同步集群时间ntp
  4. JavaScript 对引擎、运行时、调用堆栈的概述理解
  5. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-PLC支持哪些PLC语言类型
  6. 使用StringWriter和StringReader的好处
  7. poj-2336 Ferry Loading II(dp)
  8. 8.ActionContext类与Servlet API解耦的访问方式
  9. VC6里面的中文名字或者注释复制乱码解决
  10. 程序员写了段代码,自称完美! 网友: 我现在还在改你的Bug