【运维篇】负载均衡策略

12 篇文章 1 订阅
9 篇文章 0 订阅

集中式负载均衡、进程内负载均衡

目前业界主流的负载均衡方案可分成两类:

  • 第一类:集中式负载均衡, 即在consumer和provider之间使用独立的负载均衡设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把 访问请求 通过某种策略转发至provider;

在这里插入图片描述

  • 第二类:进程内负载均衡,将负载均衡逻辑集成到consumer,consumer从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的provider。

在这里插入图片描述

Ribbon就属于后者,它只是一个类库,集成于consumer进程,consumer通过它来获取到provider的地址。

几种常见的四层负载均衡的工作模式。(凤凰架构)

现在所说的“四层负载均衡”其实是多种均衡器工作模式的统称,“四层”的意思是说这些工作模式的共同特点是维持着同一个 TCP 连接,而不是说它只工作在第四层。

事实上,这些模式主要都是工作在二层(数据链路层,改写 MAC 地址)和三层(网络层,改写 IP 地址)上,单纯只处理第四层(传输层,可以改写 TCP、UDP 等协议的内容和端口)的数据无法做到负载均衡的转发,因为 OSI 的下三层是媒体层(Media Layers),上四层是主机层(Host Layers),既然流量都已经到达目标主机上了,也就谈不上什么流量转发,最多只能做代理了。

但出于习惯和方便,现在几乎所有的资料都把它们统称为四层负载均衡,笔者也同样称呼它为四层负载均衡,如果读者在某些资料上看见“二层负载均衡”、“三层负载均衡”的表述,应该了解这是在描述它们工作的层次,与这里说的“四层负载均衡”并不是同一类意思。

四层和七层在软件层面是怎么实现的?

平常我们经常听到某某软件工作在四层,某某软件工作在七层,他们是怎么做到的?

软件实现四层或七层网络数据通常是通过操作系统的网络协议栈实现的。

在 Linux 系统中,网络协议栈由多个网络层组成(如数据链路层、网络层、传输层和应用层),每一层都使用不同的协议和 API,实现网络通信和数据传输。

在四层网络数据通信中,应用程序主要通过套接字(Socket) API 接口,使用 TCP 或 UDP 协议进行传输。

  • 应用程序向操作系统内核发送请求后,内核负责把数据包传递到传输层,然后将数据封装成 TCP 或 UDP 数据包。
  • 传输层将数据包发送到网络层,网络层对 IP 数据包进行封装,然后通过路由协议发送到目的地。网络层会根据协议规则进行负载均衡和路由选择,以确保数据包能够到达目标地址。

**在七层网络通信中,应用程序使用更具体的协议(如 HTTP、FTP、SMTP 等)通过套接字(Socket)API 接口进行网络通信。**应用程序通过特定的 API 调用,按照指定协议进行数据传输。内核接收到数据后会将数据交给相应的协议模块进行处理。每个协议模块负责解析其对应协议的数据,并根据协议规则进行处理和组装,最终将数据包通过网络层传递到目标地址。

因此,软件实现四层和七层网络数据主要依靠操作系统提供的网络协议栈和对应的 API 接口来实现。不同的应用程序使用不同的套接字 API 接口和协议,来操作不同层次的数据传输。

一、四层、七层负载均衡简介

  • 所谓四层就是基于 IP + 端口的负载均衡;
  • 七层就是基于 URL 等应用层信息的负载均衡;
  • 同理,还有基于 MAC 地址的二层负载均衡和基于 IP 地址的三层负载均衡。

所谓的四到七层负载均衡,就是在对后台的服务器进行负载均衡时,依据四层的信息或七层的信息来决定怎么样转发流量。

负载均衡器通常称为四层交换机或七层交换机。
四层交换机主要分析 IP 层及 TCP/UDP 层,实现四层流量负载均衡。
七层交换机除了支持四层负载均衡以外,还有分析应用层的信息,如 HTTP 协议 URI 或 Cookie 信息。

