一、haproxy 编译安装,并简述全局配置段各参数作用

编译安装

  • 脚本安装
#!/bin/bash

# 编译安装HAProxy



. /etc/init.d/functions

#HAproxy版本

HAProxy_version=haproxy-2.6.1

TAR=tar.gz

HAProxy=${HAProxy_version}.${TAR}



#HAProxy源码下载地址

HAProxy_url=http://www.haproxy.org/download/2.6/src/haproxy-2.6.1.tar.gz

# haproxy安装路径

HAProxy_install_DIR=/apps/haproxy



#lua版本

Lua_version=lua-5.3.5

TAR_lua=tar.gz

Lua=${Lua_version}.${TAR_lua}

#lua源码下载地址

Lua_url=http://www.lua.org/ftp/${Lua}





# CPU数量

CPUS=`lscpu|grep "^CPU(s)"|awk '{print $2}'`

# 系统类型

os_type=`grep "^NAME" /etc/os-release |awk -F'"| ' '{print $2}'`

# 系统版本号

os_version=`awk -F'"' '/^VERSION_ID/{print $2}' /etc/os-release`



color () {

if [[ $2 -eq 0 ]];then

echo -e "\e[1;32m$1\t\t\t\t\t\t[ OK ]\e[0;m"

else

echo $2

echo -e "\e[1;31m$1\t\t\t\t\t\t[ FAILED ]\e[0;m"

fi

}



download_lua (){

cd /opt

if [ -e ${Lua} ];then

color "lua安装包已存在" 0

else

color "开始下载lua安装包" 0

wget ${Lua_url}

if [ $? -ne 0 ];then

color "下载lua安装包失败,退出!" 1

exit 1

fi



fi

}



download_haproxy (){

cd /opt

if [ -e ${HAProxy} ];then

color "haproxy安装包已存在" 0

else

color "开始下载haproxy安装包" 0

wget ${HAProxy_url}

if [ $? -ne 0 ];then

color "下载haproxy安装包失败,退出!" 1

exit 1

fi

fi

}



update_lua (){

# 安装依赖包

yum -y install gcc readline-devel



# 解压源码包

tar -xvf /opt/${Lua} -C /usr/local/src

ln -s /usr/local/src/${Lua_version} /usr/local/src/lua



# 编译安装

cd /usr/local/src/lua

make linux test

}



install_haproxy (){

# 安装依赖包

yum -y install gcc openssl-devel pcre-devel systemd-devel



# 解压源码包

tar xvf /opt/${HAProxy} -C /usr/local/src

ln -s /usr/local/src/${HAProxy_version} /usr/local/src/haproxy



# 编译安装

cd /usr/local/src/haproxy

make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 \

USE_SYSTEMD=1 USE_LUA=1 LUA_INC=/usr/local/src/lua/src/ LUA_LIB=/usr/local/src/lua/src/

make install PREFIX=${HAProxy_install_DIR}

ln -s ${HAProxy_install_DIR}/sbin/haproxy /usr/sbin/



# 准备服务启动配置文件

## 添加用户

useradd -r -s /sbin/nologin -d /var/lib/haproxy haproxy

mkdir -p /etc/haproxy

mkdir -p /var/lib/haproxy

## 准备service服务

cat > /usr/lib/systemd/system/haproxy.service <<EOF

[Unit]

Description=HAProxy Load Balancer

After=syslog.target network.target



[Service]

ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q

ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid

ExecReload=/bin/kill -USR2 $MAINPID

LimitNOFILE=100000



[Install]

WantedBy=multi-user.target

EOF



###准备haproxy配置文件

cat > /etc/haproxy/haproxy.cfg <<EOF

global

maxconn 100000

chroot ${HAProxy_install_DIR}

stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin

#uid 99

#gid 99

user haproxy

group haproxy

daemon

#nbproc 4

#cpu-map 1 0

#cpu-map 2 1

#cpu-map 3 2

#cpu-map 4 3

pidfile /var/lib/haproxy/haproxy.pid

log 127.0.0.1 local2 info



defaults

option http-keep-alive

option forwardfor

maxconn 100000

mode http

timeout connect 300000ms

timeout client 300000ms

timeout server 300000ms



listen stats

mode http

bind 0.0.0.0:9999

stats enable

log global

stats uri /haproxy-status

stats auth haadmin:123456



listen web_port

bind 0.0.0.0:80

mode http

log global

server web1 127.0.0.1:8080 check inter 3000 fall 2 rise 5

EOF



systemctl daemon-reload

systemctl enable --now haproxy

systemctl is-active haproxy



if [ $? -ne 0 ];then

color "haproxy服务启动失败!" 1

exit 1

else

color "haproxy服务启动成功" 0

fi

}



download_lua



download_haproxy



update_lua



install_haproxy



exit 0
  • 查看状态

说明:haproxy加载子配置文件方法

haproxy本身是不支持在haproxy.cfg中通过include方式添加子配置文件的,可通过在service中添加目录方式加载子配置文件,示例如下:

# cat /lib/systemd/system/haproxy.service 

[Unit]

Descriptinotallow=HAProxy Load Balancer

After=syslog.target network.target



[Service]

#下面两行添加子配置文件路径/etc/haproxy/conf.d/

ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -c -q

ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -p /var/lib/haproxy/haproxy.pid

ExecReload=/bin/kill -USR2 $MAINPID

LimitNOFILE=100000



[Install]

WantedBy=multi-user.target

global全局配置参数

chroot  #锁定运行目录

deamon #以守护进程运行

stats socket /var/ lib/haproxy/haproxy.sock mode 600 leveladmin #socket文件

user, group,uid, gid #运行haproxy的用户身份

nbproc 1 #开启的haproxy进程数,与CPU保持一致

nbthread 1 #指定每个haproxy进程开启的线程数,默认为每个进程一个线程

