本文由 简悦 SimpRead 转码, 原文地址 www.jianshu.com
博客搬家至 Mun: https://kiddie92.github.io
简书同步更新
本文首先回顾了一下负载均衡和反向代理,随后介绍 ingress,这部分的内容主要参考了 YouTube 上印度老哥的频道:KodeKloud 的视频,直接看视频效果更佳。
7 层负载均衡
负载均衡(LB)在微服务架构演进中具有非常重要的意义,可以说的内容有很多,这里仅仅讨论四层和七层负载均衡的一些要点和区别,以便于对ingress
的理解。所谓四层和七层负载均衡是按照网络层次 OSI 来划分的负载均衡类型(也可以按照其他的规则来分类,比如:应用的地理结构),简单来说:四层负载均衡
表示负载均衡器用 ip+port 接收请求,再直接转发到后端对应的服务上,工作在传输层 (transport layer);七层负载均衡
表示负载均衡器根据虚拟的 url 或主机名来接收请求,经过处理后再转向相应的后端服务上,工作在应用层 (application layer)。
下图表示了 4 层和 7 层负载均衡在建立 TCP 连接上的区别,从图中可以看出,四层负载均衡需要建立的 TCP 连接其实之有一个,它只做一次转发,client 直接和 server 连接;而 7 层负载均衡则需要建立两次 TCP 连接,client 到 LB,LB 根据消息中的内容 (比如 URL 或者 cookie 中的信息) 来做出负载均衡的决定,接着建立 LB 到 server 的连接。
layer4VSlayer7_LB.png
7 层负载均衡有什么好处呢?
- 因为存在解包 / 封包的过程,比 4 层 LB 更加 CPU‑intensive,但是却极少降低性能;
- 可以编写更加智能的负载均衡策略,比如根据 URL、cookie 中的信息等,甚至对接收到的内容做一些优化和修改,比如加密、压缩;
- 使用 buffer 的方式来缓解服务器连接慢的问题,从而提高性能
- 具有 7 层负载均衡功能的设备通常也被称为反向代理服务器(reverse‑proxy server)
反向代理
举个例子:
正向代理
:在使用 VPS 访问的时候,通常会使用一个本地的代理服务器,浏览器的网络包会先经过本地的代理服务器,代理服务器会通过远在异国它乡的电脑来访问并返回消息;这就好比去附近的咖啡店要先问一下手机咖啡店在哪里一样,手机就是一个正向代理服务器。
反向代理
:当访问的请求到达时,那边也设置了一个代理服务器,它通过查看请求的 URL,发现是想查找视频内容,于时把消息转给了视频搜索服务器(过程是我乱说的),这就好比你去朋友家做客,开门的却是个管家,问你找谁?这时候管家就是一个反向代理了。
关于反向代理的好处这里就不多介绍,感兴趣可以看这里
其他 OSI 层也可以做反向代理
ingress
k8s 对外暴露服务(service)主要有两种方式:NotePort
, LoadBalance
, 此外externalIPs
也可以使各类 service 对外提供服务,但是当集群服务很多的时候,NodePort 方式最大的缺点是会占用很多集群机器的端口;LB 方式最大的缺点则是每个 service 一个 LB 又有点浪费和麻烦,并且需要 k8s 之外的支持; 而 ingress 则只需要一个 NodePort 或者一个 LB 就可以满足所有service
对外服务的需求。工作机制大致可以用下图表示:
ingress.png
实际上,ingress
相当于一个 7 层的负载均衡器,是 k8s 对反向代理的一个抽象。大概的工作原理也确实类似于 Nginx,可以理解成在 Ingress 里建立一个个映射规则 , ingress Controller
通过监听 Ingress
这个 api 对象里的配置规则并转化成 Nginx 的配置(kubernetes 声明式 API 和控制循环) , 然后对外部提供服务。ingress 包括:ingress controller 和 ingress resources
ingress controller
:核心是一个 deployment,实现方式有很多,比如 nginx, Contour, Haproxy, trafik, Istio,需要编写的 yaml 有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中 service 的类型可以是 NodePort 或者 LoadBalancer。
ingress resources
:这个就是一个类型为Ingress
的 k8s api 对象了,这部分则是面向开发人员。
假设已经有两个服务部署在了 k8s 集群内部:
|
|
配置 Ingress resources,即可实现多个 service 对外暴露服务: 方式一:
|
|
接着在 hosts 文件中添加一条解析规则:${ingress_IP} foo.bar.com
,这时通过在浏览器中访问:foo.bar.com/coffee
或者foo.bar.com/tea
即可访问对应的后端 service 了。
使用 curl 时的操作:
curl -H "Host: foo.bar.com" http://${ingress_IP}/coffee
方式二:
|
|
这时在 hosts 文件添加两条解析规则就可以在浏览器中访问了。此外,还可以配置 TLS 证书实现 HTTPS 访问,这里不再详述。
前面提到 ingress controller 的实现有很多方案,除了常用的 nginx 这类负载均衡器,一些网络插件也会集成相关功能。比较有代表性的如
NSX-T
,vmware 的一款重量级虚拟化网络产品。NSX-T
的ncp
组件在部署的时候只要在 yaml 文件中设置default_ingress_class_nsx = True
就 OK 了,并可以选择指定一个external_ip_pools
。
Reference
- YouTube 视频
- 阿里云
- https://www.cnblogs.com/danbing/p/7459224.html
- https://www.nginx.com/resources/glossary/layer-7-load-balancing/
- https://www.nginx.com/resources/glossary/reverse-proxy-vs-load-balancer/
- https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0