Keepalived和Haproxy

安装

yum install keepalived haproxy psmisc

修改系统参数

echo 'net.ipv4.ip_nonlocal_bind = 1' >> /etc/sysctl.conf

sysctl -p

防火墙

firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" destination address="224.0.0.18" protocol value="vrrp" accept' --permanent
Firewall-cmd --reload

架构

"keepalived_haproxy"

Haproxy反代配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

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

global
log 127.0.0.1 local2 warning

chroot /var/lib/haproxy
pidfile /run/haproxy/haproxy.pid

maxconn 4000
user haproxy
group haproxy

daemon

## 设置启动的haproxy进程数量,一般设置为cpu核数, 只能用于守护进程模式的haproxy;
## 默认只启动一个进程
#nbproc 1

## 设置绑定核心,第一个参数表示绑定id,第二个参数指定cpu核心,0开始第一个cpu核心
## 后面用bind-process 绑定id,如将CPU核心分开以进行后端处理
## frontend access_http
## bind 0.0.0.0:80
## bind-process 1
## frontend access_https
## bind 0.0.0.0:443 ssl crt /etc/yourdomain.pem
## bind-process 2 3 4

#cpu-map 1 0
#cpu-map 2 1
#cpu-map 3 2
#cpu-map 4 3


#定义统计信息保存位置
#stats socket /var/lib/haproxy/stats
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s


##===============https相关========================================
ca-base /etc/ssl/certs
crt-base /etc/ssl/private

## Default ciphers to use on SSL-enabled listening sockets.
## 参考:https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
## 需要处理以下事:
## 禁用SSL 2.0(FUBAR)和SSL 3.0 1(POODLE),
## 禁用TLS 1.0压缩(CRIME),
## 禁用弱密码(DES / 3DES,RC4),更喜欢现代密码(AES),模式(GCM)和协议(TLS 1.2)。
## OpenSSL更新为1.0.1c +,以便尽快支持TLS 1.2,GCM和ECDHE
## OpenSSL安装进行测试:
## openssl ciphers -v 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS'

## ssl-default-bind-options <force-sslv3|no-sslv3 no-tls-tickets|force-tlsv10|force-tlsv11|force-tlsv12>
ssl-default-bind-options force-tlsv12

ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS

ssl-default-server-options force-tlsv12
ssl-default-server-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS

tune.ssl.default-dh-param 2048

##============================================================


defaults

mode http
log global
option httplog
option dontlognull
option http-server-close
#option httpclose
option abortonclose

option redispatch
retries 3

option forwardfor except 127.0.0.0/8

timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s

maxconn 3000

#balance source
#balnace leastconn


#统计页面配置, frontend和backend的组合体, 监控组的名称可按需自定义
listen admin_stats
bind 0.0.0.0:1080
mode http
maxconn 10
option httplog

stats enable
stats hide-version
stats refresh 30s
stats uri /stats
stats realm Haproxy\ Statistics
stats auth test.admin:test.admin!9595
stats admin if TRUE

#设置haproxy错误页面,复制源代码目录下错误样本文件(cp ./haproxy-1.8.8/examples/errorfiles/* /usr/local/haproxy)
#errorfile 400 /usr/local/haproxy/errorfiles/400.http
#errorfile 403 /usr/local/haproxy/errorfiles/403.http
#errorfile 408 /usr/local/haproxy/errorfiles/408.http
#errorfile 500 /usr/local/haproxy/errorfiles/500.http
#errorfile 502 /usr/local/haproxy/errorfiles/502.http
#errorfile 503 /usr/local/haproxy/errorfiles/503.http
#errorfile 504 /usr/local/haproxy/errorfiles/504.http


frontend web
bind *:80
mode http
maxconn 2000

acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js .html .txt .htm

use_backend resources if url_static
default_backend app


backend resources
balance roundrobin
server web1 172.18.67.11:8080 check
server web2 172.18.67.12:8080 check


backend app
balance roundrobin
server wp1 172.18.67.11:80 check
server wp2 172.18.67.12:80 check


EOF

keepalived

## 主备不同之处
    1,router_id        不能一致
    2,state            MASTER/BACKUP
    3, priority         权重不能一致
    4, interface ens33  网络接口注意和本机对应

keepalived master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
IT@service.com
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id haproxy01
vrrp_garp_master_refresh 60
vrrp_garp_master_delay 5

vrrp_mcast_group4 224.0.0.18
}

vrrp_script chk_mantaince_down {
script "/etc/keepalived/chk_down.sh"
interval 2
weight 20
fall 2
rise 1
}