cpu-map 1 0 #绑定haproxy worker进程至指定CPU,将第1个work进程绑定至0号CPU,单进程多线程和多进程单线程不能并存。

maxconn #每个haproxy进程的最大并发连接数

maxsslconn #每个haproxy进程ssl最大连接数,用于haproxy配置了证书的场景下

maxconnrate #每个进程每秒创建的最大连接数量

spread-checks #后端server状态check随机提前或延迟百分比时间,建议2-5(20%-50%)之间

pidfile #指定pid文件路径

log 127.0.0.1 local3 info #定义全局的syslog服务器;最多可以定义两个

proxies代理配置

defaults [<name>] #默认配置项,针对以下的frontend、backend和listen生效,可以多个name也可以没有name

frontend <name> #前端servername,类似于Nginx的一个虚拟主机 server和LVS服务集群。

backend <name> #后端服务器组,等于nginx的upstream和LVS中的RS服务器

listen <name> #将frontend和backend合并在一起配置,相对于frontend和backend配置更简洁,生产常用

注意:name字段只能使用大小写字母,数字,‘-’,‘_’,‘.’和 ‘:’,并且严格区分大小写。

  • defaults配置参数
option redispatch #当server Id对应的服务器挂掉后,强制定向到其他健康的服务器,重新派发

option abortonclose #当服务器负载很高时,自动结束掉当前队列处理比较久的连接,针对业务情况选择开启

option http-keep-alive #开启与客户端的会话保持

option forwardfor #透传客户端真实IP至后端web服务器

mode http|tcp #设置默认工作类型,使用TCP服务器性能更好,减少压力

timeout http-keep-alive 120s #session 会话保持超时时间,此时间段内会转发到相同的后端服务器

timeout connect 120s #客户端请求从haproxy到后端server最长连接等待时间(TCP连接之前),默认单位ms

timeout server 600s #客户端请求从haproxy到后端服务端的请求处理超时时长(TCP连接之后),默认单位ms,

#如果超时,会出现502错误,此值建议设置较大些,访止502错误

timeout client 600s #设置haproxy与客户端的最长非活动时间,默认单位ms,建议和timeout server相同

timeout check 5s #对后端服务器的默认检测超时时间

default-server inter 1000 weight 3 #指定后端服务器的默认设置
  • listen配置参数
    范例
listen WEB_PORT_80 

bind 10.0.0.7:80

mode http

option forwardfor

server web1 10.0.0.17:8080 check inter 3000 fall 3 rise 5

server web2 10.0.0.27:8080 check inter 3000 fall 3 rise 5
  • bind
#监听http的多个IP的多个端口和sock文件

listen http_proxy

#指定HAProxy的监听地址,可以是IPV4或IPV6,可以同时监听多个IP或端口,可同时用于listen字段中

bind :80,:443,:8801-8810

#注意:如果需要绑定在非本机的IP,需要开启内核参数:net.ipv4.ip_nonlocal_bind=1

bind 10.0.0.1:10080,10.0.0.1:10443

bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy



#https监听

listen http_https_proxy

bind :80

#公钥和私钥公共文件

bind :443 ssl crt /etc/haproxy/site.pem



#监听ipv6、ipv4和unix sock文件

listen http_https_proxy_explicit

bind ipv6@:80

bind ipv4@public_ssl:443 ssl crt /etc/haproxy/site.pem

bind unix@ssl-frontend.sock user root mode 600 accept-proxy



#监听file descriptor

listen external_bind_app1

bind "fd@${FD_APP1}"
  • mode
mode http|tcp #指定负载协议类型
  • option

配置选项,option后面加 httpchk,smtpchk,mysql-check,pgsql-check,ssl-hello-chk方法,可用于实现更多应用层检测功能。

  • server

定义后端real server

check #对指定real进行健康状态检查.如果不加此设置,默认不开启检查,只有check后面没有其它配置也可以启用检查功能

#默认对相应的后端服务器IP和端口,利用TCP连接进行周期性健康性检查,注意必须指定端口才能实现健康性检查

addr <IP> #可指定的健康状态监测IP,可以是专门的数据网段,减少业务网络的流量

port <num> #指定的健康状态监测端口

inter <num> #健康状态检查间隔时间,默认2000 ms

fall <num> #后端服务器从线上转为线下的检查的连续失效次数,默认为3

rise <num> #后端服务器从下线恢复上线的检查的连续有效次数,默认为2

weight <weight> #默认为1,最大值为256,0(状态为蓝色)表示不参与负载均衡,但仍接受持久连接

backup #将后端服务器标记为备份状态,只在所有非备份主机down机时提供服务,类似Sorry Server

disabled #将后端服务器标记为不可用状态,即维护状态,除了持久模式,将不再接受连接,状态为深黄色,

#优雅下线,不再接受新用户的请求

redirect prefix http://www.baidu.com/ #将请求临时(302)重定向至其它URL,只适用于http模式

redir http://www.baidu.com #将请求临时(302)重定向至其它URL,只适用于http模式

maxconn <maxconn> #当前后端server的最大并发连接数

二、使用haproxy作为代理服务器,后端两台nginx来提供web服务进行测试。

架构




haproxy
10.0.0.7

web1
10.0.0.17

web2
10.0.0.27

client

  1. 配置haproxy(10.0.0.7)
  • 修改haproxy.cfg配置文件
[root@haproxy haproxy]# vim /etc/haproxy/haproxy.cfg 

......

listen web_port

bind 0.0.0.0:80

mode http

log global

server web1 10.0.0.17:80 check inter 3s fall 3 rise 5

server web2 10.0.0.27:80 check inter 3s fall 3 rise 5
  • 重启服务

​systemctl restart haproxy​

  1. 配置web1(10.0.0.17)
  • 安装nginx

