lvs+keepalive+nginx负载均衡
1、部署规划
系统:Centos7
MASTER 192.168.26.8:安装Lvs+Keepalived
BACKUP 192.168.26.9:安装Lvs+Keepalived
192.168.26.6:安装Nginx
192.168.26.7:安装Nginx
虚拟ip(VIP):192.168.26.10,对外提供服务的ip,也可称作浮动ip
原理说明:
为了保证负载层足够稳定的状态下,适应更大的访问吞吐量还要应付可能的访问洪峰,我们加入了LVS技术。LVS负责第一层负载,然后再将访问请求转发到后端的若干台Nginx上。LVS的DR工作模式,只是将请求转到后端,后端的Nginx服务器必须有一个外网IP,在收到请求并处理完成后,Nginx将直接发送结果到请求方,不会再经LVS回发
原理图:
注意点:
- 有了上层的LVS的支撑Nginx就不再需要使用Keepalived作为热备方案。因为首先Nginx不再是单个节点进行负载处理,而是一个集群多台Nginx节点;另外LVS对于下后端的服务器自带基于端口的健康检查功能;
- LVS是单节点处理的,虽然LVS是非常稳定的,但是为了保证LVS更稳定的工作,我们还是需要使用Keepalived为 LVS做一个热备节点,以防不时之需。
2、nginx安装与配置
需要安装: 192.168.26.6 192.168.26.7
2.1 配置nginx的yum源
第一步:配置yum源
#两台机器同时操作
[root@Num26-7 ~]# vi /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
#缓存清理机创建
[root@Num26-7 ~]# yum clean all
[root@Num26-7 ~]# yum makecache
[root@Num26-7 ~]# yum repolist
2.2 yum安装nginx并修改配置文件
第二步:yum安装nginx并修改配置文件
#yum安装
[root@Num26-7 ~]# yum -y install nginx
[root@Num26-7 ~]# systemctl start nginx
#修改默认监听端口和服务名称
[root@Num26-7 ~]# cd /etc/nginx/conf.d/
[root@Num26-7 conf.d]# vi default.conf
server {
listen 8080;
server_name www.b.com;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
...
}
- 修改默认页面
#
[root@Num26-7 conf.d]# vi /usr/share/nginx/html/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx! This is 192.168.26.7</h1>
</body>
</html>
- 重启nginx
[root@Num26-6 conf.d]# systemctl restart nginx
#配置域名解析
[root@Num26-7 conf.d]# vi /etc/hosts
192.168.26.6 www.a.com
192.168.26.7 www.b.com
2.3 访问测试
第三步:页面访问测试
- 访问地址1:www.a.com:8080
- 访问地址2:www.b.com:8080
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eEWK0V50-1618575073102)(C:\Users\hukanfa\AppData\Roaming\Typora\typora-user-images\image-20210414202854001.png)]
2.4 配置VIP
#192.168.26.6 192.168.26.7 上执行
[root@Num26-6 home]# cd /etc/sysconfig/network-scripts/
[root@Num26-6 network-scripts]# ls
ifcfg-ens33 ifcfg-lo ...
#虚拟ip的配置是在回环lo文件中复制一份出来配置
[root@Num26-6 network-scripts]# cp ifcfg-lo ifcfg-lo:1
[root@Num26-6 network-scripts]# vi ifcfg-lo:1
DEVICE=lo:1
IPADDR=192.168.26.10
NETMASK=255.255.255.255
NETWORK=127.0.0.0
# If you're having problems with gated making 127.0.0.0/8 a martian,
# you can change this to something else (255.255.255.255, for example)
BROADCAST=127.255.255.255
ONBOOT=yes
NAME=loopback
#刷新配置
[root@Num26-6 network-scripts]# ifup lo
#查看
[root@Num26-6 network-scripts]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 192.168.26.10/32 brd 192.168.26.10 scope global lo:1
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2.5 配置ARP
说明:就是请求指定给虚拟ip才处理,其他地址不受影响。
arp_ignore:响应级别 选用 1
-
0 :表示只要本机配置了ip就能响应请求
-
1 :表示请求的目标地址到达了对应的网络接口,才会相应请求
说明:返回响应的网络接口通过行为限制
arp_announce:通告行为 选用 2
- 0 :本机上任何网络接口都向外通告,所有的网卡都能接收到通告
- 1 :尽可能避免本网卡与不匹配的目标进行通告
- 2 :只在本网卡通告
以上选项配置如下
#192.168.26.6 192.168.26.7 上执行
[root@Num26-6 home]# vi /etc/sysctl.conf
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
#刷新生效
[root@Num26-6 home]# sysctl -p
- 添加路由
#接收数据报文,会交给lo:1网卡进行处理
[root@Num26-6 home]# route add -host 192.168.26.10 dev lo:1
#查看
[root@Num26-6 home]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.26.1 0.0.0.0 UG 100 0 0 ens33
192.168.26.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
192.168.26.10 0.0.0.0 255.255.255.255 UH 0 0 0 lo
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
#添加到开机自启
[root@Num26-8 home]# echo "route add -host 192.168.26.10 dev lo:1" >> /etc/rc.local
[root@Num26-8 home]# cat /etc/rc.local
touch /var/lock/subsys/local
route add -host 192.168.26.10 dev lo:1
到这里配置完成
3、lvs安装与配置
实现LVS/DR最重要的两个东西是ipvs 内核 模块和ipvsadm工具包,现在的系统已经包含ip_vs模块 只要安装管理工具就行。
- 检查内核模块,看一下ip_vs 是否被加载
- 192.168.26.8 192.168.26.9 上执行
- 如果没有显示,则说明没有加载,执行命令 modprobe ip_vs 就可以把ip_vs模块加载到内核
[root@Num26-8 ipvsadm-1.26]# lsmod |grep ip_vs
[root@Num26-8 ipvsadm-1.26]# modprobe ip_vs
[root@Num26-8 ipvsadm-1.26]# lsmod |grep ip_vs
ip_vs 145497 0
- 链接内核目录
[root@Num26-8 ipvsadm-1.26]# ln -s /usr/src/kernels/3.10.0-957.el7.x86_64/ /usr/local/linux
[root@Num26-8 ipvsadm-1.26]# ll /usr/local/linux
lrwxrwxrwx 1 root root 39 Apr 14 06:29 /usr/local/linux -> /usr/src/kernels/3.10.0-957.el7.x86_64/
3.1 使用源码安装
第一步:源码包准备
#查看内核版本
[root@Num26-9 ~]# uname -r
3.10.0-957.el7.x86_64
#内核2.6及以上的下载
[root@Num26-9 ~]# cd /home/
[root@Num26-9 home]# mkdir software
[root@Num26-9 home]# cd software/
[root@Num26-9 software]# wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.26.tar.gz
#解压,编译,安装
[root@Num26-8 software]# tar -zxvf ipvsadm-1.26.tar.gz
[root@Num26-8 software]# cd ipvsadm-1.26/
- 执行make编译时发生报错如下
In file included from libipvs.h:13:0,
from libipvs.c:23:
ip_vs.h:15:29: fatal error: netlink/netlink.h: No such file or directory
#include <netlink/netlink.h>
- 解决方法如下
[root@Num26-8 ipvsadm-1.26]# yum -y install popt-static libnl-devel
#安装完成后再次执行编译安装
[root@Num26-8 ipvsadm-1.26]# make
[root@Num26-8 ipvsadm-1.26]# make install
make -C libipvs
make[1]: Entering directory `/home/software/ipvsadm-1.26/libipvs'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/home/software/ipvsadm-1.26/libipvs'
if [ ! -d /sbin ]; then mkdir -p /sbin; fi
install -m 0755 ipvsadm /sbin
install -m 0755 ipvsadm-save /sbin
install -m 0755 ipvsadm-restore /sbin
[ -d /usr/man/man8 ] || mkdir -p /usr/man/man8
install -m 0644 ipvsadm.8 /usr/man/man8
install -m 0644 ipvsadm-save.8 /usr/man/man8
install -m 0644 ipvsadm-restore.8 /usr/man/man8
[ -d /etc/rc.d/init.d ] || mkdir -p /etc/rc.d/init.d
install -m 0755 ipvsadm.sh /etc/rc.d/init.d/ipvsadm
- 检查以上编译安装是否成功
#检查lvs是否安装成功
[root@Num26-8 ipvsadm-1.26]# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
至此,lvs安装完成
4、keepalive安装与配置
4.1 使用源码安装
第一步:获取源码包,编译安装
#192.168.26.8 192.168.26.9 上执行
[root@Num26-8 software]# wget https://www.keepalived.org/software/keepalived-2.2.2.tar.gz
#安装opensll
[root@Num26-8 software]# yum -y install openssl-devel
#解压
[root@Num26-8 software]# tar -zxvf keepalived-2.2.2.tar.gz
[root@Num26-8 software]# cd keepalived-2.2.2/
[root@Num26-8 keepalived-2.2.2]# ./configure --prefix=/usr/local/keepalive
Keepalived configuration
------------------------
Keepalived version : 2.2.2
Compiler : gcc gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
Preprocessor flags : -D_GNU_SOURCE
...
Use IPVS Framework : Yes
IPVS use libnl : Yes
- 注意yes和no的值,如果一样,证明配置成功,如果lvs为no,那么证明你的lvs没有安装成功,需要从新安装lvs再安装keepalived
#编译安装
[root@Num26-8 keepalived-2.2.2]# make
[root@Num26-8 keepalived-2.2.2]# make install
4.2 修改配置文件
- 路径:/usr/local/keepalive/etc/keepaliv/keepalived.conf
- 以下是该配置文件讲解
! Configuration File for keepalived
global_defs {
#notification_email { #email 通知
#acassen@firewall.loc #设置报警邮件地址,可以设置多个,每行一个。
#failover@firewall.loc
#sysadmin@firewall.loc
#}
#notification_email_from Alexandre.Cassen@firewall.loc #设置邮件的发送地址
#smtp_server 192.168.200.1 #设置smtp server地址
#smtp_connect_timeout 30 #设置连接smtp server的超时时间
router_id LVS_DEVEL #表示运行keepalived服务器的一个标识。发邮件时显示在邮件主题的信息
#vrrp_skip_check_adv_addr
#vrrp_strict
#vrrp_garp_interval 0
#vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER #指定keepalived的角色,MASTER表示此主机是主服务器,BACKUP表示此主机是备用服务器
interface ens33 #网卡名,用ip addr命令可以查看
virtual_router_id 51 #虚拟路由标识,主备两个节点的设置必须一样,以指明各个节点属于同一VRRP组
priority 100 #定义优先级,数字越大,优先级越高,在同一个vrrp_instance下,MASTER的优先级必须大于BACKUP的优先级
advert_int 1 ##设定MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒
authentication { #设置验证类型和密码
auth_type PASS #设置验证类型,主要有PASS和AH两种
auth_pass 1111 #设置验证密码,在同一个vrrp_instance下,MASTER与BACKUP必须使用相同的密码才能正常通信
}
virtual_ipaddress { #设置vip
192.168.1.110 #可以多个虚拟IP,换行即可
}
}
virtual_server 192.168.1.110 80 { #设置虚拟服务器,需要指定虚拟IP地址和服务端口,端口和nginx的保持一致
delay_loop 6 ##健康时间检查,单位秒
lb_algo rr #负载均衡调度算法wlc|rr,和您将使用的LVS的调度算法保持原则一致
lb_kind DR #设置LVS实现负载均衡的机制,有NAT、TUN、DR三个模式可选
persistence_timeout 50 #会话保持时间,单位是秒。这个选项对动态网页是非常有用的,为集群系统中的session共享提供了一个很好的解决方案。
#有了这个会话保持功能,用户的请求会被一直分发到某个服务节点,直到超过这个会话的保持时间。
#需要注意的是,这个会话保持时间是最大无响应超时时间,也就是说,用户在操作动态页面时,如果50秒内没有执行任何操作
#那么接下来的操作会被分发到另外的节点,但是如果用户一直在操作动态页面,则不受50秒的时间限制
protocol TCP #指定转发协议类型,有TCP和UDP两种
real_server 192.168.1.127 80 { #真实服务器,此处为Nginx服务器
weight 1 #设置权重,数字越大权重越高
TCP_CHECK { #设置检查方式,可以设置HTTP_GET | SSL_GET
connect_timeout 3 #超时时间,秒。如果在这个时间内没有返回,则说明一次监测失败
nb_get_retry 3 #设置多少次监测失败,就认为这个真实节点死掉了
delay_before_retry 3 #重试间隔
}
}
real_server 192.168.1.128 80 { #真实服务器,此处为Nginx服务器
weight 1 #设置权重,数字越大权重越高
TCP_CHECK { #设置检查方式,可以设置HTTP_GET | SSL_GET | TCP_CHECK
connect_timeout 3 #超时时间,秒。如果在这个时间内没有返回,则说明一次监测失败
nb_get_retry 3 #设置多少次监测失败,就认为这个真实节点死掉了
delay_before_retry 3 #重试间隔
}
}
}
- 以下是正式的配置文件
! Configuration File for keepalived
global_defs {
#notification_email {
#acassen@firewall.loc
#failover@firewall.loc
#sysadmin@firewall.loc
#}
#notification_email_from Alexandre.Cassen@firewall.loc
#smtp_server 192.168.200.1
#smtp_connect_timeout 30
#192.168.26.8设置为8,192.168.26.9为9
router_id LVS_DEVEL_8
#vrrp_skip_check_adv_addr
#vrrp_strict
#vrrp_garp_interval 0
#vrrp_gna_interval 0
}
vrrp_instance VI_1 {
#192.168.26.8设置为master,192.168.26.9为backup
state MASTER
interface ens33
virtual_router_id 51
#192.168.26.8设置为100,192.168.26.9为99
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.26.10
}
}
virtual_server 192.168.26.10 8080 {
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 10
protocol TCP
real_server 192.168.26.6 8080 {
weight 1
TCP_CHECK{
connect_port 8080
connect_timeout 2
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.26.7 8080 {
weight 1
TCP_CHECK{
connect_port 8080
connect_timeout 2
nb_get_retry 3
delay_before_retry 3
}
}
}
4.3 配置keepalive服务
说明:因为keepalived安装时使用的是自己定义的安装目录,(这样方便卸载,如果默认安装失败后卸载很麻烦,这里建议自己指定安装目录)。Keepalived启动时默认是从/etc/keepalived/keepalived.conf读取我们的配置文件的,后面所有在/usr/local/keepalive/etc/keepalive/keepalived.conf下修改的东西都必须在/etc/keepalived/keepalived.conf这个目录修改,keepalived启动时读取的是默认的文件,而不是你修改的文件。当然也可以在keepalive安装目录下启动,不过有点麻烦
————————————————
- 配置操作如下
#
[root@Num26-8 home]# mkdir /etc/keepalived
[root@Num26-8 home]# ln -s /usr/local/keepalive/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf
[root@Num26-8 etc]# cp /usr/local/keepalive/sbin/keepalived /usr/sbin/
[root@Num26-8 sysconfig]# cp /usr/local/keepalive/etc/sysconfig/keepalived /etc/sysconfig/
- 编写开机启动脚本
#注意修改脚本中的相关路径
[root@Num26-8 home]# vi /etc/init.d/keepalived
#!/bin/sh
. /etc/rc.d/init.d/functions
exec="/usr/sbin/keepalived"
prog="keepalived"
config="/etc/keepalived/keepalived.conf"
[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
lockfile=/var/lock/subsys/keepalived
start() {
[ -x $exec ] || exit 5
[ -e $config ] || exit 6
echo -n $"Starting $prog: "
daemon $exec $KEEPALIVED_OPTIONS
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
stop
start
}
reload() {
echo -n $"Reloading $prog: "
killproc $prog -1
retval=$?
echo
return $retval
}
force_reload() {
restart
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status &>/dev/null
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
exit 2
esac
exit $?
- 脚本授权
#添加执行权限
[root@Num26-8 home]# chmod 755 /etc/init.d/keepalived
或者
chmod a+x /etc/init.d/keepalived
- 启动服务
[root@Num26-8 home]# systemctl start keepalived
[root@Num26-8 home]# systemctl status keepalived
● keepalived.service - LVS and VRRP High Availability Monitor
Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)
Active: active (running) since Wed 2021-04-14 18:53:52 PDT; 10s ago
Process: 17241 ExecStart=/usr/local/keepalive/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS)
Main PID: 17242 (keepalived)
Tasks: 3
CGroup: /system.slice/keepalived.service
├─17242 /usr/local/keepalive/sbin/keepalived -D
├─17243 /usr/local/keepalive/sbin/keepalived -D
└─17244 /usr/local/keepalive/sbin/keepalived -D
- 查看虚拟IP
#可以看到master节点上ens33网卡多了个虚拟ip,backup节点是没有的
[root@Num26-8 home]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 192.168.26.10/32 brd 192.168.26.10 scope global lo:1
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:af:09:5a brd ff:ff:ff:ff:ff:ff
inet 192.168.26.8/24 brd 192.168.26.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.26.10/32 scope global ens33
valid_lft forever preferred_lft forever
- 查看前面配置的负载均衡规则是否生效
#清除规则
ipvsadm -C
#查看规则
[root@Num26-8 home]# 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.26.10:8080 rr persistent 10
- 配置ipvs集群
#查看帮助信息
[root@Num26-8 ~]# ipvsadm -h
#创建集群
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask] [--pe persistence_engine]
[root@Num26-8 ~]# ipvsadm -A -t 192.168.26.10:8080 -s rr
#添加子节点到集群
ipvsadm -a|e -t|u|f service-address -r server-address [options]
[root@Num26-8 ~]# ipvsadm -a -t 192.168.26.10:8080 -r 192.168.26.6:8080 -g
[root@Num26-8 ~]# ipvsadm -a -t 192.168.26.10:8080 -r 192.168.26.7:8080 -g
[root@Num26-8 ~]# 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.26.10:8080 rr persistent 10
-> 192.168.26.6:8080 Route 1 0 0
-> 192.168.26.7:8080 Route 1 0
#设置tcp连接超时时间,便于测试
[root@Num26-8 keepalived]# ipvsadm --set 1 1 1
5、访问测试
测试内容如下
- 访问http://192.168.26.10:8080 是否有返回nginx的web页面,隔10秒后刷新是否有轮询
- 干掉一台nginx,再次验证第一步。之后重启nginx,再次验证第一步
- 干掉masterlvs(关闭keepalived),VIP是否有漂移,重启后是否正常获取到VIP
- 全部干掉lvs后,nginx是否还能正常访问