负载均衡分为 L4 Switch(四层交换),即在 OSI 第 4 层工作,就是 TCP 层啦。
此种 Load Balancer 不理解应用协议(如 HTTP/FTP/MySQL 等等)。例子:LVS,F5。

另一种叫做 L7 Switch(七层交换),OSI 的最高层,应用层。
此时,该 Load Balancer 能理解应用协议。例子: HAProxy,MySQL Proxy。

1、四层负载均衡

比如四层的负载均衡,就是通过发布三层的 IP 地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡,
对需要处理的流量进行 NAT 处理,转发至后台服务器,并记录下这个 TCP 或者 UDP 的流量是由哪台服务器处理的,
后续这个连接的所有流量都同样转发到同一台服务器处理。

  • 负载均衡器用 ip+port 接收请求,再直接转发到后端对应服务上;

  • 工作在传输层

  • 客户端和服务器之间建立一次TCP连接,而负载均衡设备只是起到一个类似路由器的转发动作。

2、七层负载均衡

  • 负载均衡器根据 虚拟的 url 或主机名 来接收请求,经过处理后再转向相应的后端服务上;

  • 工作在应用层 ;

  • 七层负载均衡需要建立两次 TCP 连接,
    client 到 LB,LB根据消息中的内容( 比如 URL 或者 cookie 中的信息 )来做出负载均衡的决定;
    然后,建立 LB 到 server 的连接。

  • 负载均衡设备需要先代理最终的服务器和客户端建立 TCP 连接后,才可能接收到客户端发送的真正应用层内容的报文,
    然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。

  • 具有七层负载均衡功能的设备通常也被称为反向代理服务器。

七层的负载均衡,就是在四层的基础上(没有四层是绝对不可能有七层的),再考虑应用层的特征, 比如同一个 Web 服务器的负载均衡,除了根据 VIP 加 80 端口辨别是否需要处理的流量, 还可根据七层的 URL、浏览器类别、语言来决定是否要进行负载均衡。

在这里插入图片描述

3.四到七层负载均衡区别

所谓的四到七层负载均衡,就是在对后台的服务器进行负载均衡时,依据四层的信息或七层的信息来决定怎么样转发流量。
比如四层的负载均衡,就是通过发布三层的IP地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡,对需要处理的流量进行NAT处理,转发至后台服务器,并记录下这个TCP或者UDP的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理。

七层的负载均衡,就是在四层的基础上(没有四层是绝对不可能有七层的),再考虑应用层的特征,比如同一个Web服务器的负载均衡,除了根据VIP加80端口辨别是否需要处理的流量,还可根据七层的URL、浏览器类别、语言来决定是否要进行负载均衡。

举个例子,如果你的Web服务器分成两组,一组是中文语言的,一组是英文语言的,那么七层负载均衡就可以当用户来访问你的域名时,自动辨别用户语言,然后选择对应的语言服务器组进行负载均衡处理。

- 负载均衡器通常称为四层交换机或七层交换机。四层交换机主要分析IP层及TCP/UDP层,实现四层流量负载均衡。七层交换机除了支持四层负载均衡以外,还有分析应用层的信息,如HTTP协议URI或Cookie信息。

1、七层负载均衡:基本都是基于http协议,适用于web服务器的负载均衡
2、四层负载均衡:基于TCP协议,可以做任何基于tcp/ip协议的负载均衡(haproxy, LVS)
3、二者主要区别在于利用的报文所在的层面是不同的,各有各的好处。
4、七层负载均衡的好处,是使得整个网络更“智能化”。例如访问一个网站的用户流量,可以通过七层的方式,将对图片类的请求转发到特定的图片服务器,并可以利用缓存技术;将对文字类的请求转发到特定的文字服务器,并可以利用压缩技术。
从技术原理上,七层负载可以对客户端的请求和服务器的响应进行任何意义上的修改,极大的提升了应用系统在网络层的灵活性。例如nginx或apache上部署的功能可以迁移到负载均衡器上,例如客户请求中的Header重写,服务器响应中的关键字过滤或内容插入等功能。
5、四层负载均衡的优点是较为灵活,可以作为多种软件的负载均衡器。

