1 本文背景
笔者在学习kubernetes的kube-proxy的时候,kube-proxy具有三种proxy mode:
- userspace
- iptables
- ipvs
在Kubernetes v1.8.0-beta.0后引入的ipvs mode, 官方文档宣称其有更好的性能和更多的选项。但ipvs是什么呢,笔者作为网络方面的小白,这里并不打算恶补所有的网络知识,但ipvs不研究一下,后面也无法继续下去,所以本文是我学习ipvs的一个总结,可能类似的文章已经很多,能符合大家的期望最好,不到之处,也望各位看官一笑而过。
那什么是IPVS呢, IPVS(IP Virtual Server)是构建于Netfilter之上,作为Linux内核的一部分提供传输层负载均衡的模块。
提IPVS就不得不提LVS,IPVS模块是LVS集群的核心软件模块,它安装在LVS集群作为负载均衡的主节点上,虚拟出一个IP地址和端口对外提供服务, 把基于TCP或UDP的请求重定向到后面的真实的工作服务器。下文会对LVS, IPVS做比较详细的展开。
2 LVS是什么
LVS的英文全称是Linux Virtual Server,即Linux虚拟服务器, 该项目致力于为Linux构建一个高性能、高可用的集群服务。现在主要被用做IPVS(advanced IP load balancing software)。它是我们国家的章文嵩博士的一个开源项目。在linux内存2.6中,它已经成为内核的一部分,在此之前的内核版本则需要重新编译内核。
LVS一般用于实现四层的负载均衡集群。
3 什么是四层负载均衡
这里的“四层”指的是OSI七层模型中的第四层——传输层。
先看一下图吧:
如上图,一个数据从A节点传送到B节点,在A节点上的数据经过从第七层到第一层的层层封装,通过物理链路到达B节点后,再经过从第一层到第七层的层层解封后,最终为进程所用。
那么到底什么是四层负载均衡呢,上图只能解释OSI七层的工作模式,甚至连其中的网络层做什么都没有展现出来,再来看一下下图:
OSI模型是一个高阶模型,它指导着计算机节点间通讯所需遵循的基本原则,而在其具体实现——TCP/IP模型上,TCP/IP四层模型与之相对应,可以看到,工作在第四层的协议是TCP/UDP协议,也就是说四层负载均衡,是主要作用于TCP协议报文之上,基于IP+端口来判断需要重定向的报文,并修改报文中目标IP地址以进行重定向的负载均衡方式。
从第一张图可知,第四层的报文是看不到真正的数据内容的,所以此种负载不会考虑消息能容,例如无法根据不同的URL地址重定向到特定主机,相对的,其效率较高。
4 LVS相关术语
- DS:Director Server。指的是前端负载均衡器节点。
- RS:Real Server。后端真实的工作服务器。
- VIP:向外部直接面向用户请求,作为用户请求的目标的IP地址。
- DIP:Director Server IP,主要用于和内部主机通讯的IP地址。
- RIP:Real Server IP,后端服务器的IP地址。
- CIP:Client IP,访问客户端的IP地址。
5 LVS的三种工作模式
- VS/NAT模式
- VS/DR模式
- VS/TUN模式
6 LVS的工作原理
6.1 VS/NAT模式的工作原理
6.1.1 原理简介
NAT(Network Address Translation)即网络地址转换,其作用是通过数据报头的修改,使得位于企业内部的私有IP地址可以访问外网,以及外部用用户可以访问位于公司内部的私有IP主机。
VS/NAT模式的工作原理是多目标DNAT,通过Director修改请求报文中的目标地址和端口为LVS挑选出来的某RS的RIP和PORT实现转发。
6.1.2 工作过程详解
(a). 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP
(b). PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
(c). IPVS比对数据包请求的服务是否为集群服务,若是,修改数据包的目标IP地址为后端服务器IP,然后将数据包发至POSTROUTING链。 此时报文的源IP为CIP,目标IP为RIP
(d). POSTROUTING链通过选路,将数据包发送给Real Server
(e). Real Server比对发现目标为自己的IP,开始构建响应报文发回给Director Server。 此时报文的源IP为RIP,目标IP为CIP
(f). Director Server在响应客户端前,此时会将源IP地址修改为自己的VIP地址,然后响应给客户端。 此时报文的源IP为VIP,目标IP为CIP
6.1.3 特点
- RIP和DIP必须在同一网络,且应该使用私网地址,RS的网关必须指向DIP
- 支持端口映射
- 请求报文和响应报文都经过Director转发,较高负载下,Director易成为系统性能瓶颈
- RS可以使用任意操作系统
6.2 VS/DR模式的工作原理
6.2.1 原理简介
DR模式也叫直接路由模式,该模式中LVS依然仅承担数据的入站请求以及根据算法选出合理的真实服务器,最终由后端真实服务器负责将响应数据包发送返回给客户端。
此模式中Director为请求报文重新封装一个MAC首部进行转发,源MAC地址是DIP所在接口的MAC,目标MAC是挑选出来的的某RS的RIP接口所在的MAC,IP首部不会发生变化(CIP/VIP)
6.2.2 工作过程详解
(a). 客户请求在前端路由器发送ARP广播来获取Director的VIP所在网卡的MAC地址,获知后,在请求报文上封装MAC首部(源MAC是路由器接口的MAC,目标MAC是Director上VIP接口的MAC),保证将报文发送至Director
(b). 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP,PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
(c). IPVS比对数据包请求的服务是否为集群服务,若是,将请求报文(源地址CIP/目标地址VIP)再次封装一个MAC首部(源MAC是DIP的MAC/目标MAC是RIP的MAC),然后将数据包发至POSTROUTING链。 此时的源IP和目的IP均未修改,仅修改了源MAC地址为DIP的MAC地址,目标MAC地址为RIP的MAC地址
(d). 由于DS和RS在同一个网络中,所以是通过二层来传输。POSTROUTING链检查目标MAC地址为RIP的MAC地址,那么此时数据包将会发至Real Server
(e). RS发现请求报文的MAC地址是自己的MAC地址,就接收此报文,拆了MAC首部,发现目标地址是VIP,于是继续向lo:0转发,最终到达用户空间的进程给予响应,开始构建响应报文,处理完成之后,将响应报文通过lo:0接口传送给eth0网卡然后向外发出。 此时的源IP地址为VIP,目标IP为CIP。此时可能需要另外一个路由器,如图vs/dr.png所示,RIP的网关指向此路由,向外转发
(f). 响应报文最终送达至客户端
6.2.3 VS/DR要点
- 每个RS主机上都应有VIP,并且RIP配置在物理接口上,VIP配置在内置接口lo的别名上(lo:0),来自Director的请求报文进来时,经由RIP再到lo:0再到用户空间的进程,回去时控制响应报文先经过lo:0(此时源IP已封装成VIP)再由RIP离开,保证客户端接收到的报文源IP是VIP,目标IP是CIP
- 让RS主机禁止响应ARP广播级别和通告级别
- 响应级别(arp_ingore)设定目的:当客户端请求过来时,让Director上的VIP响应,而不是让RS上的VIP响应,保证请求报文一定走Director
- 通告级别(arp_announce)设定目的:当Director向RS转发时,经由的是RIP的接口,由于RS和Director都有VIP,会造成地址冲突,通过设定ARP通告级别可让其总是避免向非本网络通告(经由的是RIP接口,不会向非RIP接口的网络通告),因此解决了地址冲突问题
有关arp_ingore和arp_announce的具体介绍可以参见 《Linux内核参数之arp_ignore和arp_announce》
6.2.4 特点
- RS的RIP可以使用私网地址,也可以使用公网地址,如果使用公网地址,此时可以通过互联网对RIP进行直接访问
- RS跟Director必须在同一物理网络(一旦隔开,MAC会变);RS的网关必须不能指向DIP
- 不支持端口映射
- 请求报文必须由Director调度,但响应报文必须不能经由Director
- 缺陷:RS和DS必须在同一机房中
6.3 VS/TUN模式的工作原理
VS/TUN模式貌似并不是一个主要的负载均衡应用模式,笔者作为非网络专家,这里只罗列简单的调查内容,供用时参考。但是,前面两种模式VS/DR以及VS/NAT是应该掌握的基础知识。
6.3.1 原理简介
不修改请求报文的IP首部(源地址是CIP,目标地址是VIP),而是在原IP首部之外再封装一个IP首部(原地址是DIP,目标地址是挑选出来的RS的RIP)进行转发。
6.3.2 工作过程详解
(a). 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP 。
(b). PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
(c). IPVS比对数据包请求的服务是否为集群服务,若是,在请求报文的首部再次封装一层IP报文,封装源IP为为DIP,目标IP为RIP。然后发至POSTROUTING链。 此时源IP为DIP,目标IP为RIP
(d). POSTROUTING链根据最新封装的IP报文,将数据包发至RS(因为在外层封装多了一层IP首部,所以可以理解为此时通过隧道传输)。 此时源IP为DIP,目标IP为RIP
(e). RS接收到报文后发现是自己的IP地址,就将报文接收下来,拆除掉最外层的IP后,会发现里面还有一层IP首部,而且目标是自己的lo接口VIP,那么此时RS开始处理此请求,处理完成之后,通过lo接口送给eth0网卡,然后向外传递。 此时的源IP地址为VIP,目标IP为CIP
(f). 响应报文最终送达至客户端
6.3.3 特点
- RIP、VIP、DIP全是公网地址
- RS的网关不会也不可能指向DIP
- 所有的请求报文经由Director Server,但响应报文必须不能进过Director Server
- 不支持端口映射
- RS的系统必须支持隧道
7 负载均衡调度算法
7.1 静态方法
仅依据算法本身进行轮询调度
- RR:
Round Robin,轮调, 一个接一个,自上而下 - WRR:
Weighted RR,加权论调, 加权,手动让能者多劳。 - SH:
SourceIP Hash,来自同一个IP地址的请求都将调度到同一个RealServer - DH:
Destination Hash,不管IP,请求特定的东西,都定义到同一个RS上
7.2 动态方法
根据算法及RS的当前负载状态进行调度
- LC:
least connections(最小链接数)
链接最少,也就是Overhead最小就调度给谁。
假如都一样,就根据配置的RS自上而下调度。
overhead=active*256+inactiveconns - WLC:
Weighted Least Connection (加权最小连接数)
这个是LVS的默认算法。
overhead=(activeconns*256+inactiveconns)/weight - SED:
Shortest Expection Delay(最小期望延迟)
WLC算法的改进。
overhead=(activeconns+1)*256/weight - NQ:
Never Queue
SED算法的改进。第一次均匀分配,后续SED - LBLC:
Locality-Based Least-Connection,基于局部的的LC算法
正向代理缓存机制。访问缓存服务器,调高缓存的命中率。
和传统DH算法比较,考虑缓存服务器负载。可以看做是DH+LC
如果有两个缓存服务器- 只要调度到其中的一个缓存服务器,那缓存服务器内就会记录下来。下一次访问同一个资源的时候也就是这个服务器了。 (DH)
- 有一个用户从来没有访问过这两个缓存服务器,那就分配到负载较小的服务器。LC
- LBLCR:
Locality-Based Least-Connection with Replication(带复制的lblc算法)
缓存服务器中的缓存可以互相复制。
因为即使没有,也能立即从另外一个服务器内复制一份,并且均衡负载
8 LVS软件组件
- ipvsadm:用户空间的命令行工具,规则管理器,用于管理集群服务及RealServer
- ipvs:工作于内核空间netfilter的INPUT钩子上的框架
- 支持的协议: tcp udp ah_esp esp ah sctp
9 ipvsadm使用帮助
ipvsadm 用法同iptables
管理集群服务
ipvsadm -A|E -t|u|f service-address [-s scheduler] E 修改
ipvsadm -D -t|u|f service-address
service-address
tcp: -t ip:port
udp: -u ip:port
fwm: -f mark
-s scheduler
管理集群服务中的RS
ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight]
ipvsadm -d -t|u|f service-address -r server-address
server-address
ip:port
lvs-type 要注意使用 什么模型
-g gateway dr
-i ipip tun
-m masquerade,nat
清空和查看
ipvsadm -C
ipvsadm -L|l [options]
-n numberic 基于数字格式显示地址和端口
-c connetcion 显示ipvs连接
--rate 速率
--stats 统计数据
--exact 精确值
保存和重载
ipvsadm -R
ipvsadm -S [n]
置零计数器
ipvsadm -Z [-t|u|f service-address]
10 看懂ipvs规则
例:
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
UDP master.mike.com:domain rr
-> 10.244.0.6:domain Masq 1 0 0
-> 10.244.0.7:domain Masq 1 0 0
对于UDP协议,有一个集群服务master.mike.com:domain,它有两个RS,分别为10.244.0.6和10.244.0.7, LVS是以轮询的方式把请求分配给这两台RS, 两台RS的工作模式是Masq,即VS/NAT
11 为什么要在Kubernetes中使用IPVS
随着Kubernetes使用率的增长,其资源的可扩展性变得越来越重要。特别是服务的可扩展性对于开发者和那些有高负载的公司对Kubernetes的接纳程度来说是非常重要的。
Kube-proxy作为服务路由(Service routing)的构建块一直依赖于久经沙场的iptables来实现对核心服务类型(ClusterIP和NodePort)的支持。但是,iptables在对10000以上的Service的扩展性支持上显得非常的挣扎,因为iptables本身是为防火墙而设计的,并基于内部的(in-kernel)规则列表。
在Kubernetes 1.6的时候, 它已经可以支持5000个节点,导致这个数量的实际瓶颈就是kube-proxy中的iptables。举例来说,在一个5000节点的集群中全部使用NodePort类型的的service,如果我们创建2000个services,每个service对应10个pods,这将使每个节点上生成至少20000条记录,从而导致内核相当繁忙。
相对来说,使用基于IPVS的集群服务负载均衡就对这种情景游刃有余的多了。IPVS是专门为负载均衡而设计的,并使用了更高效的数据结构(hash tables),从而在底层几乎具有无限的可扩展性。
12 Kubernetes中IPVS Service网络拓扑
当创建一个ClusterIP类型的Service时, IPVS proixer做了以下三件事:
- 确保节点上存在虚拟接口,默认为kube-ipvs0
[root@master ~]# ip addr
...
8: kube-ipvs0: mtu 1500 qdisc noop state DOWN group default
link/ether 4a:4e:8d:52:b0:3b brd ff:ff:ff:ff:ff:ff
...
- 把Service IP绑定到虚拟接口上
[root@master ~]# kubectl describe svc kubernetes
Name: kubernetes
Namespace: default
Labels: component=apiserver
provider=kubernetes
Annotations:
Selector:
Type: ClusterIP
IP: 10.96.0.1
Port: https 443/TCP
TargetPort: 6443/TCP
Endpoints: 192.168.56.101:6443
Session Affinity: None
Events:
[root@master ~]# ip addr
...
8: kube-ipvs0: mtu 1500 qdisc noop state DOWN group default
link/ether 4a:4e:8d:52:b0:3b brd ff:ff:ff:ff:ff:ff
inet 10.96.0.1/32 brd 10.96.0.1 scope global kube-ipvs0
valid_lft forever preferred_lft forever
...
- 为每个Service IP单独创建IPVS virtual servers
[root@master ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
...
TCP 10.96.0.1:443 rr
-> 192.168.56.101:6443 Masq 1 4 0
...
注意这里Kubernetes Service与IPVS virtual server的比例是1:N的关系。考虑一个kubernetes Service有多个IP的场景,比如,一个External IP类型的Service就含有两个IP —— Cluster IP 和 External IP,这时候IPVS proxier就会创建2个IPVS virtual servers——一个给Cluster IP,另一个给External IP。
13 参考资料
本文大量图文摘自以下文章,另附加作者自我总结,特此声明
- LVS负载均衡(LVS简介、三种工作模式、十种调度算法)
- linux负载均衡总结性说明(四层负载/七层负载)
- 超详细!使用 LVS 实现负载均衡原理及安装配置详解
- LVS原理介绍
- LVS
- IPVS-Based In-Cluster Load Balancing Deep Dive
14 作者介绍
马楠,曾就职于日资公司NTT DATA Beijing, 国企中体彩科技发展有限公司,现Oracle系统架构和性能服务团队成员。职场中扮演过多种角色,不会运维的程序员不是好的架构师。