Nginx官方和K8s官方都维护了一个Ingress Controller,两者实现不太一样。(K8s社区基于Openresty,实现方式和Nginx官方差别很大)
Nginx集群是怎样从是K8s的etcd中拿到变更的数据,又是怎样修改Nginx的共享内存? 因为Nginx是多进程模型。
如何自动修改conf文件
Ingress Controller的工作原理
Ingress是在处理南北向带流量,尤其是集群的出口/入口流量
基于servername(其实就是域名)做第一级的匹配,之后再匹配url,即location。这就是Nginx中最核心的两级匹配
Nginx每一个请求有11个处理阶段,其中一个叫find config,这个阶段就是就是在匹配location
至于匹配域名,在接收到host头部时就开始做了。
性能很高,匹配域名是用的hash表。匹配url用的是Trie树
Linux上有个配置叫net.ipv4.ipforward,设置为1时,就有转发报文的能力,有个iptables规则。
如访问这个虚拟ip时,10%的流量给pod1,90%给pod2
Ingress Controller主要在监控5类数据,其中Endpoint是第一类,Service是第二类。
阿里云SLB的控制台页面,也是一种抽象
Nginx的location本身有很多种配置,如正则表达式匹配,前缀匹配,完全匹配等
但是k8s Ingress在抽象时实现的很有限,因为K8s认为Nginx不是其唯一选择,还可以是lvs等等。只是把一个这些同类产品的最大公约数抽象了出来
高可用(HA)
- 数据会不会丢?K8s中的所有数据都会放到etcd中。会通过apiserver提供的grpc,写入到etcd中(etcd提供的现在也是grpc接口)
etcd中存了5类数据
Ingress,Endpoint&Service其实就是两类yaml。当一个外部请求过来,先通过Ingress中的host做域名判断,再通过url做二次匹配。
然后就进入upstream。根据Endpoint&Service 唯一确定该路由给哪个server。
另外在K8s Nginx Ingress还需要Secret和ConfigMap。在身份认证时用到了PKI公钥体系,需要把公私钥放在Nginx上。K8s的secret就是加密后再存etcd; ConfigMap是存放配置的
Ingress Controller必须要监控这5类文件
只要宕掉的机器小于一半,那这些文件就不会丢。。
Networking CNI插件 网桥。是kubelet来管的
- Nginx Ingress Controller如何高可用地管理k8s中的pod
Nginx Ingress Controller不会直接通过apiserver去和k8s通信。。不现实
k8s ingress官方,Nginx Ingress Controller,Kong的 Ingress Controller,这几家都用了类似的方案,搞出一个新的进程,(几家名字都不一样),这个进程和nginx共同在一个pod里(其实违反了容器的设计原则,一般一个container里就一个进程,这样好管理)
Ingress-nginx-controller 这个进程,k8s官方和nginx官方都使用了go。 不需要很高的性能,并发能力好
(Go很适合团队协作)
nginx的reload其实不是“nice”的,有长尾效应,可能99%的请求正常,但1%的会有影响。
这也就是k8s官方用openresty的原因
work_process这些都放到ConfigMap里
go写的这个程序,通过informer模式,监听五类资源的变化。一旦有改动,apiserver立马推给store协程
k8s官方的:
有通过lua来管理
三个基于nginx开发的ingress controller的对比
第一个是nginx官方开发的,oss译为opensource
第二个是基于nginx plus(其商业化版本)实现的,不是开源的
第三个是k8s官方的
所谓的静态,即nginx.conf基本不变。
动态则是nginx.conf发生改变
官方的是去改nginx.conf
k8s推出的是基于lua去改共享内存
每秒发送3w个请求,99%的请求,时延小于50ms。
到99.9%时,k8s官方提供的ingress时延就变高了,接近100ms (因为lua,有个balance by lua,即从C语言跳到lua)
nginx官方的因为是纯C语言的,不支持动态修改(改了就要reload)
什么是 balance by lua
“balance by lua” 是指使用 Lua 脚本来实现负载均衡的一种方法。
负载均衡是在分布式系统中常用的技术,用于将流量均匀地分发到多个后端服务实例上,以提高系统的性能和可靠性。在某些情况下,简单的负载均衡策略(如轮询)可能无法满足特定的需求,因此需要一种更灵活的方法来实现。
Lua 是一种轻量级的脚本语言,可以嵌入到其他应用程序中使用。在负载均衡中,可以使用 Lua 脚本来编写自定义的负载均衡算法和逻辑。这种方法称为 “balance by lua”。
使用 Lua 脚本可以获取请求的相关信息(如请求头、请求参数等),并基于这些信息进行动态的负载均衡决策。Lua 脚本可以让负载均衡器更加灵活,能够根据实际业务需求进行定制化的流量分发策略。
负载均衡器通常会将请求传递给预配置的 Lua 脚本进行处理。Lua 脚本可以根据自定义逻辑选择合适的后端服务实例,并将请求转发给选定的实例。这种方式允许负载均衡器根据实时的请求特征、后端服务的状态或其他因素来动态地选择目标实例。
总之,”balance by lua” 是一种使用 Lua 脚本来实现自定义负载均衡逻辑的方法。它提供了更大的灵活性和定制化能力,以满足特定场景下的负载均衡需求。
动态测试: 每隔10-12s对pod做一次调整,一会儿调成5个,一会儿调成7个。
即会不停地启停nginx
k8s官方的,走的是balance by lua,根本不执行reload,所以不会有啥变化
而nginx官方提供的,因为需要重启,就非常差了,最高能时延超过1分钟…(只要不重启,性能就相当好)
https://www.tencentcloud.com/zh/document/product/457/40957
Ingress Controller与Master的通信机制
原文链接: https://dashen.tech/2020/09/13/K8s-Ingress-Controller技术细节探讨/
版权声明: 转载请注明出处.