Istio 深入理解数据平面组件 Envoy

ingress control承载了控制面和数据面的一个职责,在control里面有一个process,这个进程就承担了反向代理的能力,当有任何请求发过来的时候,会被nginx接收到这个请求并且被转发,基于的规则由ingress control动态配置的,所以control就是控制平面,nginx本身就是其数据面。

在谈istio的时候一样会分数据面和控制面,控制面就是istio自身,istio会有各种各样的控制平面组件,比如istiod,在里面有流量控制的控制器,它会去监听istio相关的一些对象以及k8s status这些对象,它会基于这些对象把所有的路由配置信息变更组装成envoy的配置,然后推送给envoy。

envoy就是我们在istio里面数据平面的组件,所有的请求都是发到envoy,再由envoy转发到后端的服务器的。

主流七层代理软件比较


http2被业界认可以及部署的范围越来越广了,http2相对于http1.x来说它有一些明显的优势,因为是连接复用的,所以对整个网络的链路需求会小很多。

然后又是连接复用的,那么传输的性能会高很多。k8s很多组件都是基于grpc的,也是基于http2的。

envoy在做技术选型的时候它有非常完整的支持,无论是upstream还是downstream,两个方向都基于http2,但是nginx是单方向的。

处理优雅终止:当你的一个应用,它接收到一些请求的时候,我们要让这个进程重启或者停止,在那一刻往往都有一些发送到服务器上面但是还没有处理完的请求,之所以要优雅终止就是要给到这些请求一些时间让他们处理完。然后再优雅退出,这样就不会让客户端感受到突然重启造成的一些error。

connection draining就是重新加载静态配置的时候,它老的进程不退出,新的进程谈过共享内存启动起来,然后将老的进程里面的socket copy到新的进程里面去。然后老的进程已经连接的connection它会继续的去处理,当所有的已连接的请求处理完成之后,它再将老的进程退出,然后平滑的过度到新的进程去。

这样在重启的过程当中,对于客户来说是没有感知到的,因为是平滑过渡去的,这个功能envoy支持的非常好。

上面就是envoy在能力层次上面有很强的优势。

Envoy的优势


性能:

在具备大量特性的同时,Envoy提供极高的吞吐量和低尾部延迟差异,而CPU和RAM消耗却相对较少。

envoy可以提供非常高的吞吐量,然后只贡献一点点延迟,对资源cpu 内存的开销相对比较少。

可扩展性:

Envoy在L4和L7都提供了丰富的可插拔过滤器能力,使用户可以轻松添加开源版本中没有的功能。

你可以写很多的插件。你可以通过c++ rust语言的代码去编写自己的插件,当任何数据包被envoy接受的时候,除了envoy内置的逻辑去处理这些数据包,你所编写的插件逻辑也可以对这些数据包进行一些额外的处理,这就使得envoy的能力变的非常的容易扩展,你可以在envoy原有逻辑的基础上加上自己对数据包的处理能力。

API可配置性:

·Envoy提供了一组可以通过控制平面服务实现的管理API。如果控制平面实现所有的API,则可以使用通用引导配置在整个基础架构上运行Envoy。所有进一步的配置更改通过管理服务器以无缝方式动态传送,因此Envoy从不需要重新启动。这使得Envoy成为通用数据平面,当它与一个足够复杂的控制平面相结合时,会极大的降低整体运维的复杂性。

在envoy出来之前,其他的代理软件都只支持静态文件的配置,让静态配置文件生效就需要重启进程。在以前低频率下这种模式是没有问题的,k8s是一个动态的环境,节点会失效,pod就会故障转移,ip就会变动。还有弹性使得pod实例的数量加加减减,这样就会去频繁的修改配置文件,那么基于静态重启进程生效那么你的应用进程会一直重启。