二、四层负载均衡实现:kube-proxy

K8s 的内部服务发现是基于 DNS 解析实现的

kube-dns可以解决Service的发现问题,k8s将Service的名称当做域名注册到kube-dns中,通过Service的名称就可以访问其提供的服务

默认解析到一个稳定虚拟 IP (Service),该虚拟 IP 再通过 kube_proxy 将流量均衡到后端 Pods 上。( Pod 的 IP 可能会随着 Pod 的重建而变动,但 Service 的 IP 是稳定的 )

kube-proxy 是 k8s 原生组件,主要通过 NodePort 方式暴露服务。

NodePort 方式是什么呢?
k8s 能保证在任意 Pod 挂掉时自动启动一个新的,甚至是动态扩容,这就意味着 Pod IP 是会动态变化的;
因此这个 Pod IP 你不适合暴露出去,
而 Service 可以以标签的形式选定一组带有指定标签的 Pod,并监控和自动负载这些 Pod IP;
因此对外只暴露 Service IP 就行了;
这就是 NodePort 模式,即在每个节点 node 上起一个端口,然后转发到内部 Pod IP 上。

上面提到的这个稳定虚拟 IP 就是一个 ClusterIP 类型的 Service,
这个 Service 会根据 kube-proxy 的代理模式的不同,有不同的性能表现:

三、七层负载均衡实现: Ingress

  • Ingress 是 k8s 的一种资源对象,
    该对象允许外部访问 k8s 服务, 通过创建规则集合来配置访问权限,这些规则定义了哪些入站连接可以访问哪些服务;
  • Ingress 仅支持 HTTP 和 HTTPS 协议;
  • ingress 可配置用于提供外部可访问的服务 url、负载均衡流量、SSL终端和提供虚拟主机名配置。
ingress-controller 实现过程

ingress-controller 是实现反向代理和负载均衡的程序, 通过监听 Ingress 这个 api 对象里的配置规则并转化成 Nginx 的配置 , 然后对外部提供服务

Ingress 对于上面提到的 “如何修改 Nginx 配置” 这个问题的解决方案是:
把 “修改 Nginx 配置各种域名对应哪个 Service ” 这些动作抽象为一个 Ingress 对象,
然后直接改 yml 创建/更新就行了,不用再修改 nginx 。

而 ingress-controller 通过与 k8s API 交互,动态感知集群中 Ingress 规则的变化并读取它,
然后按照模板生成一段 Nginx 配置,再写到 Nginx Pod 里,最后再 reload 一下生效。

大概的访问路径如下:

用户访问 --> LB --> ingress-nginx-service --> ingressController-ingress-nginx-pod --> ingress字段中调用的后端pod

ingress 总结:

注意后端 pod 的 service 只提供 pod 归类,
归类后 ingress 会将此 service 中的后端 pod 信息提取出来,
然后动态注入到 ingress-nginx-pod 中的 ingress 字段中,
如此,后端 pod 就能被调用了

微服务网关 vs K8s Ingress

微服务+网关

网关的引入可以使前端与后端进行解耦,使得两边不直接依赖,可以相互独立变化,网关的作用主要是七层反向代理,当前端进行访问时,Gateway会根据请求的内容进行路由转发至后端的微服务,它属于后端微服务的一个统一入口,还可支持安全认证,日志监控等功能

在这里插入图片描述

公有云K8s通过LB暴露服务

在阿里云K8S环境中,为了将Petclinic微服务暴露在公网,我们在发布时Service时需要指定它的Type为LoadBalancer,还需额外购买阿里云提供的LB进行配置暴露服务,使用户能够访问

在这里插入图片描述

K8s Ingress