​yum install nginx -y​

  • 准备网页
echo "web1 `hostname -I`" > /usr/share/nginx/html/index.html
  • 启动服务

​systemctl start nginx​

  1. 配置web2(10.0.0.27)
  • 安装nginx

​yum install nginx -y​

  • 准备网页
echo "web2 `hostname -I`" > /usr/share/nginx/html/index.html
  • 启动服务

​systemctl start nginx​

  1. 验证

Haproxy&Keepalived实现高可用_haproxy

Haproxy&Keepalived实现高可用_keepalived_02

三、简述haproxy调度算法,并搭建监控页面。

haproxy调度算法

1. 静态算法

按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(只能为0和1,不支持其它值),只能靠重启HAProxy生效。

  1. static-rr
    基于权重的轮询调度,不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其他值)及后端服务器慢启动,其后端主机数量没有限制,相当于LVS中的wrr。
    配置示例
listen web_host

bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010

mode http

log global

balance static-rr

server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

server web2 10.0.0.27:80 weight 2 check inter 3000 fall 2 rise 5
  1. first
    根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置,此方式使用较少。
    不支持使用socat进行动态修改权重,可以设置0和1,可以设置其他值但无效
    配置示例
listen web_host

bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010

mode http

log global

balance first

server web1 10.0.0.17:80 maxconn 2 weight 1 check inter 3000 fall 2 rise 5

server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

2. 动态算法

基于后端服务器状态进行调度适当调整,新请求将优先调度至当前负载较低的服务器,且权重可以在haproxy运行时动态调整无需重启。

  1. roundronbin
    基于权重的轮询动态调度算法,支持权重的运行时调整,不同于lvs中的rr轮询模式,HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),其每个后端backend中对多支持4095个real server,支持对real server权重动态调整,roundrobin为默认调度算法,此算法使用广泛。
    配置示例
listen web_host

bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010

mode http

log global

balance roundrobin

server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

server web2 10.0.0.27:80 weight 2 check inter 3000 fall 2 rise 5

支持动态调整权重

# echo "get weight web_host/web1" | socat stdio /var/lib/haproxy/haproxy.sock 

1 (initial 1)



# echo "set weight web_host/web1 3" | socat stdio /var/lib/haproxy/haproxy.sock



# echo "get weight web_host/web1" | socat stdio /var/lib/haproxy/haproxy.sock

3 (initial 1)
  1. leastconn
    加权的最少连接的动态,支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接),比较适合长连接的场景使用,比如:MySQL等场景。
    配置示例
listen web_host

bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010

mode http

log global

balance leastconn

server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5
  1. random
    在1.9版本开始增加 random的负载平衡算法,其基于随机数作为一致性hash的key,随机负载平衡对于大型服务器场或经常添加或删除服务器非常有用,支持weight的动态调整,weight较大的主机有更大概率获取新请求。
    配置示例
listen web_host

bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010

mode http

log global

balance random

server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

3. 其他算法

即可作为静态算法,又可以通过选项成为动态算法

1)souce

源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端web服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type支持的选项更改。

这个算法一般是在不插入Cookie的TCP模式下使用,也可给拒绝会话cookie的客户提供最好的会话粘性,适用于session会话保持但不支持cookie和缓存的场景。

源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash。

  1. map-based取模法
    取模法,对source即源地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度。缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变,hash-type 指定的默认值为此算法
map-based算法:基于权重取模,hash(source_ip)%所有后端服务器相加的总权重

配置示例

listen web_host

bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010

mode tcp

log global

balance source

hash-type map-based

server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 3

server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 3



#不支持动态调整权重值

[root@haproxy ~]#echo "set weight web_host/10.0.0.27 10" | socat stdio /var/lib/haproxy/haproxy.sock

Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.



#只能动态上线和下线

[root@haproxy ~]#echo "set weight web_host/10.0.0.27 0" | socat stdio /var/lib/haproxy/haproxy.sock

[root@haproxy conf.d]#echo "get weight web_host/10.0.0.27" | socat stdio /var/lib/haproxy/haproxy.sock

0 (initial 1)
  1. 一致性hash
    一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动,hash(o)mod n ,该hash算法是动态的,支持使用 socat等工具进行在线权重调整,支持慢启动。
    算法:
1、key1=hash(source_ip)%(2^32) [0---4294967295]

2、keyA=hash(后端服务器虚拟ip)%(2^32)

3、将key1和keyA都放在hash环上,将用户请求调度到离key1最近的keyA对应的后端服务器

hash环偏斜问题

增加虚拟服务器IP数量,比如:一个后端服务器根据权重为1生成1000个虚拟IP,再hash。而后端服务器权重为2则生成2000的虚拟IP,再bash,

最终在hash环上生成3000个节点,从而解决hash环偏斜问题。

配置示例

listen web_host

bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010

mode tcp

log global

balance source

hash-type consistent

server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5
2)uri

基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后,根据最终结果将请求转发到后端指定服务器,适用于后端是缓存服务器场景,默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash。

注意:此算法基于应用层,所以只支持 mode http ,不支持 mode tcp

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>

左半部分:/<path>;<params>

整个uri:/<path>;<params>?<query>#<frag>

Haproxy&Keepalived实现高可用_haproxy_03

uri取模法配置示例

listen web_host

bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010

mode http

log global

balance uri

server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

uri 一致性hash配置示例

listen web_host

bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010

mode http

log global

balance uri

hash-type consistent

server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5
3)url_param

url_param对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server,如果无没key,将按roundrobin算法。

# 假设:

url = http://www.magedu.com/foo/bar/index.php?key=value



# 则:

host = "www.magedu.com"

url_param = "key=value"

取模法配置示例

listen web_host

bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010

mode http

log global

balance url_param userid #url_param hash

server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

一致性hash配置示例

