keepalived食用方法之负载均衡

上一期我说到了keepalived是干啥的,顺便举了两个例子来使用keepalived做高可用。但是keepalived也是可以LVS的负载均衡的,而且也不需要安装ipvsadm的专用接口包。然后顺便说一些其他使用技巧!

首先说说定义一个nat的负载均衡,当然还有dr模型。

定义keepalived同步组(nat负载均衡):

这是负载均衡的第一个实验和LVS-NAT一样。这个内容在公司很少用到,因为没有人将服务器作为NAT设备或者路由器…使用同步组的情况就是有两个网段,一个是外网地址一个内网地址,每个网段都开启一个VRRP实例,如果有一个网段出现问题时,VRRP master会认为自己是健康的,则不会发送Master和Backup的切换,从而导致问题,同步组可以把两个实例都放入一个组中,这样在组内的实例中任何一个实例出现问题都会发生切换。

接下来来看看在实战操作中如何配置。首先你需要两台虚拟机随后配置上两块网卡拥有两个网段,拓扑如下:

其中vrrp组的网络分别为:192.168.1.50和172.16.1.50。随后我们首先配置node1为master节点,随后后端代理选择两个主机安装httpd即可,网络分别为192.168.1.11 & 192.168.1.12。对了别忘了在配置之前首先配置网卡等基本信息!这个我就不展示了吧?

node1节点配置:

[root@localhost network-scripts] cd /etc/keepalived/
[root@localhost keepalived] vim keepalived.conf
! Configuration File for keepalived
global_defs {
 notification_email {
 root@localhost
 }
 notification_email_from keepalive@localhost
 smtp_server 127.0.0.1
 smtp_connect_timeout 30
 router_id LVS_DEVEL
}
vrrp_sync_group test { #这里我们定义一个同步组,名字叫test。注意:名字这种东西不要重名!
 group {
 test1
 test2
 }
}
vrrp_instance test1 { #定义test1 vrrp组
 state MASTER
 interface enp0s3
 virtual_router_id 16
 priority 100
 advert_int 1
 authentication {
 auth_type PASS
 auth_pass 075bf718
 }
 virtual_ipaddress {
 172.16.1.50/24 dev enp0s3
 }
}

vrrp_instance test2 { #定义test2 vrrp组
 state MASTER
 interface enp0s8
 virtual_router_id 16
 priority 100
 authentication {
 auth_type PASS
 auth_pass 075bf718
 }
 virtual_ipaddress {
 192.168.1.50/24 dev enp0s8
 }
}

virtual_server 172.16.1.50 80 { #定义一个反向代理
 delay_loop 6 #健康状态检测信息
 lb_algo rr #使用rr算法进行轮询
 lb_kind NAT #使用NAT模式
 nat_mask 255.255.255.0 #网络掩码
 persistence_timeout 50 #设置绘画会话保持时间
 protocol TCP #反向代理使用的协议
 real_server 192.168.1.11 80 { #后端node1主机
 weight 1 #权重
 TCP_CHECK { #使用tcp算法检测
 connect_timeout 3  #超时时间
 }
 }
 real_server 192.168.1.12 80 { #后端node2主机
 weight 1
 TCP_CHECK {
 connect_timeout 3
 }
 }
}

随后我们配置node2从节点的配置:

[root@localhost network-scripts] vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
 notification_email {
 root@localhost
 }
 notification_email_from keepalive@localhost
 smtp_server 127.0.0.1
 smtp_connect_timeout 30
 router_id LVS_DEVEL
}
vrrp_sync_group test { #定义同步组其实一样
 group {
 test1
 test2
 }
}
vrrp_instance test1 { #这里改的东西和单主模型一样
 state BACKUP
 interface enp0s3
 virtual_router_id 16
 priority 99
 advert_int 1
 authentication {
 auth_type PASS
 auth_pass 075bf718
 }
 virtual_ipaddress {
 172.16.1.50/24 dev enp0s3
 }
}

vrrp_instance test2 { #这里改的东西和单主模型一样
 state BACKUP
 interface enp0s8
 virtual_router_id 16
 priority 99
 authentication {
 auth_type PASS
 auth_pass 075bf718
 }
 virtual_ipaddress {
 192.168.1.50/24 dev enp0s8
 }
}

