Kubernetes Ingress Controller 技术细节探讨

对于许多企业来说,将生产环境转移到Kubernetes集群上,会让应用程序的流量管理变得复杂且具有挑战性。

而Ingress Controller允许通过Yaml编排脚本提供高可用的七层负载均衡、Waf防火墙或者API Gateway,它是Kubernetes集群对外服务的核心组件。

Ingress-nginx是Kubernetes Ingress Controller开源版本中的一种,它使用了NGINX作为反向代理和负载均衡器,生态完善、功能丰富,性能与稳定性也是极优秀的。

最近五年随着devops的落地,很多运维岗位都消失了,可能只需要在抽象的web界面上配置一下,或者k8s里面yaml去管理。

现在很多的开源产品就是拿openresty或者nginx做了一些插件的开发,通过WAF或者service mesh去包装给到用户。

Ingress是七层负载均衡,nginx最擅长的,这里主要讲nginx的两种实现。第一种是k8s官方的,第二种是nginx官方的。注意这两个ingress control是基于go实现的。

Ingress control的工作原理


工作场景:Ingress control就是在处理南北向的流量,尤其是整个集群出入口的流量

早期时候是基于物理机,之后是基于虚拟机,比如在公有云上面买了ecs,后面有了docker,K8s相对于docker来说最强大之处是在编排上面,托管上面。

外部的traffic流量下来以后,来到ingress这里可以理解为nginx,nginx是基于虚拟主机域名,这个东西就是server_name,根据server_name做第一级的匹配,匹配到之后再匹配url,也就是location。Nginx里面最核心的两级匹配一个是server一个是location。

匹配完以后就丢给了service

负载均衡服务怎么实现的呢?其实挺简单的,当有一个VIP的时候其实是通过iptables完成的,Linux上面有一个配置net.ipv4.ip_forward当其值为1的时候就具备了转发报文的能力,转发报文的时候有一个iptables的规则,这个规则就可以做了。

如果你去访问虚拟IP,50%的流量给到pod1,50%的流量给到pod2,这个就是通过iptables来完成的。

一个service可以绑定多个endpoint。

Ingress将nginx的很多东西给抽象出来了,server、location、upstream。

Ingress抽象出来了域名,host的值就和server_name的值一样,path就和我们的location一样。我们知道nginx location进行匹配的时候可以基于正则匹配,忽略大小写匹配。但是k8s抽象出来的是非常有限的,因为k8s没有认为其是其唯一的选择,因为还可以放lvs和其他的负载均衡,所以只将最小能力抽象出来了。

在nginx里面会有upstream(server pod1 ip、server pod2 ip)其实,一个service就对应了一个upstream

数据会丢失?


nginx要实现高可用,要很多维度保障,随着机器宕机,nginx的配置也会随之丢掉。

还有nginx这台机器宕机了,那么nginx是否也能够被拉起,能不能启动新的机器。 

nginx.conf和共享内存、数据要放在哪里呢?这个要放在数据库当中才不会丢失。

其实k8s当中所有的数据都是放在etcd当中,这是key value数据库。apiserver会通过etcd本身的grpc server写入数据库当中。

ETCD数据库


 paxos两段式提交,就是分布式数据库可以主备那么就有单点,要搞一个没有主备的概念,或者主节点挂掉之后无所谓,小于2/n节点即可,可以提供读写服务。

ingress就是之前的yaml文件,然后还有endpoint和service,一个是service的yaml,一个是定义的pod。这些pod是通过选择器进行关联的。

一个HTTP请求进来,先通过ingress的host来做域名判断,再通过location即url做二次匹配。然后就进入了upstream,也及时proxy pass,然后它开始选择upstream了,upstream里面根据service endpoint唯一确定了给哪一批server。

secret在配置域名的时候,那么外部流量是走tls的,实现http->https来保证其安全。

因为公钥私钥是通过secret资源,加密之后存放到etcd里面。即使你拿走了etcd数据库,那么你还是解析不了。

 另外一部分高可用体现在k8s集群管理上面。

在nginx上面本身做插件和apiserver去做通信,这个是不行的,开发效率太低了。

不管你是使用c语言与apiserver去做通信,复杂度都是非常恐怖的一件事情,因为需要支持grpc和tls。基于c和lua写都不行。

不管是k8s官方还是nginx官方还是kong都是这么干的,搞出一个新的进程,这个进程是上面图片当中的m,由这个进程和nginx在同一个pod里面,也就是一个pod里面是多进程的。

这个外部的进程m通过apiserver去管理nginx。

怎么管理呢?

  • 要去修改nginx.conf然后reload一下
  • 还可以去修改共享内存
  • 普罗米修斯监控也需要配合拉取信息
  • 健康检查也需要放到这里面去做

这个进程的实现都是k8s和nginx官方都是使用了go语言。 

bash-5.0$ ps -ef
PID   USER     TIME  COMMAND
    1 www-data  0:00 /usr/bin/dumb-init -- /nginx-ingress-controller --configmap=ingress-nginx/nginx-configuration --tcp-services-configmap=ingress-nginx/tcp-services --udp-servi
    7 www-data 47:55 /nginx-ingress-controller --configmap=ingress-nginx/nginx-configuration --tcp-services-configmap=ingress-nginx/tcp-services --udp-services-configmap=ingress-
   26 www-data  0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /etc/nginx/nginx.conf

 ​

etcd当中存储了ingress,service,endpoint,secret,configmap。这五类数据库一旦发生了任何的变化,那么就需要推送給store协程,机器挂掉了endpoint就变化了,等等。

更改了密钥,也是一样。

发生变化了那么store协程就知道了,store将apiserver传递给他的五类数据的变更写入到channel当中,nginxcontroller会从这个协程当中取出数据来,取出来放到同步队列当中,还有一个协程会将其中的数据读取出来处理。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值