listen web_host

bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010

mode http

log global

balance url_param userid #对url_param的值取hash

hash-type consistent

server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5
4)hdr

针对用户每个http头部(header)请求中的指定信息做hash,此处由name指定的http首部将会被取出并做hash计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。

取模法配置示例

listen web_host

bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010

mode http

log global

balance hdr(User-Agent)

#balance hdr(host)



server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

一致性hash配置示例

listen web_host

bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010

mode http

log global

balance hdr(User-Agent)

hash-type consistent

server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5
5)rdp-cookie

rdp-cookie对远windows远程桌面的负载,使用cookie保持会话,默认是静态,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash。

取模法配置示例

listen RDP

bind 10.0.0.7:3389

balance rdp-cookie

mode tcp

server rdp0 10.0.0.17:3389 check fall 3 rise 5 inter 2000 weight 1

一致性hash配置示例

listen magedu_RDP_3389

bind 172.16.0.100:3389

balance rdp-cookie

hash-type consistent

mode tcp

server rdp0 10.0.0.200:3389 check fall 3 rise 5 inter 2000 weight 1

注意:基于iptables实现RDP协议转发,必须开启ip转发功能: net.ipv4.ip_forward = 1。

4. 算法总结

#静态

static-rr--------->tcp/http

first------------->tcp/http



#动态

roundrobin-------->tcp/http

leastconn--------->tcp/http

random------------>tcp/http



#以下静态和动态取决于hash_type是否consistent

source------------>tcp/http

Uri--------------->http

url_param--------->http

hdr--------------->http

rdp-cookie-------->tcp

5. 适用场景

static-rr     #做session共享的web集群

first #使用较少



roundrobin #默认调度算法

leastconn #数据库

random #对于大型服务器场或经常添加或删除服务器非常有用



source #基于客户端公网IP的会话保持



Uri #缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯

url_param #可以实现session保持



hdr #基于客户端请求报文头部做下一步处理

rdp-cookie #基于Windows主机,很少使用

搭建监控页面

  1. 修改haproxy配置文件
[root@haproxy haproxy]# vim /etc/haproxy/haproxy.cfg 

.....

#添加如下status信息

listen stats

mode http

bind 0.0.0.0:9999

stats enable

log global

stats uri /haproxy-status

stats auth haadmin:123456
  1. 访问http://10.0.0.7:9999/haproxy-status监控网页

用户名:haadmin,密码:123456

Haproxy&Keepalived实现高可用_haproxy_04

  1. 进入监控首页

Haproxy&Keepalived实现高可用_haproxy_05

四、基于haproxy,实现网页动静分离。

架构




haproxy
10.0.0.7

static-web
10.0.0.17

dynamic-web
10.0.0.27

client

  1. 配置haproxy(10.0.0.7)
  • 修改haproxy配置
[root@haproxy haproxy]# cat /etc/haproxy/haproxy.cfg 

.....

#添加如下内容

frontend http_port

bind 10.0.0.7:80

mode http

log global

balance roundrobin

option httplog





########acl setting#############

acl acl_static path_end -i .jpg .jpeg .png .gif .css .js

acl acl_dynamic path_end -i .php



#######acl hosts####################

use_backend static_hosts if acl_static

use_backend dynamic_hosts if acl_dynamic

default_backend default_hosts





#静态服务器

backend static_hosts

mode http

server web1 10.0.0.17:80 check inter 3s fall 3 rise 5



#动态服务器

backend dynamic_hosts

mode http

server web2 10.0.0.27:80 check inter 3s fall 3 rise 5



#默认服务器

backend default_hosts

mode http

server web 10.0.0.7:8080 check inter 3s fall 3 rise 5
  • 重启服务
    ​systemctl restart haproxy​
  1. 配置静态服务器static-hosts(10.0.0.17)
    将图片1.jpg上传至/usr/share/nginx/html目录下
[root@web1 html]# ls

1.jpg 404.html 50x.html en-US icons img index.html nginx-logo.png poweredby.png
  1. 配置动态服务器dynamic-hosts(10.0.0.27)
    准备php文件
#cat /usr/share/nginx/html/test.php

<?php

<h1> dynamic-hosts 10.0.0.27</h1>;

?>
  1. 配置默认服务器default-hosts(10.0.0.7)
  • 安装nginx
  • 修改监听端口为8080
server {

listen 8080;

listen [::]:8080;

......

}
  • 准备默认网页
[root@haproxy haproxy]# echo "nginx `hostname -I`" > /usr/share/nginx/html/index.html
  • 重启服务
    ​systemctl restart nginx​
  1. 实现动静分离
  • 查看jpg图片时,调度至static-hosts(10.0.0.17)

Haproxy&Keepalived实现高可用_haproxy_06

  • 查看test.php时,调度至dynamic-hosts(10.0.0.27)

Haproxy&Keepalived实现高可用_haproxy_07

test.php内容

Haproxy&Keepalived实现高可用_haproxy_08

  • 查看其他类型页面时,调度至default-host(10.0.0.7)

Haproxy&Keepalived实现高可用_keepalived_09

五、使用haproxy,实现https。

架构

https

http

http

haproxy
10.0.0.7

web1
10.0.0.17

web2
10.0.0.27

client

haproxy配置(10.0.0.7)

  • 制作证书
mkdir -p /etc/haproxy/ssl

cd /etc/haproxy/ssl

openssl req -x509 -newkey rsa:2048 -subj "/CN=www.test.com" -keyout www.test.com.key -nodes -days 365 -out www.test.com.crt

cat www.test.com.crt www.test.com.key > www.test.com.pem #crt放前面
  • 配置https
#cat /etc/haproxy/haproxy.cfg

......

listen web_port

bind 10.0.0.7:80

