本文分享自华为云社区《【理解云容器网络】2-基础篇-ipvs介绍》,作者: 可以交个朋友。
IPVS简介
ipvs是工作在Linux内核态的4层负载均衡;和用户态的负载均衡软件(如nginx、haproxy)功能类似:作为客户端访问的统一入口并将访问请求根据调度算法转给后端真实的服务器。相比于用户态负载均衡,ipvs为Linux内核子模块性能更强,但ipvs仅工作在4层无法处理7层数据(比如SSL证书、修改HTTP请求头)。
IPVS调度算法
IPVS是如何决策应该把请求调度到哪个后端RS(Real Server)上的呢?这是由负载均衡调度算法决定的。IPVS常用的调度算法有:
-
轮询(Round Robin):IPVS认为集群内每台RS都是相同的,会轮流进行调度分发。从数据统计上看,RR模式是调度最均衡的。
-
加权轮询(Weighted Round Robin):IPVS会根据RS上配置的权重,将消息按权重比分发到不同的RS上。可以给性能更好的RS节点配置更高的权重,提升集群整体的性能。
-
最小连接数(Least Connections):IPVS会根据集群内每台RS的连接数统计情况,将消息调度到连接数最少的RS节点上。在长连接业务场景下,LC算法对于系统整体负载均衡的情况较好;但是在短连接业务场景下,由于连接会迅速释放,可能会导致消息每次都调度到同一个RS节点,造成严重的负载不均衡。
-
加权最小连接数(Weighted Least Connections):最小连接数算法的加权版~
-
地址哈希(Address Hash):LB上会保存一张哈希表,通过哈希映射将客户端和RS节点关联起来。
IPVS转发模式
根据调度算法选择一个合适的后端RS节点,IPVS怎么将数据转发给后端RS呢?
IPVS支持三种转发模式:
- DR模式(Direct Routing)
- NAT模式(Network Address Translation)
- IP隧道(IP tunneling)
三种转发模式性能从高到低:DR > NAT > IP隧道
DR模式
DR模式下,客户端的请求包到达负载均衡器的虚拟服务IP端口后,负载均衡器不会改写请求包的IP和端口,但是会改写请求包的MAC地址为后端RS的MAC地址,然后将数据包转发;真实服务器处理请求后,响应包直接回给客户端,不再经过负载均衡器。所以DR模式的转发效率是最高的。
DR模式的特点:
- 数据包在LB转发过程中,源/目的IP端口都不会变化。LB只是将数据包的MAC地址改写为RS的MAC地址,然后转发给相应的RS。所以LB必须和后端RS节点在同一个子网
- 每台RS上都必须在环回网卡(lo)上绑定VIP。因为LB转发时并不会改写数据包的目的IP,所以RS收到的数据包的目的IP仍是VIP,为了保证RS能够正确处理该数据包,而不是丢弃,必须在RS的环回网卡上绑定VIP。这样RS会认为这个虚拟服务IP是自己的IP,自己是能够处理这个数据包的,否则RS会直接丢弃该数据包。
- RS上的业务进程必须监听在环回网卡的VIP上,且端口必须和LB上的虚拟服务端口一致。因为LB不会改写数据包的目的端口,所以RS服务的监听端口必须和LB上虚拟服务端口一致,否则RS会直接拒绝该数据包。
- RS处理完请求后,响应直接回给客户端,不再经过LB。因为RS收到的请求数据包的源IP是客户端的IP,所以理所当然RS的响应会直接回给客户端,而不会再经过LB。这时候要求RS和客户端之间的网络是可达的。
NAT模式
NAT模式下请求包和响应包都需要经过LB处理。当客户端的请求到达LB后,LB会对请求包做目的地址转换(DNAT),将请求包的目的IP改写为RS的IP。RS处理请求后将响应返回给LB,当LB收到RS的响应后,LB会对响应包做源地址转换(SNAT),将响应包的源IP改写为LB的VIP。
NAT模式的特点:
-
LB会修改数据包的地址。对于请求包,会进行DNAT;对于响应包,会进行SNAT。
-
LB会透传客户端IP到RS(DR模式也会透传)。虽然LB在转发过程中做了NAT转换,但是因为只是做了部分地址转发,所以RS收到的请求包里是能看到客户端IP的。
-
需要将RS的默认网关地址配置为LB的浮动IP地址。因为RS收到的请求包源IP是客户端的IP,为了保证响应包在返回时能走到LB上面,所以需要将RS的默认网关地址配置为LB的虚拟服务IP地址。当然,如果客户端的IP是固定的,也可以在RS上添加明细路由指向LB的虚拟服务IP,不用改默认网关。
-
LB和RS须位于同一个子网,并且客户端不能和LB/RS位于同一子网。因为需要将RS的默认网关配置为LB的虚拟服务IP地址,所以需要保证LB和RS位于同一子网。又因为需要保证RS的响应包能走回到LB上,则客户端不能和RS位于同一子网。否则RS直接就能获取到客户端的MAC,响应包就直接回给客户端了,也就走不到LB上面了。这时候由于没有LB做SNAT,客户端收到的响应包源IP是RS的IP,而客户端的请求包目的IP是LB的虚拟服务IP,这时候客户端无法识别响应包,会直接丢弃。
IP隧道模式
隧道模式下LB将原始请求报文封装在另一个IP报文中,再将封装好的IP报文转发给后端RS;后端RS服务器收到报文后,先将报文解封获得原报文中目标地址为VIP的报文,服务器发现VIP地址被配置在本地的IP隧道设备上,所以就处理这个请求,然后根据路由表将响应报文直接返回给客户。
隧道模式的特点:
- LB和RS节点不用处于同一子网;解除了NAT模式和DR模式的限制。
- LB和RS节点必须都支持隧道技术,且RS节点也需要在TUN网卡上配置VIP地址;因为LB通过隧道发送报文,RS节点必须支持隧道才能解封装,解封装后拿到原始报文的目的地址为VIP,如果RS节点上没有配置VIP,则会丢弃报文。
- RS节点必须能访问互联网;因为RS节点是直接将响应报文返回给客户端,所以必须能访问外网。
命令演示
IPVS为内核子模块,需要用ipvsadm命令添加虚拟服务规则;IPVS与ipvsadm的关系就和netfilter与iptables一样。
ipvsadm命令参数展示
Commands:
--add-service -A 增加一个虚拟服务
--edit-service -E 修改一个虚拟服务
--delete-service -D 删除一个虚拟服务
--clear -C 清理所有虚拟服务
--restore -R 从标准输入获取ipvsadm命令。一般结合下边的-S使用。
--save -S 从标准输出输出虚拟服务器的规则。可以将虚拟服务器的规则保存,在以后通过-R直接读入,以实现自动化配置。
--add-server -a 为虚拟服务添加一个real server(RS)
--edit-server -e 修改虚拟服务中的RS
--delete-server -d 删除虚拟服务中的RS
--list -L|-l 列出虚拟服务表中的所有虚拟服务。可以指定地址。添加-c显示连接表。
--help -h 显示帮助信息
Options:
--tcp-service -t service-address 指定虚拟服务为tcp服务。service-address要是host[:port]的形式。
--udp-service -u service-address 指定虚拟服务为udp服务。service-address要是host[:port]的形式。
--scheduler -s scheduler 指定调度算法。调度算法可以指定以下10种:rr(轮询),wrr(权重),lc(最后连接),wlc(权重),lblc(本地最后连接),lblcr(带复制的本地最后连接),dh(目的地址哈希),sh(源地址哈希),sed(最小期望延迟),nq(永不排队)。默认调度算法为wlc。
--real-server -r server-address 为虚拟服务指定数据可以转发到的真实服务器的地址。可以添加端口号。如果没有指定端口号,则等效于使用虚拟地址的端口号。
--gatewaying -g 指定转发模式为DR(direct routing) (default)
--ipip -i 指定转发模式为ip隧道(tunneling)
--masquerading -m 指定转发模式为NAT模式(NAT)
--connection -c 列出当前的IPVS连接。
环境准备;VM1/VM2/VM3都是在client上的VMware虚拟机。VMware网络模式为NAT。
设备名称 | 设备ip |
---|---|
client | 7.249.241.35 |
VM1(LB) | ip:192.168.81.128 vip: 192.168.81.100 |
VM2(RS1) | 192.168.81.129 |
VM3(RS2) | 192.168.81.130 |
确保LB节点上开启contrack和forward功能
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
echo "net.ipv4.vs.conntrack=1" >> /etc/sysctl.conf
sysctl -p
在虚拟机VM1(LB)上安装ipvsadm命令
yum install ipvsadm
在虚拟机VM1(LB)上为网卡添加一个VIP
[root@vm1 ~]# ip addr add 192.168.81.100/24 dev eth0
[root@vm1 ~]# ip a s eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether fa:16:3e:68:5a:12 brd ff:ff:ff:ff:ff:ff
inet 192.168.81.128/24 brd 172.16.2.255 scope global noprefixroute dynamic eth0
valid_lft 102241123sec preferred_lft 102241123sec
inet 192.168.81.100/24 scope global secondary eth0
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fe68:5a12/64 scope link
valid_lft forever preferred_lft forever
在虚拟机VM1(LB)上添加ipvs虚拟配置,并指定调度算法为轮询
ipvsadm -At 192.168.81.100:80 -s rr
在虚拟机VM1(LB)上添加RS节点
ipvsadm -at 192.168.81.100:80 -r 192.168.81.129:80 -m
ipvsadm -at 192.168.81.100:80 -r 192.168.81.130:80 -m
在虚拟机VM1(LB)上查看虚拟配置
[root@test ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.81.100:80 rr
-> 192.168.81.129:80 Masq 1 0 0
-> 192.168.81.130:80 Masq 1 0 0
为了使client能访问vip,确保client机器上有访问vip的路由,192.168.81.1
为VMware的虚拟网卡VMnet8的ip
由于本次环境的LB/RS都是通过VMware虚拟出来的,虚拟机和client互通,为了使RS节点将响应报文返回给LB,需要在两个RS节点上添加路由,使响应报文经过LB从而把响应报文的源地址换回vip
#目的地址为什么不是客户端ip?因为VMware用的nat模式,client的请求到达LB时,VMware会把数据包源ip改为VMnet8网卡的地址`192.168.81.1`,也就是会做SNAT
ip route add 192.168.81.1 via 192.168.81.128 dev eth0
访问测试,LB将请求轮询转发给后端RS节点