vrrp_script chk_haproxy {
script "/bin/killall -0 haproxy && exit 0 || exit 1"
interval 2
weight 20
fall 2
rise 1
}

vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 50
priority 100
advert_int 1
#garp_master_delay 10
#garp_master_refresh 60
#nopreempt
smtp_alert

authentication {
auth_type PASS
auth_pass DFwx4893Gh60
}

virtual_ipaddress {
## <IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>
172.18.67.33/24 dev ens33
}

## mcast_src_ip <IPADDR>
#unicast_src_ip 172.18.67.13
#unicast_peer {
# 172.18.67.14
#}

track_interface {
ens33
}

track_script {
chk_haproxy
chk_mantaince_down
}

## 可以不用执行脚本,除非需要执行某些操作。keepalived 1.5 + postfix 能够发送邮件。

#notify_master "/etc/keepalived/notify.sh master"
#notify_backup "/etc/keepalived/notify.sh backup"
#notify_fault "/etc/keepalived/notify.sh fault"

}

EOF

keepalived backup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
IT@service.com
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id haproxy02
vrrp_garp_master_refresh 60
vrrp_garp_master_delay 5

vrrp_mcast_group4 224.0.0.18
}

vrrp_script chk_mantaince_down {
script "/etc/keepalived/chk_down.sh"
interval 2
weight 20
fall 2
rise 1
}

vrrp_script chk_haproxy {
script "/bin/killall -0 haproxy && exit 0 || exit 1"
#script "/etc/keepalived/chk_haproxy.sh"
interval 2
weight 20
fall 2
rise 1
}

vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 50
priority 90
advert_int 1
#garp_master_delay 10
#garp_master_refresh 60
#nopreempt
smtp_alert

authentication {
auth_type PASS
auth_pass DFwx4893Gh60
}

virtual_ipaddress {
## <IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>
172.18.67.33/24 dev ens33
}

## mcast_src_ip <IPADDR>
#unicast_src_ip 172.18.67.14
#unicast_peer {
# 172.18.67.13
#}

track_interface {
ens33
}

track_script {
chk_haproxy
chk_mantaince_down
}

## 可以不用执行脚本,除非需要执行某些操作。keepalived 1.5 + postfix 能够发送邮件。

#notify_master "/etc/keepalived/notify.sh master"
#notify_backup "/etc/keepalived/notify.sh backup"
#notify_fault "/etc/keepalived/notify.sh fault"

}

EOF

haproxy 进程检查脚本

1
2
3
4
5
6
7
8

cat > /etc/keepalived/chk_haproxy.sh << EOF
#!/bin/bash
[[ \$(ps -C 'haproxy' --no-heading -o stat,ppid,pid,cmd | grep -ve '^[Zz]' | grep -iv 'grep' | wc -l) -ge 2 ]] && exit 0 || exit 1

EOF

chmod u+x /etc/keepalived/chk_haproxy.sh

维护脚本

1
2
3
4
5
6
7
8

cat > /etc/keepalived/chk_down.sh << EOF
#!/bin/bash
[[ -f /etc/keepalived/down ]] && exit 1 || exit 0

EOF

chmod u+x /etc/keepalived/chk_down.sh

通知脚本

## 只是发送通知邮件,不是必须的。keepalived 1.5 + postfix 能够发送邮件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

cat > /etc/keepalived/notify.sh << EOF
#!/bin/bash

contact='root@localhost'

notify() {
mailsubject="$(hostname) to be $1, vip floating"
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

EOF

chmod u+x /etc/keepalived/notify.sh

web 监控脚本

监控web服务器脚本:


#! /bin/bash

## 注意,这里需要tomcat开启了所有IP地址的web请求,

## 这里填写首页的index地址
URL=
URL_STATUS=`curl -o /dev/null -s -w %{http_code} $URL`

if [ $URL_STATUS != 200 ];then

    killall tomcat

    /opt/tomcat/bin/start.sh #这里是启动tomcat,当然,有其他方法也可以

    sleep 3

    if [ `curl -o /dev/null -s -w %{http_code} $URL` != 200 ];then

        killall keepalived

    fi

fi

监控mysql脚本

#! /bin/bash

STATUS=`mysqladmin ping -u设置的用户名 -p设置的密码`

if [ “$STATUS” != “mysqld is alive” ];then

    service mysql restart

    RE=$?

    sleep 3

    if [ $RE != 0 ];then

        killall keepalived

    fi

fi

参考

https://www.cnblogs.com/mrlapulga/p/6857294.html