为了解决以上问题,K8S引入了Ingress组件,它和网关类似,本身是七层反向代理,引入Ingress之后,运维人员只需购买一个LB就可以将多个服务暴露出去使用户访问,实现的原理就是依靠Ingress来实现转发,新增服务要暴露的话,只需在Ingress上添加对应的路由规则即可;Ingress作为K8S集群流量接入的入口,所以它也可实现安全认证,流量治理等功能,Ingress它是K8S中的一种服务(Service)

在这里插入图片描述

(1)微服务网关 = K8s Ingress,本质:都是七层反向代理,微服务集中出入口,可以降低暴露多个微服务的复杂性和成本
(2)核心功能:反向路由
(3)高级功能:安全认证,日志监控,流量治理等

Nginx负载均衡策略

  • Nginx工作在OSI的第七层,可以这对http应用做一些分流策略;
  • Nginx反向代理服务的核心主要是转发Http请求,扮演了浏览器后端和后端服务器中转的角色;
  • Nginx官方测试支持5万并发连接,在实际生产环境中可以到2-3万并发数连接,1万个非活跃http keep-alive连接占用约2.5M内存。3万并发连接下,10个Nginx进程,消耗内存约150M;
  • 负载均衡的目的是为了解决单个节点压力过大,导致Web服务响应慢的问题;

内置负载策略

策略
轮循(round-robin)默认策略

根据请求次数,将每个请求均匀分配到每台服务器,如果后端服务器宕机,自动剔除。
权重(Weight)

把请求更多的分配到高配置的后端服务器上,默认每个服务器的权重都是1。
ip_hash

同一客户端的Web请求被分发到同一个后端服务器进行处理,使用该策略可以有效的避免用户Session失效的问题。该策略可以连续产生1045个互异的value,经过20次hash仍然找不到可用的机器时,算法会退化成轮循。
最少连接(last_conn)

Web请求会被转发到连接数最少的服务器上。

Nginx为什么支持那么高的并发量?

多进程模型

多进程:一个 Master 进程、多个 Worker 进程。

Master 进程:管理 Worker 进程。

  • 对外接口:接收外部的操作(信号);
  • 对内转发:根据外部操作的不同,通过信号管理 Worker;
  • 监控:监控 Worker 进程的运行状态,Worker 进程异常终止后,自动重启 Worker 进程。

Worker 进程:所有 Worker 进程都是平等的。

  • 实际处理:网络请求,由 Worker 进程处理。
  • Worker 进程数量:在 nginx.conf 中配置,一般设置为核心数,充分利用 CPU 资源,同时,避免进程数量过多,避免进程竞争 CPU 资源,增加上下文切换的损耗

在这里插入图片描述

  • Nginx 采用多进程+异步非阻塞方式(IO 多路复用 Epoll)。

    请求的完整过程:建立连接→读取请求→解析请求→处理请求→响应请求。
    请求的完整过程对应到底层就是:读写 Socket 事件。

配置

DNS域名解析

在这里插入图片描述

通过Annotation配置负载均衡

https://help.aliyun.com/document_detail/86531.html?spm=a2c4g.11174283.6.743.6a7d2ceeFdQ000

设置阿里云 负载均衡 SLB/证书管理
在这里插入图片描述

service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-cert-id
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-protocol-port

如果是https服务,则

在这里插入图片描述

如果是rpc服务,则

在这里插入图片描述

如果是http服务,则
在这里插入图片描述

创建HTTPS类型的负载均衡

在这里插入图片描述

Kubernetes的三种外部访问方式:NodePort、LoadBalancer 和 Ingress

ClusterIP

ClusterIP 服务是 Kubernetes 的默认服务。它给你一个集群内的服务,集群内的其它应用都可以访问该服务。集群外部无法访问它。

如果 从Internet 没法访问 ClusterIP 服务,那么我们为什么要讨论它呢?那是因为我们可以通过 Kubernetes 的 proxy 模式来访问该服务!

