一 LVS IP tunnel 模式介绍
IP 隧道 (IP tunneling) 是将一个 IP 报文封装在另一个 IP 报文的技术, 这可以使得目标为一个 IP 地址的数据报文能被封装和转发到另一个 IP 地址. IP 隧道技术亦称为 IP 封装技术(IP encapsulation).IP 隧道主要用于移动主机和虚拟私有网络(Virtual Private Network), 在其中隧道都是静态建立的, 隧道一端有一个 IP 地址, 另一端也有唯一的 IP 地址. 它的连接调度和管理与 VS/NAT 中的一样, 只是它的报文转发方法不同. 调度器根据各个服务器的负载情况, 动态地选择一台服务器, 将请求报文封装在另一个 IP 报文中, 再将封装后的 IP 报文转发给选出的服务器; 服务器收到报文后, 先将报文解封获得原来目标地址为 VIP 的报文, 服务器发现 VIP 地址被配置在本地的 IP 隧道设备上, 所以就处理这个请求, 然后根据路由表将响应报文直接返回给客户.
二 LVS DR 模式介绍
DR 模式也就是用直接路由技术实现虚拟服务器. 它的连接调度和管理与 VS/NAT 和 VS/TUN 中的一样, 但它的报文转发方法又有不同, VS/DR 通过改写请求报文的 MAC 地址, 将请求发送到 Real Server, 而 Real Server 将响应直接返回给客户, 免去了 VS/TUN 中的 IP 隧道开销. 这种方式是三种负载调度机制中性能最高最好的, 但是必须要求 Director Server 与 Real Server 都有一块网卡连在同一物理网段上. Director 和 RealServer 必需在物理上有一个网卡通过不间断的局域网相连. RealServer 上绑定的 VIP 配置在各自 Non-ARP 的网络设备上(如 lo 或 tunl),Director 的 VIP 地址对外可见, 而 RealServer 的 VIP 对外是不可见的. RealServer 的地址即可以是内部地址, 也可以是真实地址.
具体实现过程为:
DR 模式将报文直接路由给目标真实服务器. 在 DR 模式中, 调度器根据各个真实服务器的负载情况, 连接数多少等, 动态地选择一台服务器, 不修改目标 IP 地址和目标端口, 也不封装 IP 报文, 而是将请求报文的数据帧的目标 MAC 地址改为真实服务器的 MAC 地址. 然后再将修改的数据帧在服务器组的局域网上发送. 因为数据帧的 MAC 地址是真实服务器的 MAC 地址, 并且又在同一个局域网. 那么根据局域网的通讯原理, 真实复位是一定能够收到由 LB 发出的数据包. 真实服务器接收到请求数据包的时候, 解开 IP 包头查看到的目标 IP 是 VIP.(此时只有自己的 IP 符合目标 IP 才会接收进来, 所以我们需要在本地的回环借口上面配置 VIP. 另: 由于网络接口都会进行 ARP 广播响应, 但集群的其他机器都有这个 VIP 的 lo 接口, 都响应就会冲突. 所以我们需要把真实服务器的 lo 接口的 ARP 响应关闭掉.)然后真实服务器做成请求响应, 之后根据自己的路由信息将这个响应数据包发送回给客户, 并且源 IP 地址还是 VIP.
三 lvs DR 模式搭建
结构框图如下
上图是客户端发过来的请求报文, 我们知道 DR 模式中, LB 和 RS 上都绑定了 vip, 那么客户是如何请求到 LB 而不是直接到 RS 呢? 我们知道 IP 数据包其实是通过数据链路层发过来的, 只要确定上面问号处的 mac 地址为 LB 的 mac 地址即可, 如何办到呢, 这里使用了 ARP 协议, 简单来说就是通过 ip 解析出 mac 地址的一个协议, 我们把 vip 地址给广播出去, 具有此 ip 的机器就会回复自己的 mac 地址, 然而这里 LB 和 RS 均有 vip, 因此需要抑制住 RS 对于该 vip 地址的 arp 相应. 这样一来, 就能确定唯一的 LB mac 地址.
既然 Load Balancer 得到了这个 IP 数据包, 它就可以用某个策略从 RS1, RS2,RS3 中选取一个服务器, 例如 RS1(192.168.226.130), 把 IP 数据报原封不动, 封装成数据链路层的包(目的地是 RS1 的 MAC 地址), 直接转发就可以了, 请看下图
RS1(192.168.226.130)这个服务器收到了数据包, 拆开一看, 目的地 IP 是 192.168.226.100, 是自己的 IP, 那就可以处理了.
处理完了以后, RS1 可以直接响应发回给客户端, 完全不用再通过 Load Balancer. 因为自己的地址就是 192.168.226.100.
对于客户端来说, 它看到的还是那个唯一的 vip 地址 192.168.226.100, 并不知道后台发生了什么事情.
由于 Load Balancer 根本不会修改 IP 数据报, 其中的 TCP 的端口号自然也不会修改, 这就要求 RS1, RS2,RS3 上的端口号必须得和 Load Balancer 一致才行
数据的流向为:
客户端 --> Load Balancer --> RS --> 客户端
下面跟据具体实例来理解整个过程
准备三台机器
- DIR ens33 192.168.226.129 ens37
- RS1 ens33 192.168.226.130
- RS2 ens33 192.168.226.131
指定 vip 为 192.168.226.100,DIR vip 绑定在 ens37 上, 当然可以直接绑定一个虚拟网卡, 比如 ens33:2
以上每台机器都需要一个公网 ip
dir 上编写脚本 vim /usr/local/sbin/lvs_dr.sh // 内容如下
- #! /bin/bash
- echo 1> /proc/sys/net/ipv4/ip_forward
- ipv=/usr/sbin/ipvsadm
- vip=192.168.226.100
- rs1=192.168.226.130
- rs2=192.168.226.131
- # 注意这里的网卡名字
ifconfig ens37 $vip broadcast $vip netmask 255.255.255.255 up
- route add -host $vip dev ens37
- $ipv -C
$ipv -A -t $vip:80 -s wrr
$ipv -a -t $vip:80 -r $rs1:80 -g -w 1
$ipv -a -t $vip:80 -r $rs2:80 -g -w 1
两台 rs 上也编写脚本 vim /usr/local/sbin/lvs_rs.sh// 内容如下
- #/bin/bash
- vip=192.168.226.100
- # 把 vip 绑定在 lo 上, 是为了实现 rs 直接把结果返回给客户端
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
- route add -host $vip lo:0
- # 以下操作为更改 arp 内核参数, 目的是为了让 rs 顺利发送 mac 地址给客户端
- # 参考文档 www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html
- echo "1">/proc/sys/net/ipv4/conf/lo/arp_ignore
- echo "2">/proc/sys/net/ipv4/conf/lo/arp_announce
- echo "1">/proc/sys/net/ipv4/conf/all/arp_ignore
- echo "2">/proc/sys/net/ipv4/conf/all/arp_announce
分别运行以上脚本后, 在浏览器测试
刷新后
四 keepalived +lvs
之前我们试验过 lvs 的 nat 和 dr 两种模型的负载均衡, keepalived 不光可以基于 vrrp((Virtual Router Redundancy Protocol)协议实现高可用, 他本身集成有 lvs 功能, 可以实现负载均衡. 下面我们用四台机器做下实验, 基本拓扑结构如下
我们先准备四台服务器
LB1 LB2 RS1 RS2
LB1 两网卡 :ens33 192.168.226.129
ens37 192.168.199.200
LB2 两网卡: ens33 192.168.226.132
ens37 192.168.199.201
RS1 一网卡 ens33 192.168.226.130
RS2 一网卡 ens33 192.168.226.131
准备工作:
四台机器都关闭 selinux , 清空防火墙规则
两台调度器上安装好 keepalived, 两台 RS 上安装好 web nginx
1 LB1 作为主调度器
编辑 keepalived 配置文件
- vim /etc/keepalived/keepalived.conf
- vrrp_instance VI_1 {
- // 备用服务器上为 BACKUP
- state MASTER
- // 绑定 vip 的网卡为 ens37,
- interface ens37
- virtual_router_id 51
- // 备用服务器上为 90
- priority 100
- advert_int 1
- authentication {
- auth_type PASS
- auth_pass lvlinux
- }
- virtual_ipaddress {
- 192.168.226.100
- }
- }
- virtual_server 192.168.226.100 80 {
- //(每隔 10 秒查询 realserver 状态)
- delay_loop 10
- //(lvs 算法)
- lb_algo wrr
- //(DR 模式)
- lb_kind DR
- //(同一 IP 的连接 60 秒内被分配到同一台 realserver)
- persistence_timeout 60
- //(用 TCP 协议检查 realserver 状态)
- protocol TCP
- real_server 192.168.226.130 80 {
- //(权重)
- weight 100
- TCP_CHECK {
- //(10 秒无响应超时)
- connect_timeout 10
- nb_get_retry 3
- delay_before_retry 3
- connect_port 80
- }
- }
- real_server 192.168.226.131 80 {
- weight 100
- TCP_CHECK {
- connect_timeout 10
- nb_get_retry 3
- delay_before_retry 3
- connect_port 80
- }
- }
- }
备注: 上面我们定义了 vip 为 192.168.226.100, 并且绑定在网卡 ens37
上
LB2 操作
- vim /etc/keepalived/keepalived.conf
- vrrp_instance VI_1 {
- // 备用服务器上为 BACKUP
- state BACKUP
- // 绑定 vip 的网卡为 ens37
- interface ens37
- virtual_router_id 51
- // 备用服务器上为 90
- priority 90
- advert_int 1
- authentication {
- auth_type PASS
- auth_pass lvlinux
- }
- virtual_ipaddress {
- 192.168.226.100
- }
- }
- virtual_server 192.168.226.100 80 {
- //(每隔 10 秒查询 realserver 状态)
- delay_loop 10
- //(lvs 算法)
- lb_algo wrr
- //(DR 模式)
- lb_kind DR
- //(同一 IP 的连接 60 秒内被分配到同一台 realserver)
- persistence_timeout 60
- //(用 TCP 协议检查 realserver 状态)
- protocol TCP
- real_server 192.168.226.130 80 {
- #(权重)
- weight 100
- TCP_CHECK {
- #(10 秒无响应超时)
- connect_timeout 10
- nb_get_retry 3
- delay_before_retry 3
- connect_port 80
- }
- }
- real_server 192.168.226.131 80 {
- weight 100
- TCP_CHECK {
- connect_timeout 10
- nb_get_retry 3
- delay_before_retry 3
- connect_port 80
- }
- }
- }
也就是将 state master 更改为 backup , priority 100 改为 90
RS1 和 RS2 上编辑脚本
- vim /usr/local/sbin/lv_dr_rs.sh
- #/bin/bash
- vip=192.168.226.100
- # 把 vip 绑定在 lo 上, 是为了实现 rs 直接把结果返回给客户端
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
- route add -host $vip lo:0
- # 以下操作为更改 arp 内核参数, 目的是为了让 rs 顺利发送 mac 地址给客户端
- # 参考文档 www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html
- echo "1">/proc/sys/net/ipv4/conf/lo/arp_ignore
- echo "2">/proc/sys/net/ipv4/conf/lo/arp_announce
- echo "1">/proc/sys/net/ipv4/conf/all/arp_ignore
- echo "2">/proc/sys/net/ipv4/conf/all/arp_announce
RS 上 sh 运行脚本后, 在 LB1 上和 LB2 上 启动 keepalived
ipvsadm -ln 查看 RS 链接状态
ip add 查看 vip 绑定情况
LB1 上关闭 keepalived 后发现, LB2 上重新绑定了 vip 接管了服务, 在 / var/log/messages 中可以看到 vrrp 主从变更
lB2 上 ipvsadem -ln 查看 RS 链接状态
关闭一台 RS nginx , 测试高可用
来源: http://blog.51cto.com/12606610/2120140