virtual_server 172.16.1.50 80 { #定义一个反向代理和master一样
 delay_loop 6
 lb_algo rr
 lb_kind NAT
 nat_mask 255.255.255.0
 persistence_timeout 50
 protocol TCP
 real_server 192.168.1.11 80 { #后端node1主机
 weight 1
 TCP_CHECK {
 connect_timeout 3
 }
 }
 real_server 192.168.1.12 80 { #后端node2主机
 weight 1
 TCP_CHECK {
 connect_timeout 3
 }
 }
}

接下来我们需要配置后端主机让他们安装httpd并生成一个网页:

#首先我们需要修改网路,就拿192.168.1.11来说:
[root@localhost ~] cat /etc/sysconfig/network-scripts/ifcfg-eth0
#注意网关改为nat的内网地址这里是192.168.50.1
DEVICE=eth0
HWADDR=08:00:27:48:78:91
TYPE=Ethernet
UUID=4d0aab16-d51c-4138-81c0-65f7106890db
ONBOOT=yes
NM_CONTROLLED=no
BOOTPROTO=static
IPADDR=192.168.1.11
NETMASK=255.255.255.0
GATEWAY=192.168.1.50
DNS1=223.6.6.6
#当然对于另一台主机来说也是一样
#接下来全部安装httpd和添加一个index.html即可这个我就不说了!

好了我们启动两个节点看看情况,然后看看能不能反向代理?不知道怎么启动?看上一篇

[root@localhost keepalived] curl 172.16.1.50
welcome to 192.168.1.12 real-server 2

随后看看还我的真机看看效果:

注意:我这边真机是使用的端口映射才能访问nat里面的虚拟机所以大家可别输入127.0.0.1如果是桥接的直接输入正确地址即可!

关于keepalived同步组就到这里结束了,测试大家可以自己下行测试。因为NAT模型在实战中极少使用(我至今没用过只是在虚拟机测试过)并且网上资料也少所以我就先把它贴出来了!

关于keepalived之中定义脚本

有没有想过一个问题,keepalived好像没有手动下线的功能!如果我要对有Keepalived的主机进行硬件扩容或者应用升级要临时将keepalived下线并且改造完毕以后上线能让它恢复master地位那该怎么做?所以这里我们就需要自定义脚本给keepalived执行,当然在keepalived使用脚本还可以检测应用程序是否工作不正常?如果出现意外也能即使切换Keepalived的主从关系,因为Keepalived的缺陷就是应用出现问题时是不会切换主从关系的。

说了这么多首先我们通过写一个简单脚本让keepalived能够手动让keepalived下线,实验还是老样子两台主机做一个简单的单主模型随后我们添加一个非常小的脚本随后在一个vrrp实例中将脚本应用即可!

首先在master(172.16.1.10)中这样配置:

! Configuration File for keepalived
global_defs {
 notification_email {
 root@localhost
 }
 notification_email_from keepalive@localhost
 smtp_server 127.0.0.1
 smtp_connect_timeout 30
 router_id LVS_DEVEL
}

vrrp_script keepalived_down { #添加一个脚本叫做keepalived_down的脚本
 script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"
#检查/etc/keepalived/中有没有down文件
 interval 2 #每隔两秒执行文件
 weight -50 #如果有down文件则权重减50
}

vrrp_instance test1 {
 state MASTER
 interface enp0s3
 virtual_router_id 16
 priority 100
 advert_int 1
 track_interface {
 enp0s3
 }
 authentication {
 auth_type PASS
 auth_pass 075bf718
 }
 virtual_ipaddress {
 172.16.1.50/24 dev enp0s3
 }
 track_script { #调用某个脚本为实例所用
 keepalived_down #这里写上脚本名即可
 }
}

那么配置好主节点就行,从节点不用配置脚本我们只是看看脚本的效果而已。从节点(172.16.1.30)这样配置:

! Configuration File for keepalived
global_defs {
 notification_email {
 root@localhost
 }
 notification_email_from keepalive@localhost
 smtp_server 127.0.0.1
 smtp_connect_timeout 30
 router_id LVS_DEVEL
}

vrrp_instance test1 {
 state BACKUP
 interface enp0s3
 virtual_router_id 16
 priority 99
 advert_int 1
 track_interface {
 enp0s3
 }
 authentication {
 auth_type PASS
 auth_pass 075bf718
 }
 virtual_ipaddress {
 172.16.1.50/24 dev enp0s3
 }
}

接下来我们启动keepalived服务并且看看测试结果:

[root@localhost ~] systemctl start keepalived #主从都得启动服务
[root@localhost ~] ip addr show #master节点
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
 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
 inet6 ::1/128 scope host
 valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
 link/ether 08:00:27:ac:9d:0e brd ff:ff:ff:ff:ff:ff
 inet 172.16.1.10/24 brd 172.16.1.255 scope global enp0s3
 valid_lft forever preferred_lft forever
 inet 172.16.1.50/24 scope global secondary enp0s3
 valid_lft forever preferred_lft forever
 inet6 fe80::a00:27ff:feac:9d0e/64 scope link
 valid_lft forever preferred_lft forever
[root@localhost ~] ip addr show #backup节点
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
 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
 inet6 ::1/128 scope host
 valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
 link/ether 08:00:27:d4:d3:0d brd ff:ff:ff:ff:ff:ff
 inet 172.16.1.30/24 brd 172.16.1.255 scope global enp0s3
 valid_lft forever preferred_lft forever
 inet6 fe80::a00:27ff:fed4:d30d/64 scope link
 valid_lft forever preferred_lft forever
#随后我在/etc/keepalived/中touch一个down文件看看变化:
[root@localhost ~] touch /etc/keepalived/down
[root@localhost keepalived] ip addr show #现在看看master节点是不是virtual ip没有了?
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
 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
 inet6 ::1/128 scope host
 valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
 link/ether 08:00:27:ac:9d:0e brd ff:ff:ff:ff:ff:ff
 inet 172.16.1.10/24 brd 172.16.1.255 scope global enp0s3
 valid_lft forever preferred_lft forever
 inet6 fe80::a00:27ff:feac:9d0e/64 scope link
 valid_lft forever preferred_lft forever
[root@localhost ~] ip addr show #现在看看backup节点是不是将权限拿来了?
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
 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
 inet6 ::1/128 scope host
 valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
 link/ether 08:00:27:d4:d3:0d brd ff:ff:ff:ff:ff:ff
 inet 172.16.1.30/24 brd 172.16.1.255 scope global enp0s3
 valid_lft forever preferred_lft forever
 inet 172.16.1.50/24 scope global secondary enp0s3
 valid_lft forever preferred_lft forever
 inet6 fe80::a00:27ff:fed4:d30d/64 scope link
 valid_lft forever preferred_lft forever

关于小脚本的实验就说到这里了不进行拓展,如果想要让master上线可以删除down文件就能手动上线。其实也可以将脚本写成一个文件里面,随后使用script “/PATH/FOR/FILE”调用脚本然后写上执行间隔和结果。这样做的好处就是能够写上复杂脚本检测跑在keepalived上的应用的情况如果发生应用停止无法启动就立刻切换主从关系。

关于keepalived定义日志存储在指定地点

在默认的情况下keepalived在vrrp组内切换virtual ip地址都会写入日志但是默认都会写在/var/log/messages之中,这可不是我们理想的状态由于massages日志使用频率较大可能我们会错过keepalived的消息从而无法排错。那么如何将keepalived的日志消息单独拿出来放到一个指定的文件中呢?其实是有办法的不过得修改rsyslog的配置文件。

首先我们找到/etc/sysconfig/keepalived的配置文件将其打开:

[root@localhost keepalived] vim /etc/sysconfig/keepalived
# Options for keepalived. See `keepalived --help' output and keepalived(8) and
# keepalived.conf(5) man pages for a list of all options. Here are the most
# common ones :
#
# --vrrp -P Only run with VRRP subsystem.
# --check -C Only run with Health-checker subsystem.
# --dont-release-vrrp -V Dont remove VRRP VIPs & VROUTEs on daemon stop.
# --dont-release-ipvs -I Dont remove IPVS topology on daemon stop.
# --dump-conf -d Dump the configuration data.
# --log-detail -D Detailed log messages.
# --log-facility -S 0-7 Set local syslog facility (default=LOG_DAEMON)
#

KEEPALIVED_OPTIONS="-f /etc/keepalived/keepalived.conf -D -S 0"

在这里我得讲解一下在默认情况下只有-D选项所以保存的位置只有/var/log/messages之中了。-D表示记录详细信息那么我后来加的-f表示指明配置文件所在位置(可选)。最重要的就是添加-S选项意思就是使用0-7表示添加rsyslog的设备的占有模块位(稍后的演示你就明白了)。然后-P -C等选项上面其实都写明了自己看就行记得写在””号之内!

随后我们配置rsyslog.conf配置文件:

[root@localhost keepalived] vim /etc/rsyslog.conf
#打开之后找到这段话:
# Save boot messages also to boot.log #这里不用看是说保存boot信息日志的地方
local7.* /var/log/boot.log
local0.* /var/log/keepalived.log 
#上面的local0.*是我们在keepalived中定义的-S 0表示使用0号模块。
#由于7被boot信息日志占用了所以我使用了0随后写好保存的位置即可。
#如果想要日志生效别忘了重启rsyslog应用
[root@localhost keepalived] systemctl restart rsyslog

好了这样我们就把日志定义到我们指定的地点,想要看日志?也千万别忘了重启keepalived这样文件就生成了。

定义keepalived负载均衡(dr模型)

总算说到文章的重点…不过其实也不是重点在很多企业中使用lvs的概率并不大不过使用haproxy或者nginx作为负载均衡器的概率是极大的。不过我还是得讲讲因为这个比nat模型有用多了!

首先看看我设计的拓扑:

其实就是在lvs博客中讲过的拓扑只是在lvs设备中添加一个keepalived让其高可用而已。

首先我来设置一下后端的real server还记得在LVS-DR模型中需要修改arp参数吗?

[root@localhost ~] echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@localhost ~] echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@localhost ~] echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@localhost ~] echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
#上面的修改arp内核参数与之前lvs一样
[root@localhost ~] ip addr add 172.16.1.50/32 broadcast 172.16.1.50 dev lo
[root@localhost ~] ip route add 172.16.1.50/32 dev lo
#这里添加环回地址的时候记得是virtual ip千万不是某个keepalived主机的地址!
[root@localhost ~] yum install httpd #安装httpd
[root@localhost html] vi /var/www/html/index.html #编辑一个网页文件用于检测
welcome to 172.16.1.11 real-server 1

配置好后端主机之后我们来配置keepalived 的master节点:

! Configuration File for keepalived
global_defs {
 notification_email {
 root@localhost
 }
 notification_email_from keepalived@localhost
 smtp_connect_timeout 30
 smtp_server 127.0.0.1
 router_id LVS_DEVEL
}

vrrp_instance test1 {
 interface enp0s3
 state MASTER
 priority 100
 virtual_router_id 10
 garp_master_delay 1

 authentication {
 auth_type PASS
 auth_pass fa3d9824
 }
 track_interface {
 enp0s3
 }
 virtual_ipaddress {
 172.16.1.50 dev enp0s3
 }
}

virtual_server 172.16.1.50 80 {
 delay_loop 6
 lb_algo rr #使用轮询
 lb_kind DR #与nat不同这边改为DR模型
 nat_mask 255.255.255.0
 persistence_timeout 50
 protocol TCP
 real_server 172.16.1.11 80 { #后端主机
 weight 1
 HTTP_GET { #这边检测的方法改为curl获取的方式
 url {
 path / #获取主页为/
 status_code 200 #200的响应码表示成功
 }
 connect_timeout 3 #超时时间
 nb_get_retry #重试次数
 delay_before_retry 1 #重试间隔时间
 }
 }
 real_server 172.16.1.12 80 {
 weight 1
 HTTP_GET {
 url {
 path /
 status_code 200
 }
 connect_timeout 3
 nb_get_retry 3
 delay_before_retry 1
 }
 }
}

好了keepalived master已经配置完毕了,后面的backup节点只要修改两个选项就能搞定一个是state还有一个就是优先级priority。这我就不在进行啰嗦了。

现在我们启动keepalived 和 后端httpd看看能不能获取内容?

看来访问神马的没有任何问题,注意:我这边真机是使用的端口映射才能访问nat里面的虚拟机所以大家可别输入127.0.0.1如果是桥接的直接输入正确地址即可!


结语:

以上keepalived的基本内容就算说到这里了,今后有空我来更新一些脚本。keepalived在企业中是属于常用品种,由于简单的配置和小巧的应用非常理想。但是这个方案也是有问题的,比如:如果没有定义virtual server只有keepalived应用断开或者机器宕机才会发生主从转移,所以写脚本是必须要做的事情。还有就是邮件通知的问题,邮件通知必须要在服务器上安装邮件程序才能对外发送邮件(如果在OS内给不同用户发送则不需要但是这个没人会用吧?),当然如果是要发送短信首先得有短信网关然后还得写脚本调用短信网关进行通知。

Comments

Leave a Reply

Your email address will not be published. Name and email are required