bind 10.0.0.7:443 ssl crt /etc/haproxy/ssl/www.test.com.pem #证书路径

redirect scheme https if !{ ssl_fc } #注意{ }内空格

http-request set-header X-forwarded-Port %[dst_port]

http-request add-header X-forwarder-Proto https if { ssl_fc }



mode http

log global

option httplog

balance roundrobin

server web1 10.0.0.17:80 check inter 3s fall 3 rise 5 #后端real server使用http

server web2 10.0.0.27:80 check inter 3s fall 3 rise 5
  • 重启服务

​systemctl restart haproxy​

Real Server配置

​hostname -I > /usr/share/nginx/html/index.html​

实现https

访问http://www.test.com会自动跳转至https://www.test.com,代理后端两web服务器(10.0.0.17/10.0.0.27)

Haproxy&Keepalived实现高可用_haproxy_10

轮询访问web1

Haproxy&Keepalived实现高可用_keepalived_11

轮询访问web2

Haproxy&Keepalived实现高可用_haproxy_12

六、详解keepalived配置和使用

keepalived配置文件

配置文件

​/etc/keepalived/keepalived.conf​

配置文件组成

  • global configuration
    global definitions:定义邮件配置,route_id,vrrp配置,多播地址等
  • vrrp configuration
    vrrp instance(s):定义每个vrrp虚拟路由器
  • lvs configuration
    virtual server group(s)
    virtual server(s):LVS集群的VS和RS

keepalived配置使用说明

global全局配置

global_defs {

notification_email {

root@localhost #keepalived 发生故障切换时邮件发送的目标邮箱,可以按行区分写多个

example@qq.com

}

notification_email_from keepalived@localhost #发邮件的地址

smtp_server 127.0.0.1 #邮件服务器地址

smtp_connect_timeout 30 #邮件服务器连接timeout

router_id ka1.example.com #每个keepalived主机唯一标识,建议使用当前主机名,但多节点重名不影响

vrrp_skip_check_adv_addr #对所有通告报文都检查,会比较消耗性能,启用此配置后,如果收到的通告报文和上一个报文

#是同一个路由器,则跳过检查,默认值为全检查

vrrp_strict #严格遵守VRRP协议,启用此项后以下状况将无法启动服务:

#1.无VIP地址

#2.配置了单播邻居

#3.在VRRP版本2中有IPv6地址,开启动此项并且没有配置vrrp_iptables时会自动开启iptables防火墙规则,默认导致VIP无法访问,建议不加此项配置

vrrp_garp_interval 0 #gratuitous ARP messages 报文发送延迟,0表示不延迟

vrrp_gna_interval 0 #unsolicited NA messages (不请自来)消息发送延迟

vrrp_mcast_group4 224.0.0.18 #指定组播IP地址范围:224.0.0.0到239.255.255.255,默认值:224.0.0.18

vrrp_iptables #此项和vrrp_strict同时开启时,则不会添加防火墙规则,如果无配置vrrp_strict项,则无需启用此项配置

}

虚拟路由配置

vrrp_instance <STRING> {  #<String>为vrrp的实例名,一般为业务名称

配置参数

......

}



#配置参数

state MASTER|BACKUP #当前节点在此虚拟路由器上的初始状态,状态为MASTER或者BACKUP

interface IFACE_NAME #绑定为当前虚拟路由器使用的物理接口,如:eth0,bond0,br0,可以和VIP不在一个网卡

virtual_router_id VRID #每个虚拟路由器惟一标识,范围:0-255,每个虚拟路由器此值必须唯一,否则服务无法启动,

#同属一个虚拟路由器的多个keepalived节点必须相同,务必要确认在同一网络中此值必须唯一



priority 100 #当前物理节点在此虚拟路由器的优先级,范围:1-254,值越大优先级越高,每个keepalived主机节点此值不同

advert_int 1 #vrrp通告的时间间隔,默认1s



authentication { #认证机制

auth_type AH|PASS #AH为IPSEC认证(不推荐),PASS为简单密码(建议使用)

auth_pass <PASSWORD> #预共享密钥,仅前8位有效,同一个虚拟路由器的多个keepalived节点必须一样

}



virtual_ipaddress { #虚拟IP,生产环境可能指定上百个IP地址

#<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>

192.168.200.100 #指定VIP,不指定网卡,默认为eth0,注意:不指定/prefix,默认为/32

192.168.200.101/24 dev eth1 #指定VIP的网卡,建议和interface指令指定的网卡不在一个网卡

192.168.200.102/24 dev eth2 label eth2:1 #指定VIP的网卡label

}





#单播配置,默认keepalived主机之间利用多播相互通告消息,会造成网络拥塞,可以替换成单播,减少网络流量

#注意:启用vrrp_strict时,不能启用单播

#在所有节点vrrp_instance语句块中设置对方主机的IP,建议设置为专用于对应心跳线网络的地址,而非使用业务网络

unicast_src_ip <IPADDR> #指定发送单播的源IP,本机IP

unicast_peer {

<IPADDR> #指定接收单播的对方目标主机IP

<IPADDR2> #如果有多个keepalived,再加其它节点的IP

......

}



track_interface { #配置监控网络接口,一旦出现故障,则转为FAULT状态实现地址转移

eth0

eth1

......

}

虚拟服务配置

  • 虚拟服务组配置

将多个虚拟服务器定义成一个组,统一对外服务,如:http和https定义成一个虚拟服务器组

virtual_server_group <STRING> {

# Virtual IP Address and Port

<IPADDR> <PORT>

<IPADDR> <PORT>

...

# <IPADDR RANGE> has the form

# XXX.YYY.ZZZ.WWW-VVV eg 192.168.200.1-10

# range includes both .1 and .10 address

<IPADDR RANGE> <PORT># VIP range VPORT

<IPADDR RANGE> <PORT>

...

# Firewall Mark (fwmark)

fwmark <INTEGER>

fwmark <INTEGER>

...

}