有没有更加优雅的方式?更加轻量级的方式,就是envoy提供的开创性的能力。就是API可配置,除了envoy可以读取本地的配置文件进行热重启,它还可以在基础配置文件里面配置,接受另外一个地址的管理,当要进行配置更新,配置加载的时候,那么我就去那个地址要一份配置清单。这样的话就可以在不重启进程的前提下静态的去远端的网络地址要一份配置清单,只要这个配置清单生成好了之后,推送到envoy这一侧,那么配置就会即使生效。

比如说有pod一直redy或者一直不redy,那么只需要在远端控制服务器里面把这个envoy配置进行一个动态的变更。这个动态的变更要推送到envoy这一侧,那么envoy这边就可以及时生效了。

envoy线程模式


envoy是单进程模式,有些代理软件是多进程模式,就是它会去启动很多的进程,但是对于envoy来说是单进程,首先它会起多个线程,一个进程但是多个线程,多线程里面最重要的就是主线程。主线程负责协调,它相当于管理线程,它不具体的处理数据包,这个主线程会去启动一些子线程,子线程负责这些请求监听和过滤和转发。

如果有个客户端发起了连接请求,这个请求一旦被监听器接受,然后就会和特点的工作线程,也就是子线程产生绑定关系,那么这个连接的整个生命周期会和子线程会发生紧密的绑定。

也就是说只要这个连接还在,它不会换线程的,这样的好处就是线程和线程之间不需要再协调了,就每个线程处理固定的连接。这样的话它们之间彼此独立,这样程序的设计就比较简单。不涉及到多线程的协调,不涉及到锁,线程安全等等问题。

envoy首先会去定义是静态还是动态资源,所谓的静态资源是通过配置文件落盘还是envoy读取这个配置文件来直接生效的,这是静态的。

动态就是配置部分就会定义这个部分的配置它应该去什么样的地址去拉取配置

这里会去定义配置是静态资源还是动态资源,静态资源是通过配置文件落盘,然后通过envoy读取这个文件来生效的。

动态配置就是配置部分应该去什么样的地址去拉取配置。

第一部分是listen,第二部分是cluster。监听器里面就定义socket的地址,就是监听器监听在哪个IP哪个端口上面。0.0.0.0其实也就是当前节点所有的有效IP都可以访问这个端口,因为这个节点上面有多个网卡,可能有多个IP,所谓0.0.0.0就是这些地址都能够接受10000端口的请求。

domin里面是*表示请求过来的时候,要验证发过来这个请求里面的DNS地址,所谓的*就是不去校验。如果填写了正真域名的话,只有基于这个域名,那么header里面host域名必须和这个域名匹配,我下面才去处理,否则它就认为不匹配。这里就是domin的filter不加,无论是通过IP访问还是域名访问,这里面都可以处理。route下面就是具体的路由配置了,match就是匹配规则了,匹配路由之后转到名字叫some_cluster的cluster里面去。

这个cluster是什么呢?cluster在envoy里面就是一堆IP的聚合,这样就叫做cluster。第一第一了负载均衡策略是啥,就是轮询,之后就是endpopint的ip和端口。这样完整的配置就能够理解envoy是做什么的。

上面就是首先envoy监听到0.0.0.0的10000端口,然后它就处理请求,无论访问这个端口的上面uri,都会匹配到/,就会转发到some_service的cluster,这个目标服务器就是ip为1.2.3.4端口为80。

上面就是完整的envoy的config,主要由三部分组成,listener的部分,router部分和cluster的部分。

 在envoy里面,其中最重要的一个线程就是主线程,这里面会提供一个api,叫做xds api,这个api最终会去管理端去拉取配置清单。这个配置清单被envoy拉取到之后,它有listener router cluster部分,这些都是从管理服务器拉取过来的,拉取过来的请求在每一个thread里面存储为一个本地缓存。

推送到这个本地缓存之后,这个缓存会被推送到所有的worker线程TLS里面,在每个线程里面就知道监听器,路由,cluster的配置,这些信息在每个线程里面就有了。

这样每个线程就有处理这种请求的能力了,客户端将请求发送到envoy这个主机上面,那么envoy网卡就会接收到这个请求,这个请求最终会被某个work thread去处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值