LVS之2---基于LVS负载均衡集群架构实现
ipvsadm
software package
[root@lb01 ~]# rpm -ql ipvsadm
/etc/sysconfig/ipvsadm-config # 配置文件
/usr/lib/systemd/system/ipvsadm.service # 服务
/usr/sbin/ipvsadm # 主命令
/usr/sbin/ipvsadm-restore # 导入规则命令
/usr/sbin/ipvsadm-save # 导出规则命令
/usr/share/doc/ipvsadm-1.27 # 说明书
/usr/share/doc/ipvsadm-1.27/README
/usr/share/man/man8/ipvsadm-restore.8.gz
/usr/share/man/man8/ipvsadm-save.8.gz
/usr/share/man/man8/ipvsadm.8.gz
Options
Usage:
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask] [--pe persistence_engine] [-b sched-flags]
ipvsadm -D -t|u|f service-address
ipvsadm -C
ipvsadm -R
ipvsadm -S [-n]
ipvsadm -a|e -t|u|f service-address -r server-address [options]
ipvsadm -d -t|u|f service-address -r server-address
ipvsadm -L|l [options]
ipvsadm -Z [-t|u|f service-address]
ipvsadm --set tcp tcpfin udp
ipvsadm --start-daemon state [--mcast-interface interface] [--syncid sid]
ipvsadm --stop-daemon state
Commands:
--add-service -A 添加具有选项的虚拟服务
--edit-service -E 编辑具有选项的虚拟服务
--delete-service -D 删除虚拟服务
--clear -C 清理整张表
--restore -R 从标准输入还原规则
--save -S 保存规则到标准输出
--add-server -a 添加带有选项的真实服务器
--edit-server -e 编辑带有选项的真实服务器
--delete-server -d 删除真实服务器
--list -L|-l 列出表
--zero -Z 一个或所有服务的计数器清零(清空当前的连接数量等)
--set tcp tcpfin udp 设置连接超时值
--start-daemon 启动连接同步守护程序
--stop-daemon 停止连接同步守护程序
Options:
--tcp-service -t service-address service-address is host[:port]
--udp-service -u service-address service-address is host[:port]
--fwmark-service -f fwmark fwmark是一个大于零的整数
--ipv6 -6 fwmark使用ipv6
--scheduler -s 调度器 one of rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,(default=wlc)
--pe engine 备用持久性引擎可以是sip,默认不设置
--persistent -p [timeout] 持久服务,会话保持时间,省略时长,默认360秒
--netmask -M netmask 持久粒度掩码
--real-server -r server-address server-address is host (and port)
指定工作模式:
--gatewaying -g 网关 (直接路由) (default)
--ipip -i ipip 封装 (tunneling)
--masquerading -m 伪装 (NAT)
--weight -w weight 真实服务器的权值
--u-threshold -x uthreshold 连接的上限阈值
--l-threshold -y lthreshold 连接的下限阈值
--mcast-interface interface 用于连接同步的多播接口
--syncid sid 用于连接同步的 syncid (default=255)
--connection -c 输出当前的IPVS连接
--timeout 输出超时 (tcp tcpfin udp)
--daemon 输出守护进程信息
--stats 输出统计信息
--rate 输出速率信息
--exact 精确展开数字(显示精确值)
--thresholds 输出阈值信息
--persistent-conn 输出持久连接信息
--nosort 禁用服务/服务器项的输出排序
--sort 为了向后兼容,什么都不做
--ops -o 单包调度
--numeric -n 以数字输出地址和端口
--sched-flags -b flags 计划程序标志 (逗号分隔)
常用命令
管理集群服务
添加:-A -t|u|f service-address [-s scheduler]
-t: TCP协议的集群
-u: UDP协议的集群
service-address: IP:PORT
-f: FWM: 防火墙标记
service-address: Mark Number
修改:-E
删除:-D -t|u|f service-address
例如:
# ipvsadm -A -t 10.10.0.1:80 -s rr
管理集群服务中的 RS
添加:-a -t|u|f service-address -r server-address [-g|i|m] [-w weight]
-t|u|f service-address:事先定义好的某集群服务
-r server-address: 某RS的地址,在NAT模型中,可使用IP:PORT实现端口映射;
[-g|i|m]: LVS类型
-g: DR
-i: TUN
-m: NAT
[-w weight]: 定义服务器权重
修改:-e
删除:-d -t|u|f service-address -r server-address
例如:
# ipvsadm -a -t 10.10.0.2:80 -r 192.168.10.8 -m
# ipvsadm -a -t 10.10.0.3:80 -r 192.168.10.9:8080 -m
查看规则
-L|-l
-n:数字格式显式主机地址和端口
--stats:统计数据
--rate: 速率
--timeout: 显示tcp、tcpfin和udp的会话超时时长
-c: 显示当前的ipvs连接状况
删除所有集群服务
-C:清空 ipvs 规则
保存及重载规则
启动ipvsadm服务并设置为开机启动
systemctl start ipvsadm
systemctl enable ipvsadm
停止ipvsadm服务会自动保存到/etc/sysconfig/ipvsadm配置文件
systemctl stop ipvsadm
重启ipvsadm服务会自动重载/etc/sysconfig/ipvsadm配置文件中的LVS规则
systemctl restart ipvsadm
手动将LVS规则保存在指定的/tmp/ipvs.log文件中
ipvsadm-save > /tmp/ipvs.log
ipvsadm -R > /tmp/ipvs.log
手动将指定的/tmp/ipvs.log文件中的LVS规则加载到ipvsadm服务中
ipvsadm-restore < /tmp/ipvs.log
ipvsadm -S < /tmp/ipvs.log
内存映射文件
[root@lb01 ~]# ls /proc/net/ip_vs* | xargs -l
/proc/net/ip_vs # ipvs规则
/proc/net/ip_vs_app
/proc/net/ip_vs_conn # ipvs连接
/proc/net/ip_vs_conn_sync
/proc/net/ip_vs_stats
/proc/net/ip_vs_stats_percpu
arp_ignore:定义接受到ARP请求时的相应级别
0:只要本地配置的有相应地址,就给予响应(默认)
1:仅回应目标IP地址是本地的入网地址的arp请求。
2:仅回应目标IP地址是本地的入网地址,而且源IP和目标IP在同一个子网的arp请求。
3:不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应
4-7:保留未使用
8:不回应所有的arp请求
arp_announce: 定义将自己地址向外界通告的通告级别
支持内核参数
# 查看内核是否有lvs模块
[root@lb01 ~]# grep -i -C 10 " IPVS " /boot/config-3.10.0-1127.19.1.el7.x86_64
... ...
# IPVS transport protocol load balancing support
#
CONFIG_IP_VS_PROTO_TCP=y # 开启tcp
CONFIG_IP_VS_PROTO_UDP=y # 开启udp
CONFIG_IP_VS_PROTO_AH_ESP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
CONFIG_IP_VS_PROTO_SCTP=y
#
# IPVS scheduler # 默认支持的算法
#
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
#
# IPVS SH scheduler
#
CONFIG_IP_VS_SH_TAB_BITS=8
#
# IPVS application helper
#
CONFIG_IP_VS_FTP=m
CONFIG_IP_VS_NFCT=y
CONFIG_IP_VS_PE_SIP=m
#
# IP: Netfilter Configuration
#
CONFIG_NF_DEFRAG_IPV4=m
CONFIG_NF_CONNTRACK_IPV4=m
实现
环境准备
-
CentOS 7.6 关闭防火墙和selinux
-
Keepalived 1.3.5
-
ipvsadm 1.27
-
Nginx 1.18.0
主机名 | eth0 | eth1 | 角色 |
---|---|---|---|
lb01 | DIP:10.0.0.5 VIP:10.0.0.3 | 172.16.1.5 | DS1 |
lb02 | DIP:10.0.0.6 VIP:10.0.0.3 | 172.16.1.6 | DS2 |
web01 | RIP:10.0.0.7 | 172.16.1.7 | RS1 |
web02 | RIP:10.0.0.8 | 172.16.1.8 | RS2 |
相关软件安装配置
RS
yum install nginx -y
cat > /etc/nginx/conf.d/web.conf <<EOF
server {
listen 80;
location / {
root /usr/share/nginx/html;
}
}
EOF
echo `hostname` >/usr/share/nginx/html/index.html
systemctl start nginx
DS
yum install ipvsadm keepalived -y
[root@lb01 ~]# curl 10.0.0.7
web01
[root@lb01 ~]# curl 10.0.0.8
web02
LVS-DR模式(VIP与RIP在同一网段)
架构图:
|
|VIP:10.0.0.3
+-------+--------+
| DS1:lb01 |
| LVS |
+-------+--------+
|DIP:10.0.0.5
|
+------------+VIP:10.0.0.3 | VIP:10.0.0.3+------------+
| RS1:web01 |RIP:10.0.0.7 | RIP:10.0.0.8| RS2:web02 |
| Web Server +--------------+---------------+ Web Server |
+------------+ +------------+
DS
# 设置 tcp tcpfin udp 连接超时值
ipvsadm --set 10 5 20
# 手动绑定VIP到eth0
ip a a 10.0.0.3/32 dev eth0
# 创建LVS服务调度算法规则,将VIP地址绑定在LVS调度器上,指定调度算法rr
ipvsadm -A -t 10.0.0.3:80 -s rr
# 使用DR模型,添加后端RS1服务器
ipvsadm -a -t 10.0.0.3:80 -r 10.0.0.7 -g
# 使用DR模型,添加后端RS2服务器
ipvsadm -a -t 10.0.0.3:80 -r 10.0.0.8 -g
# 查看规则表
ipvsadm -ln
# 保存规则
ipvsadm-save > /etc/sysconfig/ipvsadm
systemctl start ipvsadm
systemctl enable ipvsadm
RS
# 开启ARP抑制
cat >> /etc/sysctl.conf << EOF
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.lo.arp_announce=2
EOF
sysctl -p
# 手动绑定VIP到eth0
ip a a 10.0.0.3/32 dev lo
测试
[root@m01 ~]# i=0;while ((i<6)); do curl 10.0.0.3; sleep 0.5;((i++));done;
web01
web02
web01
web02
web01
web02
注意:如果VIP和RIP的IP地址在同一网段,会导致客户端也可以直接访问RS服务器内网地址,可能会不需要经过LVS,造成访问网络风险。
持久连接
persistence template:持久连接模板:将多个集群服务归并到一起统一调度
- PPC:每端口持久;持久连接生效范围仅为单个集群服务;如果有多个集群服务,每服务被单独持久调度;
- PCC:每客户端持久;持久连接生效范围为所有服务;定义集群服务时,其TCP或UDP协议的目标端口要使用0;
- PFWM:每FWM持久:持久连接生效范围为定义为同一个FWM下的所有服务;
语法:
ipvsadm -A t|u|f server-address -s scheduler -p
无-p选项:不启用持久链接
-p:指定持久时长,省略时长,默认360秒
定义一个PPC持久链接服务 (客户端请求同一个集群服务,始终调度到同一台RS服务器)
ipvsadm -A -t 10.0.0.3:80 -s rr -p
ipvsadm -a -t 10.0.0.3:80 -r 10.0.0.7 -g -w 1
ipvsadm -a -t 10.0.0.3:80 -r 10.0.0.8 -g -w 1
定义一个PCC持久链接服务(客户端的所有请求都调度到同一个realserver)
ipvsadm -A -t 10.0.0.3:80 -s rr -p
ipvsadm -a -t 10.0.0.3:80 -r 10.0.0.7 -g
ipvsadm -a -t 10.0.0.3:80 -r 10.0.0.8 -g
定义一个FWM持久链接服务 (根据防火墙标记,将相同的标记的调度到同一个realserver)
iptables -t mangle -A PREROUTING -d 10.0.0.3 -p tcp --dport 80 -j MARK --set-mark 10
iptables -t mangle -A PREPOUTING -d 10.0.0.3 -p tcp --dport 443 -j MARK --set-mark 10
ipvsadm -A -f 10 -s rr -p
ipvsadm -a -f 10 -r 10.0.0.7 -g -w 1
ipvsadm -a -f 10 -r 10.0.0.8 -g -w 1
80/443 的请求都会调用到同一个realserver
示例:
DS
ipvsadm -C
ipvsadm -A -t 10.0.0.3:80 -s rr -p 5
ipvsadm -a -t 10.0.0.3:80 -r 10.0.0.7 -g
ipvsadm -a -t 10.0.0.3:80 -r 10.0.0.8 -g
ipvsadm -ln
测试
# 一直保持连接
[root@m01 ~]# i=0;while ((i<6)); do curl 10.0.0.3; sleep 1;((i++));done;
web01
web01
web01
web01
web01
web01
# 长连接
[root@m01 ~]# i=0;while ((i<6)); do curl 10.0.0.3; sleep 350;((i++));done;
web01
web02
web01
web02
LVS-NAT模式
架构图:
|
|VIP:10.0.0.3
+-------+--------+
| DS1:lb01 |
| LVS |
+-------+--------+
|DIP:172.16.1.5
|
+------------+ | +------------+
| RS1:web01 |RIP:172.16.1.7| RIP:172.16.1.8| RS2:web02 |
| Web Server +--------------+---------------+ Web Server |
+------------+ +------------+
DS
ipvsadm -C
# 手动绑定VIP到eth0
ip a a 10.0.0.3/32 dev eth0
# 创建LVS服务调度算法规则,将VIP地址绑定在LVS调度器上,指定调度算法rr
ipvsadm -A -t 10.0.0.3:80 -s rr
# 使用NAT模型,添加后端RS1服务器
ipvsadm -a -t 10.0.0.3:80 -r 172.16.1.7 -m
# 使用NAT模型,添加后端RS2服务器
ipvsadm -a -t 10.0.0.3:80 -r 172.16.1.8 -m
# 查看规则表
ipvsadm -ln
# 保存规则
ipvsadm-save > /etc/sysconfig/ipvsadm
# 开启路由转发功能
cat >> /etc/sysctl.conf << EOF
net.ipv4.ip_forward=1
EOF
sysctl -p
RS
mv /etc/sysconfig/network-scripts/ifcfg-eth0{,.bak}
cat > /etc/sysconfig/network-scripts/ifcfg-eth1 << EOF
TYPE=Ethernet
BOOTPROTO=static
NAME=eth1
DEVICE=eth1
ONBOOT=yes
IPADDR=172.16.1.7
PREFIX=24
GATEWAY=172.16.1.5
DNS1=223.5.5.5
EOF
systemctl restart network
mv /etc/sysconfig/network-scripts/ifcfg-eth0{,.bak}
cat > /etc/sysconfig/network-scripts/ifcfg-eth1 << EOF
TYPE=Ethernet
BOOTPROTO=static
NAME=eth1
DEVICE=eth1
ONBOOT=yes
IPADDR=172.16.1.8
PREFIX=24
GATEWAY=172.16.1.5
DNS1=223.5.5.5
EOF
systemctl restart network
测试
[root@m01 ~]# i=0;while ((i<6)); do curl 10.0.0.3; sleep 0.5;((i++));done;
web01
web02
web01
web02
web01
web02
WRR算法
DS
ipvsadm -C
# 手动绑定VIP到eth0
ip a a 10.0.0.3/32 dev eth0
# 创建LVS服务调度算法规则,将VIP地址绑定在LVS调度器上,指定调度算法wrr
ipvsadm -A -t 10.0.0.3:80 -s wrr
# 使用NAT模型,添加后端RS1服务器,权重3
ipvsadm -a -t 10.0.0.3:80 -r 172.16.1.7 -m -w 3
# 使用NAT模型,添加后端RS2服务器,权重1
ipvsadm -a -t 10.0.0.3:80 -r 172.16.1.8 -m -w 1
# 查看规则表
ipvsadm -ln
# 保存规则
ipvsadm-save > /etc/sysconfig/ipvsadm
测试
[root@m01 ~]# i=0;while ((i<12)); do curl 10.0.0.3; sleep 0.5;((i++));done;
web02
web01
web01
web01
web02
web01
web01
web01
web02
web01
web01
web01
HTTPS
借助于 FireWall Mark(防火墙标签)来分类报文,而后基于标记定义集群服务;可将多个不同的应用使用同一个集群服务进行调度,贴同一个标签就是同一个服务。
--set-mark NUMBER # NUMBER 可为十六进制数,格式0xffff
实现方法:
# LVS主机打标记:
iptables -t mangle -A PREROUTING -d $vip -p $proto -m multiport --dports $port1,$port2,… -j MARK --set-mark NUMBER
# LVS主机基于标记定义集群服务:
ipvsadm -A -f NUMBER [options]
DS
# 最后一个10是自定义的标签
iptables -t mangle -A PREROUTING -d 10.0.0.3 -p tcp -m multiport --ports 80,443 -j MARK --set-mark 10
# 查看防火墙的规则
iptables -t mangle -vnL
ipvsadm -C
# 添加标签调度算法
ipvsadm -A -f 10 -s rr
# 使用NAT模型,添加后端RS1服务器
ipvsadm -a -f 10 -r 172.16.1.7 -m
# 使用NAT模型,添加后端RS1服务器
ipvsadm -a -f 10 -r 172.16.1.8 -m
# 查看规则表
ipvsadm -ln
# 保存规则
ipvsadm-save > /etc/sysconfig/ipvsadm
RS
# 安装mod_ssl模块,并启动httpd服务
yum install mod_ssl
systemctl start httpd
验证
[root@m01 ~]# i=0;while ((i<6)); do curl 10.0.0.3; sleep 0.5;((i++));done;
web01
web02
web01
web02
web01
web02
Keepalived集成LVS
keepalived中集成有LVS,可以不用安装ipvsadm,在keepalived配置文件内就能配置LVS,可以用于双机热备的自动故障转移,也可以管理lvs的RS列表,自动对RS做健康检查。
|
+--------------------+--------------------+
|----- VIP:10.0.0.3 -----|
+-------+--------+ +-------+--------+
| DS1:lb01 | | DS2:lb02 |
| keepalived | | keepalived |
+-------+--------+ +-------+--------+
|DIP:10.0.0.5 |DIP:10.0.0.6
+--------------------+--------------------+
|
+------------+ | +------------+
| RS1:web01 |RIP:10.0.0.7 | RIP:10.0.0.8| RS2:web02 |
| Web Server +--------------+---------------+ Web Server |
+------------+ +------------+
DS
主lb1配置
cat > /etc/keepalived/keepalived.conf << EOF
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
# 指定Keepalived角色,MASTER 为主,BACKUP 为备
state MASTER
# 当前 IP 对应的网卡,可以使用 ip a 查看
interface eth0
# 虚拟路由编号(0-255),主备一致
virtual_router_id 51
# 优先级,数字越大,优先级越高,主必须大于备
priority 100
# 通告时间间隔:默认1s,主备一致
advert_int 1
# 认证机制,主备一致,密码最多为8位
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3 # 虚拟IP(VIP),可多设,每行一个
}
}
# 定义对外提供服务的LVS的VIP以及port
virtual_server 10.0.0.3 80 {
# 设置健康检查时间,单位是秒
delay_loop 6
# 设置调度算法为rr
lb_algo rr
# 设置LVS实现负载的机制,有NAT、TUN、DR三个模式
lb_kind DR
nat_mask 255.255.255.0
# 持久连接超时时间
persistence_timeout 0
protocol TCP
# 指定real server1的IP地址
real_server 10.0.0.7 80 {
# 配置节点权值,数字越大权重越高
weight 3
TCP_CHECK {
connect_timeout 10
# 旧版本为 nb_get_retry
retry 3
delay_before_retry 3
connect_port 80
}
}
# 指定real server2的IP地址
real_server 10.0.0.8 80 {
weight 3
TCP_CHECK {
connect_timeout 10
retry 3
delay_before_retry 3
connect_port 80
}
}
}
EOF
# 删除手动绑定的VIP
ip a d 10.0.0.3/32 dev eth0
systemctl start keepalived
从lb2配置
cat > /etc/keepalived/keepalived.conf << EOF
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
# 指定Keepalived角色,MASTER 为主,BACKUP 为备
state BACKUP
# 当前 IP 对应的网卡,可以使用 ip a 查看
interface eth0
# 虚拟路由编号(0-255),主备一致
virtual_router_id 51
# 优先级,数字越大,优先级越高,主必须大于备
priority 50
# 通告时间间隔:默认1s,主备一致
advert_int 1
# 认证机制,主备一致,密码最多为8位
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3 # 虚拟IP(VIP),可多设,每行一个
}
}
# 定义对外提供服务的LVS的VIP以及port
virtual_server 10.0.0.3 80 {
# 设置健康检查时间,单位是秒
delay_loop 6
# 设置调度算法为rr
lb_algo rr
# 设置LVS实现负载的机制,有NAT、TUN、DR三个模式
lb_kind DR
nat_mask 255.255.255.0
# 持久连接超时时间
persistence_timeout 0
protocol TCP
# 指定real server1的IP地址
real_server 10.0.0.7 80 {
# 配置节点权值,数字越大权重越高
weight 3
TCP_CHECK {
connect_timeout 10
# 旧版本为 nb_get_retry
retry 3
delay_before_retry 3
connect_port 80
}
}
# 指定real server2的IP地址
real_server 10.0.0.8 80 {
weight 3
TCP_CHECK {
connect_timeout 10
retry 3
delay_before_retry 3
connect_port 80
}
}
}
EOF
# 删除手动绑定的VIP
ip a d 10.0.0.3/32 dev eth0
systemctl start keepalived
测试
[root@m01 ~]# i=0;while ((i<6)); do curl 10.0.0.3; sleep 0.5;((i++));done;
web01
web02
web01
web02
web01
web02
# 关闭DS1,仍然可以访问
[root@lb01 ~]# systemctl stop keepalived
[root@m01 ~]# i=0;while ((i<6)); do curl 10.0.0.3; sleep 0.5;((i++));done;
web01
web02
web01
web02
web01
web02
LVS-DR模式(VIP与RIP不在同一网段)
|
+--------------------+
|IP1:10.0.0.6
+----------------+ +-------+--------+
| DS1:lb01 | | Route:lb02 |
| LVS | | Route |
+-------+--------+ +-------+--------+
|VIP:10.0.1.3 |IP2:172.16.1.6
|DIP:172.16.1.5 |VIP网关:10.0.1.6
+--------------------+--------------------+
|
+------------+VIP:10.0.1.3 | VIP:10.0.1.3+------------+
| RS1:web01 |RIP:172.16.1.7| RIP:172.16.1.8| RS2:web02 |
| Web Server +--------------+---------------+ Web Server |
+------------+ +------------+
Router
# 手动绑定VIP网关到eth1
ip a a 10.0.1.6/24 dev eth1
# 开启路由转发功能
cat >> /etc/sysctl.conf << EOF
net.ipv4.ip_forward=1
EOF
sysctl -p
DS
ipvsadm -C
# 手动绑定VIP到eth0
ip a a 10.0.0.3/32 dev eth0
# 创建LVS服务调度算法规则,将VIP地址绑定在LVS调度器上,指定调度算法rr
ipvsadm -A -t 10.0.1.3:80 -s rr
# 使用DR模型,添加后端RS1服务器
ipvsadm -a -t 10.0.1.3:80 -r 172.16.1.7 -g
# 使用DR模型,添加后端RS2服务器
ipvsadm -a -t 10.0.1.3:80 -r 172.16.1.8 -g
# 查看规则表
ipvsadm -ln
# 保存规则
ipvsadm-save > /etc/sysconfig/ipvsadm
# 开启路由转发功能
cat >> /etc/sysctl.conf << EOF
net.ipv4.ip_forward=1
EOF
sysctl -p
mv /etc/sysconfig/network-scripts/ifcfg-eth0{,.bak}
cat > /etc/sysconfig/network-scripts/ifcfg-eth1 << EOF
TYPE=Ethernet
BOOTPROTO=static
NAME=eth1
DEVICE=eth1
ONBOOT=yes
IPADDR=172.16.1.5
PREFIX=24
GATEWAY=172.16.1.6
DNS1=223.5.5.5
EOF
systemctl restart network
# 手动绑定VIP到eth1
ip a a 10.0.1.3/32 dev eth1
RS
mv /etc/sysconfig/network-scripts/ifcfg-eth0{,.bak}
cat > /etc/sysconfig/network-scripts/ifcfg-eth1 << EOF
TYPE=Ethernet
BOOTPROTO=static
NAME=eth1
DEVICE=eth1
ONBOOT=yes
IPADDR=172.16.1.7
PREFIX=24
GATEWAY=172.16.1.6
DNS1=223.5.5.5
EOF
systemctl restart network
# 手动绑定VIP到lo
ip a a 10.0.1.3/32 dev lo
mv /etc/sysconfig/network-scripts/ifcfg-eth0{,.bak}
cat > /etc/sysconfig/network-scripts/ifcfg-eth1 << EOF
TYPE=Ethernet
BOOTPROTO=static
NAME=eth1
DEVICE=eth1
ONBOOT=yes
IPADDR=172.16.1.8
PREFIX=24
GATEWAY=172.16.1.6
DNS1=223.5.5.5
EOF
systemctl restart network
# 手动绑定VIP到lo
ip a a 10.0.1.3/32 dev lo
测试
[root@m01 ~]# ip route add 10.0.1.3 via 10.0.0.6
[root@m01 ~]# i=0;while ((i<6)); do curl 10.0.1.3; sleep 0.5;((i++));done;
web01
web02
web01
web02
web01
web02
LVS-TUN模式
DS
# Install keepalived
# CentOS
yum install keepalived ipvsadm
# update iptables
vim /etc/sysconfig/iptables
# For keepalived:
# allow vrrp
-A INPUT -p vrrp -j ACCEPT
-A INPUT -p igmp -j ACCEPT
# allow multicast
-A INPUT -d 224.0.0.18 -j ACCEPT
# reload iptables
service iptables reload
# open ip_forward
echo "1" > /proc/sys/net/ipv4/ip_forward
# edit sysctl.conf
vi /etc/sysctl.conf
net.ipv4.ip_forward = 1
sysctl -p
# keepalived for lvs-tun
vim /etc/keepalived/keepalived.conf
vrrp_sync_group GOP {
group {
VI_PRI_AUTH
}
}
vrrp_instance VI_PRI_AUTH {
state BACKUP
interface em1
virtual_router_id 11
priority 100
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.10.36.11/23 dev em1
}
}
virtual_server 10.10.36.11 80 {
delay_loop 6
lb_algo rr
lb_kind TUN
protocol TCP
real_server 10.10.36.4 80 {
weight 100
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 10.10.36.7 80 {
weight 100
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
# enable and start keepalived
systemctl start keepalived
systemctl enable keepalived
watch ipvsadm -L -n --stats
# write script, recommand manage it by keepalived.conf
#!/bin/sh
# Startup script handle the initialisation of LVS
# chkconfig: - 28 72
# description: Initialise the Linux Virtual Server for TUN
#
### BEGIN INIT INFO
# Provides: ipvsadm
# Required-Start: $local_fs $network $named
# Required-Stop: $local_fs $remote_fs $network
# Short-Description: Initialise the Linux Virtual Server
# Description: The Linux Virtual Server is a highly scalable and highly
# available server built on a cluster of real servers, with the load
# balancer running on Linux.
# description: start LVS of TUN
LOCK=/var/lock/lvs-tun.lock
VIP=10.10.36.11
RIP1=10.10.36.4
RIP2=10.10.36.7
. /etc/rc.d/init.d/functions
start() {
PID=`ipvsadm -Ln | grep ${VIP} | wc -l`
if [ $PID -gt 0 ];
then
echo "The LVS-TUN Server is already running !"
else
#Load the tun mod
/sbin/modprobe tun
/sbin/modprobe ipip
#Set the tun Virtual IP Address
/sbin/ifconfig tunl0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev tunl0
#Clear IPVS Table
/sbin/ipvsadm -C
#The icmp recruit setting
echo "0" >/proc/sys/net/ipv4/ip_forward
echo "0" >/proc/sys/net/ipv4/conf/all/send_redirects
echo "0" >/proc/sys/net/ipv4/conf/default/send_redirects
#Set Lvs
/sbin/ipvsadm -At $VIP:80 -s rr
/sbin/ipvsadm -at $VIP:80 -r $RIP1:80 -i -w 1
/sbin/ipvsadm -at $VIP:80 -r $RIP2:80 -i -w 1
/bin/touch $LOCK
#Run Lvs
echo "starting LVS-TUN-DIR Server is ok !"
fi
}
stop() {
#stop Lvs server
/sbin/ipvsadm -C
/sbin/ifconfig tunl0 down >/dev/null
#Remove the tun mod
/sbin/modprobe -r tun
/sbin/modprobe -r ipip
rm -rf $LOCK
echo "stopping LVS-TUN-DIR server is ok !"
}
status() {
if [ -e $LOCK ];
then
echo "The LVS-TUN Server is already running !"
else
echo "The LVS-TUN Server is not running !"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 1
start
;;
status)
status
;;
*)
echo "Usage: $1 {start|stop|restart|status}"
exit 1
esac
exit 0
RS
# 在加载好ipip模块后就会有默认的tunl0隧道
modprobe ipip
# 添加VIP
# ifconfig tunl0 down
ifconfig tunl0 10.10.36.11 broadcast 10.10.36.11 netmask 255.255.255.255 up
# 添加路由
route add -host 10.10.36.11 tunl0
# 手动关闭ARP转发
echo '1' > /proc/sys/net/ipv4/conf/tunl0/arp_ignore
echo '2' > /proc/sys/net/ipv4/conf/tunl0/arp_announce
echo '1' > /proc/sys/net/ipv4/conf/all/arp_ignore
echo '2' > /proc/sys/net/ipv4/conf/all/arp_announce
echo '0' > /proc/sys/net/ipv4/conf/tunl0/rp_filter
echo '0' > /proc/sys/net/ipv4/conf/all/rp_filter
# iptables允许ipip协议
iptables -I INPUT 1 -p 4 -j ACCEPT
vim /etc/sysconfig/iptables
-A INPUT -p ipv4 -j ACCEPT
# 编写RS启停脚本,推荐用脚本管理RS
vim /etc/init.d/lvs-tun
#!/bin/sh
#
# Startup script handle the initialisation of LVS
# chkconfig: - 28 72
# description: Initialise the Linux Virtual Server for TUN
#
### BEGIN INIT INFO
# Provides: ipvsadm
# Required-Start: $local_fs $network $named
# Required-Stop: $local_fs $remote_fs $network
# Short-Description: Initialise the Linux Virtual Server
# Description: The Linux Virtual Server is a highly scalable and highly
# available server built on a cluster of real servers, with the load
# balancer running on Linux.
# description: start LVS of TUN-RIP
LOCK=/var/lock/ipvsadm.lock
VIP=10.10.36.11
. /etc/rc.d/init.d/functions
start() {
PID=`ifconfig | grep tunl0 | wc -l`
if [ $PID -ne 0 ];
then
echo "The LVS-TUN-RIP Server is already running !"
else
#Load the tun mod
/sbin/modprobe tun
/sbin/modprobe ipip
#Set the tun Virtual IP Address
/sbin/ifconfig tunl0 $VIP netmask 255.255.255.255 broadcast $VIP up
/sbin/route add -host $VIP dev tunl0
echo "1" >/proc/sys/net/ipv4/conf/tunl0/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/tunl0/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
echo "0" > /proc/sys/net/ipv4/conf/tunl0/rp_filter
echo "0" > /proc/sys/net/ipv4/conf/all/rp_filter
/bin/touch $LOCK
echo "starting LVS-TUN-RIP server is ok !"
fi
}
stop() {
/sbin/ifconfig tunl0 down
echo "0" >/proc/sys/net/ipv4/conf/tunl0/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/tunl0/arp_announce
echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
#Remove the tun mod
/sbin/modprobe -r tun
/sbin/modprobe -r ipip
rm -rf $LOCK
echo "stopping LVS-TUN-RIP server is ok !"
}
status() {
if [ -e $LOCK ];
then
echo "The LVS-TUN-RIP Server is already running !"
else
echo "The LVS-TUN-RIP Server is not running !"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status
;;
*)
echo "Usage: $1 {start|stop|restart|status}"
exit 1
esac
exit 0
# start lvs-tun
chmod 755 /etc/init.d/lvs-tun
service lvs-tun start
chkconfig lvs-tun on
# Nginx test
echo "rs1" > /usr/share/nginx/html/index.html
echo "rs2" > /usr/share/nginx/html/index.html
for i in {1..100}; do curl 10.10.36.11; sleep 0.5; done
这一步的主要目的是让 RS 禁言,在相对较新的版本中新增了两个内核参数 (kernel parameter)
- 第一个是 arp_ignore 定义接受到 ARP 请求时的相应级别
- 第二个是 arp_announce 定义将自己地址向外通告是的通告级别
- 第三个是 rp_filter 定义系统是否开启对数据包源地址的校验
总结: LVS/TUN 是所有模式中最最适用于跨网络跨地域地理位置的一种模式,需要注意的是:
- 若 DIR 和 RIP 在不同 lan 网络中,比如不同的网段,不同的 IDC 机房,就不需要设置 arp 仰制,不同网段中,arp 会被屏蔽掉,所以只需设置 ip tunne 以及报文反向验证即可;
- 若 DIR 和 RIP 在同一广播域中,需要和 LVS/DR 模式一样在所有的 RIP 上仰制 arp,防止 arp 响应导致 arp 表混乱,这样 lvs 就不能正常工作!
配置时除了配置 DIR,还需要需要配置后端 RS server,即在 tunl 上口配置 vip 地址(需要系统支持 tunl 才行),广播为自己,此模式下无需开启路由转发功能!