虚拟服务器配置

virtual_server IP port {    #定义虚拟主机IP地址及其端口

delay_loop <INT> #检查后端服务器的时间间隔

lb_algo rr|wrr|lc|wlc|lblc|sh|dh #定义调度方法

lb_kind NAT|DR|TUN #集群的类型,注意要大写

persistence_timeout <INT> #持久连接时长

protocol TCP|UDP|SCTP #指定服务协议,一般为TCP

sorry_server <IPADDR> <PORT> #所有RS故障时,备用服务器地址

real_server <IPADDR> <PORT> { #RS的IP和PORT

weight <INT> #RS权重

notify_up <STRING>|<QUOTED-STRING> #RS上线通知脚本

notify_down <STRING>|<QUOTED-STRING> #RS下线通知脚本

HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK { ... } #定义当前主机健康状态检测方法

}

}

#注意:括号必须分行写,两个括号写在同一行,如: }} 会出错

其他配置

include /etc/keepalived/conf.d/*.conf   #将VRRP相关配置放在子配置文件中

七、keeplived 结合haproxy 实现高可用




haproxy+keepalived 10.0.0.10

master
lo:10.0.0.10
eth0:10.0.0.7

backup
lo:10.0.0.10
eth0:10.0.0.17

Client1

web1
10.0.0.27

web2
10.0.0.37

master(10.0.0.7)

安装keepalived

#!/bin/bash

# 编译安装Keepalived



. /etc/init.d/functions

# Keepalived版本

Keepalived_versinotallow=keepalived-2.2.4

TAR=tar.gz

Keepalived=${Keepalived_version}.${TAR}



# Keepalived源码下载地址

Keepalived_url=https://keepalived.org/software/${Keepalived}

# Keepalived安装路径

Keepalived_install_DIR=/apps/keepalived



# CPU数量

CPUS=`lscpu|grep "^CPU(s)"|awk '{print $2}'`

# 系统类型

os_type=`grep "^NAME" /etc/os-release |awk -F'"| ' '{print $2}'`

# 系统版本号

os_versinotallow=`awk -F'"' '/^VERSION_ID/{print $2}' /etc/os-release`



color () {

if [[ $2 -eq 0 ]];then

echo -e "\e[1;32m$1\t\t\t\t\t\t[ OK ]\e[0;m"

else

echo $2

echo -e "\e[1;31m$1\t\t\t\t\t\t[ FAILED ]\e[0;m"

fi

}



download_keepalived (){

cd /opt

if [ -e ${Keepalived} ];then

color "Keepalived安装包已存在" 0

else

color "开始下载Keepalived安装包" 0

wget ${Keepalived_url} --no-check-certificate

if [ $? -ne 0 ];then

color "下载Keepalived安装包失败,退出!" 1

exit 1

fi

fi

}



install_keepalived (){

# 安装依赖包

yum install -y gcc curl openssl-devel libnl3-devel net-snmp-devel



# 解压源码包

tar xvf /opt/${Keepalived} -C /usr/local/src

ln -s /usr/local/src/${Keepalived_version} /usr/local/src/keepalived



# 编译安装

cd /usr/local/src/keepalived

# 选项--disable-fwmark可用于禁用iptables规则,可访止VIP无法访问,无此选项默认会启用ipatbles规则

./configure --prefix=${Keepalived_install_DIR} --disable-fwmark



make -j ${CPUS} && make install



# 准备服务启动配置文件

mkdir /etc/keepalived

cp ${Keepalived_install_DIR}/etc/keepalived/keepalived.conf /etc/keepalived/



systemctl daemon-reload

systemctl enable --now keepalived

systemctl is-active keepalived



if [ $? -ne 0 ];then

color "keepalived服务启动失败!" 1

exit 1

else

color "keepalived服务启动成功" 0

fi

}



download_keepalived



install_keepalived



exit 0

修改keepalived配置文件

[root@master ~]# vim /etc/keepalived/keepalived.conf

! 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

router_id 10.0.0.7

vrrp_skip_check_adv_addr

vrrp_garp_interval 0

vrrp_gna_interval 0

vrrp_mcast_group4 224.0.0.18

}



# 脚本需放在调用之前,先定义好

vrrp_script chk_haproxy {

script "/etc/keepalived/chk_haproxy.sh"

interval 1

timeout 2

weight -30

fall 3

rise 5

}



vrrp_instance haproxy {

state MASTER

interface eth0

virtual_router_id 51

priority 100

advert_int 1

authentication {

auth_type PASS

auth_pass 1111

}

virtual_ipaddress {

10.0.0.10/24 dev eth0 label eth0:1

}



track_script {

chk_haproxy

}



}

准备chk_haproxy.sh脚本

[root@master ~]# cat /etc/keepalived/chk_haproxy.sh 

#!/bin/bash

/usr/bin/killall -0 haproxy



#添加执行权限

[root@master ~]# chmod a+x /etc/keepalived/chk_haproxy.sh

安装haproxy

修改haproxy配置文件

[root@master ~]# vim /etc/haproxy/haproxy.cfg 

group haproxy

daemon

#nbproc 4

#cpu-map 1 0

#cpu-map 2 1

#cpu-map 3 2

#cpu-map 4 3

pidfile /var/lib/haproxy/haproxy.pid

log 127.0.0.1 local2 info



defaults

option http-keep-alive

option forwardfor

maxconn 100000

mode http

timeout connect 300000ms

timeout client 300000ms

timeout server 300000ms



listen stats

mode http

bind 0.0.0.0:9999

stats enable

log global

stats uri /haproxy-status

stats auth haadmin:123456



listen VIP #新增以下配置

bind 10.0.0.10:80

mode http

log global

option httplog

server web1 10.0.0.27:80 check inter 3s fall 3 rise 5

server web2 10.0.0.37:80 check inter 3s fall 3 rise 5

启用内核参数

#限制响应级别:arp_ignore

#0:默认值,表示可使用本地任意接口上配置的任意地址进行响应

#1:仅在请求的目标IP配置在本地主机的接收到请求报文的接口上时,才给予响应

echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore

echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore



#限制通告级别:arp_announce

#0:默认值,把本机所有接口的所有信息向每个接口的网络进行通告

#1:尽量避免将接口信息向非直接连接网络进行通告

#2:必须避免将接口信息向非本网络进行通告

echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce



echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf #开启后VIP不在本地,haproxy也可绑定该地址

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf #开启ipv4路由转发功能

执行​​sysctl -p​​命令,修改内核生效

查看状态,VIP(10.0.0.10)漂移在MASTER,haproxy绑定80端口正常

[root@master ~]# hostname -I

10.0.0.7 10.0.0.10

[root@master ~]# ss -ntl

State Recv-Q Send-Q Local Address:Port Peer Address:Port

LISTEN 0 128 *:22 *:*

LISTEN 0 100 127.0.0.1:25 *:*

LISTEN 0 128 *:9999 *:*

LISTEN 0 128 *:111 *:*

LISTEN 0 128 10.0.0.10:80 *:*

LISTEN 0 128 [::]:22 [::]:*

LISTEN 0 100 [::1]:25 [::]:*

LISTEN 0 128 [::]:111 [::]:*

[root@master ~]#

backup(10.0.0.17)

安装keepalived

安装方法同master

修改配置

[root@backup ~]# vim /etc/keepalived/keepalived.conf 



! 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

router_id 10.0.0.17 #与master不同,为本机IP

vrrp_skip_check_adv_addr

vrrp_garp_interval 0

vrrp_gna_interval 0

vrrp_mcast_group4 224.0.0.18

}



vrrp_instance haproxy {

state BACKUP #BACKUP

interface eth0

virtual_router_id 51

priority 80 #优先级80

advert_int 1

authentication {

auth_type PASS

auth_pass 1111

}

virtual_ipaddress {

10.0.0.10/24 dev eth0 label eth0:1

}

}

安装haproxy

[root@backup ~]# vim /etc/haproxy/haproxy.cfg 

group haproxy

daemon

#nbproc 4

#cpu-map 1 0

#cpu-map 2 1

#cpu-map 3 2

#cpu-map 4 3

pidfile /var/lib/haproxy/haproxy.pid

log 127.0.0.1 local2 info



defaults

option http-keep-alive

option forwardfor

maxconn 100000

mode http

timeout connect 300000ms

timeout client 300000ms

timeout server 300000ms



listen stats

mode http

bind 0.0.0.0:9999

stats enable

log global

stats uri /haproxy-status

stats auth haadmin:123456



listen VIP #新增以下配置

bind 10.0.0.10:80

mode http

log global

option httplog

server web1 10.0.0.27:80 check inter 3s fall 3 rise 5

server web2 10.0.0.37:80 check inter 3s fall 3 rise 5

启用内核参数

#限制响应级别:arp_ignore

#0:默认值,表示可使用本地任意接口上配置的任意地址进行响应

#1:仅在请求的目标IP配置在本地主机的接收到请求报文的接口上时,才给予响应

echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore

echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore



#限制通告级别:arp_announce

#0:默认值,把本机所有接口的所有信息向每个接口的网络进行通告

#1:尽量避免将接口信息向非直接连接网络进行通告

#2:必须避免将接口信息向非本网络进行通告

echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce



echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf #开启后VIP不在本地,haproxy也可绑定该地址

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf #开启ipv4路由转发功能

执行​​sysctl -p​​命令,修改内核生效

查看状态,BACKUP上无VIP(10.0.0.10),haproxy绑定10.0.0.10:80端口正常

[root@backup ~]# hostname -I

10.0.0.17

[root@backup ~]# ss -ntl

State Recv-Q Send-Q Local Address:Port Peer Address:Port

LISTEN 0 128 *:9999 *:*

LISTEN 0 128 *:111 *:*

LISTEN 0 128 10.0.0.10:80 *:*

LISTEN 0 128 *:22 *:*

LISTEN 0 100 127.0.0.1:25 *:*

LISTEN 0 128 [::]:111 [::]:*

LISTEN 0 128 [::]:22 [::]:*

LISTEN 0 100 [::1]:25 [::]:*

web1(10.0.0.27)

  • 安装nginx

​yun install nginx -y​

  • 准备网页
[root@web1 ~]# hostname -I > /usr/share/nginx/html/index.html
  • 启动服务

​systemctl start nginx​

web2(10.0.0.37)

  • 安装nginx

​yun install nginx -y​

  • 准备网页
[root@web2 ~]# hostname -I > /usr/share/nginx/html/index.html
  • 启动服务

​systemctl start nginx​

实现高可用

master正常情况下,haproxy轮询调度至后端web server

Haproxy&Keepalived实现高可用_haproxy_13

Haproxy&Keepalived实现高可用_haproxy_14

模拟master故障,停止keepalived

[root@master ~]# systemctl stop keepalived

[root@master ~]# hostname -I

10.0.0.7



# 查看backup,VIP已转移至backup上

[root@backup ~]# hostname -I

10.0.0.17 10.0.0.10

访问后端web server正常

Haproxy&Keepalived实现高可用_keepalived_15

Haproxy&Keepalived实现高可用_haproxy_16

模拟master故障,停止haproxy

[root@master ~]# systemctl stop haproxy

[root@master ~]# hostname -I

10.0.0.7

keepalived监测到haproxy进程不存在,自动进行降级处理,抓包可看到master节点优先级-30至70,backup节点优先级80升为主。

Haproxy&Keepalived实现高可用_keepalived_17

VIP漂移至backup

[root@backup ~]# hostname -I

10.0.0.17 10.0.0.10

访问后端web server正常

Haproxy&Keepalived实现高可用_haproxy_18

Haproxy&Keepalived实现高可用_haproxy_19

八、简述脑裂,产生的原因,预防的办法

脑裂

指在一个高可用(HA)系统中,当连接着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致系统混乱,数据损坏。

脑裂产生的原因

  1. 高可用服务器对之间心跳线发生故障,导致无法正常通信
  2. 心跳线坏了(包括断了,老化)
  3. 因网卡及相关驱动坏了,IP配置及冲突问题(网卡直连)
  4. 因心跳线间连接的设备故障(网卡及交换机)
  5. 因仲裁的机器出现问题(采用仲裁的方案)
  6. 高可用服务器上开启了iptables防火墙阻止了心跳消息传输
  7. 高可用服务器上心跳网卡地址等信息配置不正确,导致发送心跳失败
  8. 其他服务配置不当等原因,如心跳方式不同,心跳广播冲突,软件bug等
  9. keepalived配置里同一VRRP实例如果virtual_router_id两端参数配置不一致也会导致脑裂问题发生

常见预防/解决方案

  1. 添加冗余心跳线,可同时使用串行电缆和以太网电缆连接,同时使用两条心跳线路。
    这样一条线路坏了,另一个还是好的,依然能传送心跳消息。
  2. 当检测到裂脑时强行关闭一个心跳节点(这个功能需特殊设备支持,如Stonith、feyce)。
    相当于备节点接收不到心跳消患,通过单独的线路发送关机命令关闭主节点的电源。
  3. 做好对裂脑的监控报警(如邮件及手机短信等或值班),在问题发生时人为第一时间介入仲裁,降低损失。
    例如将报警消息发送到管理员手机上,管理员可以通过手机回复对应数字或简单的字符串操作返回给服务器.让服务器根据指令自动处理相应故障,这样解决故障的时间更短.

九、实现keeplived监控,通知

添加脚本调用方法

#vim /etc/keepalived/keepalived.conf

......

# 在vrrp_instance 语句块中添加

vrrp_instance haproxy {

state MASTER

interface eth0

virtual_router_id 51

priority 100

advert_int 1

authentication {

auth_type PASS

auth_pass 1111

}

virtual_ipaddress {

10.0.0.10/24 dev eth0 label eth0:1

}



track_script {

chk_haproxy

}



# 添加如下调用脚本方法

notify_master "/etc/keepalived/notify.sh master" #当前节点成为master时调用

notify_backup "/etc/keepalived/notify.sh backpup" #当前节点成为backup时调用

notify_fault "/etc/keepalived/notify.sh fault" #当前节点成故障时调用

}

创建通知脚本

# cat /etc/keepalived/notify.sh 

#!/bin/bash



# 接收人邮箱地址

cnotallow='2403416792@qq.com'

notify() {

mailsubject="$(hostname) to be $1, vip 转移"

mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"

echo "$mailbody" | mail -s "$mailsubject" $contact

}

case $1 in

master)

notify master

;;

backup)

notify backup

;;

fault)

notify fault

;;

*)

echo "Usage: $(basename $0) {master|backup|fault}"

exit 1

;;

esac

脚本授权

​chmod a+x /etc/keepalived/notify.sh​

邮件配置

# vim /etc/mail.rc

......

#在最后添加下面信息

set from=2403416792@qq.com #发送的邮箱地址

set smtp=smtp.qq.com #smtp服务器

set smtp-auth-user=2403416792@qq.com #邮箱登录账号

set smtp-auth-password=uqswsruhknlm #邮箱登录授权码

set smtp-auth=login

set ssl-verify=ignore

重启服务

​systemctl restart keepalived​

模拟故障,邮件通知

  • 停止master节点haproxy
[root@master ~]# systemctl stop haproxy
  • 抓包可看到master节点优先级降至70,backup节点成为主
[root@master ~]# tcpdump -i eth0 -nn host 224.0.0.18

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

13:50:50.289041 IP 10.0.0.7 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 70, authtype simple, intvl 1s, length 20

13:51:50.294612 IP 10.0.0.7 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 70, authtype simple, intvl 1s, length 20

13:51:50.978643 IP 10.0.0.17 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 80, authtype simple, intvl 1s, length 20

13:51:51.983404 IP 10.0.0.17 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 80, authtype simple, intvl 1s, length 20

13:51:52.987030 IP 10.0.0.17 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 80, authtype simple, intvl 1s, length 20
  • 邮箱收到通知,backup节点升为主
  • Haproxy&Keepalived实现高可用_keepalived_20

  • 恢复master节点haproxy
[root@master ~]# systemctl start haproxy
  • 抓包可看到master节点优先级恢复至100,master节点恢复为主
[root@master ~]# tcpdump -i eth0 -nn host 224.0.0.18

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

13:58:16.942124 IP 10.0.0.17 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 80, authtype simple, intvl 1s, length 20

13:58:17.945570 IP 10.0.0.17 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 80, authtype simple, intvl 1s, length 20

13:58:18.947258 IP 10.0.0.17 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 80, authtype simple, intvl 1s, length 20

13:58:19.948354 IP 10.0.0.17 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 80, authtype simple, intvl 1s, length 20

13:58:20.554474 IP 10.0.0.7 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20

13:58:21.556958 IP 10.0.0.7 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20

13:58:22.560039 IP 10.0.0.7 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20

13:58:23.561156 IP 10.0.0.7 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
  • 邮箱收到通知,master节点恢复为主

Haproxy&Keepalived实现高可用_keepalived_21