何时使用这种方式?
有一些场景下,你得使用 Kubernetes 的 proxy 模式来访问你的服务:
由于某些原因,你需要调试你的服务,或者需要直接通过笔记本电脑去访问它们。
容许内部通信,展示内部仪表盘等。

这种方式要求我们运行 kubectl 作为一个未认证的用户,因此我们不能用这种方式把服务暴露到 internet 或者在生产环境使用。

NodePort

NodePort 服务是引导外部流量到你的服务的最原始方式。NodePort,正如这个名字所示,在所有节点(虚拟机)上开放一个特定端口,任何发送到该端口的流量都被转发到对应服务。

在这里插入图片描述

何时使用这种方式?
这种方法有许多缺点:
每个端口只能是一种服务
端口范围只能是 30000-32767
如果节点/VM 的 IP 地址发生变化,你需要能处理这种情况。

基于以上原因,我不建议在生产环境上用这种方式暴露服务。如果你运行的服务不要求一直可用,或者对成本比较敏感,你可以使用这种方法。这样的应用的最佳例子是 demo 应用,或者某些临时应用

LoadBalancer

LoadBalancer 服务是暴露服务到 internet 的标准方式。在 GKE 上,这种方式会启动一个 Network Load Balancer,它将给你一个单独的 IP 地址,转发所有流量到你的服务。

何时使用这种方式?
如果你想要直接暴露服务,这就是默认方式。所有通往你指定的端口的流量都会被转发到对应的服务。它没有过滤条件,没有路由等。这意味着你几乎可以发送任何种类的流量到该服务,像 HTTP,TCP,UDP,Websocket,gRPC 或其它任意种类。

这个方式的最大缺点是每一个用 LoadBalancer 暴露的服务都会有它自己的 IP 地址,每个用到的 LoadBalancer 都需要付费,这将是非常昂贵的。

在这里插入图片描述

Ingress 第七层流量入口

有别于以上所有例子,Ingress 事实上不是一种服务类型。相反,它处于多个服务的前端,扮演着“智能路由”或者集群入口的角色。

通过一个公开的ip地址来公开多个服务,第7层网络流量入口是在网络堆栈的HTTP / HTTPS协议范围内运行,并建立在service之上。

你可以用 Ingress 来做许多不同的事情,各种不同类型的 Ingress 控制器也有不同的能力。

GKE 上的默认 ingress 控制器是启动一个 HTTP(S) Load Balancer。它允许你基于路径或者子域名来路由流量到后端服务。例如,你可以将任何发往域名 foo.yourdomain.com 的流量转到 foo 服务,将路径 yourdomain.com/bar/path 的流量转到 bar 服务。

在这里插入图片描述

何时使用这种方式?
Ingress 可能是暴露服务的最强大方式,但同时也是最复杂的。Ingress 控制器有各种类型,包括 Google Cloud Load Balancer, Nginx,Contour,Istio,等等。它还有各种插件,比如 cert-manager,它可以为你的服务自动提供 SSL 证书。

如果你想要使用同一个 IP 暴露多个服务,这些服务都是使用相同的七层协议(典型如 HTTP),那么Ingress 就是最有用的。如果你使用本地的 GCP 集成,你只需要为一个负载均衡器付费,且由于 Ingress是“智能”的,你还可以获取各种开箱即用的特性(比如 SSL,认证,路由,等等)

请求一个域名请求集群的流程( ingress)

工作:

  • 客户端现针对www.1234.com执行dns解析,
  • DNS服务器返回ingress控制器的ip,
  • 客户端拿到ip后,向ingress控制器发送http的get请求,将域名加在host头部发送。
  • 控制器接收到请求后,从host头部就知道了该访问哪一个服务,通过与该service关联的- endpoint对象查询podIP地址,将请求进行转发

第7层负载均衡器的一个好处是它们具有HTTP感知能力,因此它们了解URL和路径。 这允许您按URL路径细分服务流量。 它们通常还在HTTP请求的X-Forwarded-For标头中提供原始客户端的IP地址。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值