共计 12079 个字符,预计需要花费 31 分钟才能阅读完成。
一、haproxy 介绍:
HAProxy 提供高可用性、负载均衡以及基于 TCP 和 HTTP 应用的代理,支持虚拟主机。HAProxy 特别适用于那些负载特大的 web 站点,这些站点通常又需要会话保持或七层处理。HAProxy 运行在时下的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中,同时可以保护你的 web 服务器不被暴露到网络上。HAProxy 实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户端 (User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个 CPU 时间片(Cycle) 做更多的工作。
在 Linux 内核版本为 2.6 或打了 epoll 补丁的 linux2.4 上运行 haproxy 能获得其最好的性能。
二、keepalived 介绍:
keepalived 理论工作原理
keepalived 可提供 vrrp 以及 health-check 功能,可以只用它提供双机浮动的 vip(vrrp 虚拟路由功能),这样可以简单实现一个双机热备高可用功能。
keepalived 是一个类似于 layer3, 4 & 5 交换机制的软件,也就是我们平时说的第 3 层、第 4 层和第 5 层交换。Keepalived 的作用是检测 web 服务器的状态。Layer3,4&5 工作在 IP/TCP 协议栈的 IP 层,TCP 层,及应用层, 原理分别如下:
Layer3:Keepalived 使用 Layer3 的方式工作式时,Keepalived 会定期向服务器群中的服务器 发送一个 ICMP 的数据包(既我们平时用的 Ping 程序), 如果发现某台服务的 IP 地址没有激活,Keepalived 便报告这台服务器失效,并将它从服务器群中剔除,这种情况的典型例子是某台服务器被非法关机。Layer3 的方式是以服务器的 IP 地址是否有效作为服务器工作正常与否的标准。在本文中将采用这种方式。
Layer4: 如果您理解了 Layer3 的方式,Layer4 就容易了。Layer4 主要以 TCP 端口的状态来决定服务器工作正常与否。如 web server 的服务端口一般是 80,如果 Keepalived 检测到 80 端口没有启动,则 Keepalived 将把这台服务器从服务器群中剔除。
Layer5:Layer5 就是工作在具体的应用层了,比 Layer3,Layer4 要复杂一点,在网络上占用的带宽也要大一些。Keepalived 将根据用户的设定检查服务器程序的运行是否正常,如果与用户的设定不相符,则 Keepalived 将把服务器从服务器群中剔除。
vip 即虚拟 ip,是附在主机网卡上的,即对主机网卡进行虚拟,此 IP 仍然是占用了此网段的某个 IP。
keepalived 的用途:
Keepalived 是一个基于 VRRP 协议来实现的 WEB 服务高可用方案,可以利用其来避免单点故障。一个 WEB 服务至少会有 2 台服务器运行 Keepalived,一台为主服务器(MASTER),一台为备份服务器(BACKUP),但是对外表现为一个虚拟 IP,主服务器会发送特定的消息给备份服务器,当备份服务器收不到这个消息的时候,即主服务器宕机的时候,备份服务器就会接管虚拟 IP,继续提供服务,从而保证了高可用性。
在 lvs+keepalived 高可用负载均衡架构中,lvs 本身不支持对后端 real server 进行健康状态检测,而 keepalived 的诞生不仅能是 lvs 均衡器实现了高可用,而且还能对 lvs 后端的 real server 进行健康状态检测。如果有一台 web 服务器死机,或工作出现故障,Keepalived 将检测到,并将有故障的 web 服务器从系统中剔除,当 web 服务器工作正常后 Keepalived 自动将 web 服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的 web 服务器。
配置过程:
在配置之前,先将 HA 中个节点进行时间同步,主机名之间相互解析,以及配置双机互信。
在 haproxy1.daixiang.com 上配置:
1
2
3
4
5
6
|
[root@haproxy1 ~] # vim /etc/hosts 172.16.0.1 haproxy1.daixiang.com haproxy1 172.16.0.2 haproxy2.daixiang.com haproxy2<br> [root@haproxy1 ~] # ssh-keygen -t rsa -P '' [root@haproxy1 ~] # ssh-copy-id haproxy2 [root@haproxy1 ~] # ntpdate s2c.time.edu.cn |
在 haproxy2.daixiang.com 上配置:
1
2
3
4
5
6
7
|
[root@haproxy2 ~] # vim /etc/hosts 172.16.0.1 haproxy1.daixiang.com haproxy1 172.16.0.2 haproxy2.daixiang.com haproxy2 [root@haproxy2 ~] # ssh-keygen -t rsa -P '' [root@haproxy2 ~] # ssh-copy-id haproxy1 [root@haproxy2 ~] # ntpdate s2c.time.edu.cn |
安装 haproxy 和 keepalived:
在 haproxy1 和 haproxy2 节点上进行同样的操作:
1
2
3
|
[root@haproxy1 ~] # yum install keepalived haproxy -y [root@haproxy1 ~] # cd /etc/keepalived/ [root@haproxy1 keepalived] # cp keepalived.conf{,.bak} |
配置 keepalived:双主模型
[root@haproxy1 keepalived]# vim keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email { #定义收件人邮箱
root@localhost
}
notification_email_from root@localhost #定义发件人邮箱
smtp_server 127.0.0.1 #定义邮件服务器地址
smtp_connect_timeout 30 #定有邮件服务器连接超时时长为 30 秒
router_id LVS_DEVEL #运行 keepalive 的机器的标识
}
vrrp_instance VI_1 { #定义 VRRP 实例,实例名自定义
state MASTER #指定当前节点的角色,master 为主,backup 为从
interface eth1 #直接 HA 监测的接口
virtual_router_id 51 #虚拟路由标识,在同一 VRRP 实例中,主备服务器 ID 必须一样
priority 100 #定义节点优先级,数字越大越优先,主服务器优先级高于从服务器
advert_int 1 #设置主备之间永不检查时间间隔,单位为秒
authentication { 设置主从之间验证类型和密码
auth_type PASS
auth_pass a23c7f32dfb519d6a5dc67a4b2ff8f5e
}
virtual_ipaddress {192.168.80.200 #定义虚拟 ip 地址
}
}
vrrp_instance VI_2 {
state BACKUP
interface eth1
virtual_router_id 52
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 56f7663077966379d4106e8ee30eb1a5
}
virtual_ipaddress {192.168.80.201
}
}
将此配置文件同步到另一个 haproxy2.daixiang.com 上:
1
|
[root@haproxy1 keepalived] # scp keepalived.conf haproxy2:/etc/keepalived/ |
在 haproxy2.daixiang.com 上修改 keepalived.conf 配置文件:
[root@haproxy2 keepalived]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {root@localhost}
notification_email_from root@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state BACKUP
interface eth1
virtual_router_id 51
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass a23c7f32dfb519d6a5dc67a4b2ff8f5e
}
virtual_ipaddress {192.168.80.200
}
}
vrrp_instance VI_2 {
state MASTER
interface eth1
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 56f7663077966379d4106e8ee30eb1a5
}
virtual_ipaddress {192.168.80.201
}
}
重启 keepalived:
1
2
|
[root@haproxy1 keepalived] # service keepalived restart [root@haproxy1 keepalived] # ssh haproxy2 'service keepalived restart' |
配置 haproxy:
先将原始配置文件进行备份:
1
2
3
4
|
[root@haproxy1 ~] # cd /etc/haproxy/ [root@haproxy1 haproxy] # cp haproxy.cfg{,.bak} ## 节点 2 也进行同样的操作 |
编辑其配置文件修改其内容如下:
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
|
[root@haproxy1 haproxy] # vim haproxy.cfg #--------------------------------------------------------------------- # Example configuration for a possible web application. See the # full configuration options online. # # http://haproxy.1wt.eu/download/1.4/doc/configuration.txt # #--------------------------------------------------------------------- #--------------------------------------------------------------------- # Global settings #--------------------------------------------------------------------- global # 定义全局配置段 # to have these messages end up in /var/log/haproxy.log you will # need to: # # 1) configure syslog to accept network log events. This is done # by adding the '-r' option to the SYSLOGD_OPTIONS in # /etc/sysconfig/syslog # # 2) configure local2 events to go to the /var/log/haproxy.log # file. A line like the following can be added to # /etc/sysconfig/syslog # # local2.* /var/log/haproxy.log # log 127.0.0.1 local2 # 通过 rsyslog 将日志进行归档记录,在 /etc/rsyslog.conf 配置文件中,添加‘local2.* /var/log/haproxy',并且启用 $ModLoad imudp,$UDPServerRun 514,$ModLoad imtcp,$InputTCPServerRun 514 此四项功能,最后重启 rsyslog 进程。 chroot /var/lib/haproxy # 指定 haproxy 进程工作的目录 pidfile /var/run/haproxy .pid # 指定 pid 文件 maxconn 4000 # 最大并发连接数 user haproxy # 运行 haproxy 的用户 group haproxy # 运行 haproxy 的组 daemon # 以守护进程的形式运行,即后台运行 # turn on stats unix socket stats socket /var/lib/haproxy/stats #--------------------------------------------------------------------- # common defaults that all the 'listen' and 'backend' sections will # use if not designated in their block #--------------------------------------------------------------------- defaults # 默认配置端 mode http # 工作模式,源码包编译默认为 tcp log global # 记录全局日志 option httplog # 详细记录 http 日志 option dontlognull # 不记录健康检测的日志信息 option http-server-close # 启用服务器端主动关闭功能 option forwardfor except 127.0.0.0 /8 # 传递 client 端 IP 至后端 real server option redispatch # 基于 cookie 做会话保持时,后端对应存放 session 的服务器出现故障时,会话会被重定向至别的服务器 retries 3 # 请求重传次数 timeout http-request 10s # 断开客户端连接的时长 timeout queue 1m # 一个请求在队列里的超时时长 timeout connect 10s # 设定在 haproxy 转发至后端 upstream server 时等待的超时时长 timeout client 1m #client 的一次非活动状态的超时时长 timeout server 1m # 等待服务器端的非活动的超时时长 timeout http-keep-alive 10s # 持久连接超时时长 timeout check 10s # 检查请求连接的超时时长 maxconn 3000 # 最大连接数 #--------------------------------------------------------------------- # main frontend which proxys to the backends #--------------------------------------------------------------------- frontend webserver *:80 acl url_static path_beg -i /static /images /javascript /stylesheets # 匹配 path 以 /static,/images 开始的,且不区分大小写 acl url_static path_end -i .jpg .gif .png .css .js .html acl url_static hdr_beg(host) -i img. video. download. ftp . imgs. image. acl url_dynamic path_end .php .jsp use_backend static if url_static # 满足名为 url_static 这条 acl 规则,则将请求转发至后端名为 static 的 real server 组中去 use_backend dynamic if url_dynamic default_backend static # 如果上面所有 acl 规则都不满足,将请求转发到 static 组中 #--------------------------------------------------------------------- # static backend for serving up images, stylesheets and such #--------------------------------------------------------------------- backend static # 定义后端 real server 组,组名为 static balance roundrobin # 支持动态权重修改,支持慢启动 server static_1 172.16.0.100:80 check inter 3000 fall 3 rise 1 maxconn 30000 server static_2 172.16.0.101:80 check inter 3000 fall 3 rise 1 maxconn 30000 server static_Error 172.16.0.1:8080 backup check # 当此组中的所有 server 全部不能提供服务,才将请求调度至此 server 上 #--------------------------------------------------------------------- # round robin balancing between the various backends #--------------------------------------------------------------------- backend dynamic cookie cookie_name insert nocache # 使用 cookie 实现 session 绑定,且不记录缓存 balance roundrobin server dynamic1 172.16.0.200:80 check inter 3000 fall 3 rise 1 maxconn 1000 cookie dynamic1 server dynamic2 172.16.0.201:80 check inter 3000 fall 3 rise 1 maxconn 1000 cookie dynamic2 # 定义 dynamic 组中的 server,将此 server 命名为 dynamic2,每隔 3000ms 检测一个健康状态,如果检测 3 次都失败,将此 server 剔除。在离线的状态下,只要检测 1 次成功,就让其上线,此 server 支持最大的并发连接数为 1000,cookie 的值为 dynamic2 listen state # 使用单独输出,不需要 frontedn 调用:定义 haproxy 的状态统计页面 bind *:8001 # 监听的地址 mode http # http 7 层工作模式:对应用层数据做深入分析,因此支持 7 层的过滤、处理、转换等机制 stats enable # 开启统计页面输出 stats hide-version # 隐藏状态页面版本号 stats uri /haproxyadmin ?stats # 指定状态页的访问路径 stats auth admin:admin # 基于用户名,密码验证。 stats admin if TRUE # 验证通过时运行登录。 acl num1 src 192.168.80.0 /24 # 定义源地址为 192.168.80.0/24 网段的 acl 规则,将其命名为 num1 tcp-request content accept if num1 # 如果满足此规则,则允许访问 tcp-request content reject # 拒绝其他所有的访问 |
将此配置文件同步当另一个 haproxy 节点上去:
1
|
[root@haproxy1 haproxy] # scp haproxy.cfg haproxy2:/etc/haproxy/ |
重启 haproxy 服务:
1
2
|
[root@haproxy1 haproxy] # service haproxy restart [root@haproxy1 haproxy] # ssh haproxy2 'service haproxy restart' |
查看这两个节点获取 ip 的情况:
haproxy1.daixiang.com:
[root@haproxy1 ~]# ip addr show
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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
link/ether 00:0c:29:52:3b:c0 brd ff:ff:ff:ff:ff:ff
inet 172.16.0.1/16 brd 172.16.255.255 scope global eth1
inet 192.168.80.200/32 scope global eth1
inet6 fe80::20c:29ff:fe52:3bc0/64 scope link
valid_lft forever preferred_lft forever
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:52:3b:ca brd ff:ff:ff:ff:ff:ff
inet 192.168.80.125/24 brd 192.168.80.255 scope global eth0
inet6 fe80::20c:29ff:fe52:3bca/64 scope link
valid_lft forever preferred_lft forever
[root@haproxy1 ~]#
haproxy2.daixiang.com:
[root@haproxy2 haproxy]# ip addr show
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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
4: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:ae:5c:b3 brd ff:ff:ff:ff:ff:ff
inet 192.168.80.128/24 brd 192.168.80.255 scope global eth0
inet6 fe80::20c:29ff:feae:5cb3/64 scope link
valid_lft forever preferred_lft forever
6: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
link/ether 00:0c:29:ae:5c:a9 brd ff:ff:ff:ff:ff:ff
inet 172.16.0.2/16 brd 172.16.255.255 scope global eth1
inet 192.168.80.201/32 scope global eth1
inet6 fe80::20c:29ff:feae:5ca9/64 scope link
valid_lft forever preferred_lft forever
在后端的 real server 提供测试页面,测试的结果如下:
请求以.html 结尾的文件,haproxy 将请求代理至后端 static 组中的 server 处理:
请求以.php 结尾的文件,haproxy 将请求代理至后端 dynamic 组中 server 处理:
注意:本文在 haproxy.cfg 的配置文件中,将 dynamic 组中的 server 配置了基于 cookie 的 session 绑定,所以,用同一浏览器看不出负载均衡的效果来。换个浏览器再访问一次或者清空浏览器的 cookie 记录就能显示效果,如下图。
haproxy 的统计页面输出效果:
至此,实验完结,但是对于 haproxy 的两个节点,keepalived 对于这两节点是怎么进行心跳检测,其工作原理是什么,此知识点比较模糊,求大神赐教。
Linux 下 HAProxy+Keepalived 双机高可用方案 http://www.linuxidc.com/Linux/2016-02/128566.htm
Haproxy+Keepalived 搭建 Weblogic 高可用负载均衡集群 http://www.linuxidc.com/Linux/2013-09/89732.htm
Keepalived+HAProxy 配置高可用负载均衡 http://www.linuxidc.com/Linux/2012-03/56748.htm
CentOS 6.3 下 Haproxy+Keepalived+Apache 配置笔记 http://www.linuxidc.com/Linux/2013-06/85598.htm
Haproxy + KeepAlived 实现 WEB 群集 on CentOS 6 http://www.linuxidc.com/Linux/2012-03/55672.htm
Haproxy+Keepalived 构建高可用负载均衡 http://www.linuxidc.com/Linux/2012-03/55880.htm
本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-06/132225.htm