前两天成功配置了用 nginx 做负载均衡,此时 nginx 服务器存在单点故障的问题。可以通过使用 keepalived 实现高可用。网上搜了几篇文章,貌似都很简单,可是照着做时却遇到了不少问题。我的虚拟机是 ubuntu 16.04,碰到问题也许是别人的机器不是 ubuntu 吧。
IP 分配:
IP 地址 | 安装软件 |
192.168.137.47(主) | Nginx + keepalived |
192.168.137.48 (备) | Nginx + keepalived |
192.168.137.11 | Tomcat |
192.168.137.12 | Tomcat |
在 192.168.137.47 上:
1. 安装 keepalived: apt-get install keepalived
2. 修改 /etc/keepalived/keepalived.conf 这个配置文件(我安装完后,这个配置文件并不存在,连 /etc/keepalived 这个文件夹都不存在,自己创建了),在文件里添加了如下内容:
! Configuration File for keepalived
global_defs {
notification_email {
zonghsh001@126.com
}
notification_email_from zonghsh007@126.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_Master # 随便取一个唯一的标识符,主机和备机需要用不同的值
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script chk_http_port {
script "/opt/programs/keepalived/etc/keepalived/check_nginx_pid.sh"
interval 2
weight 2
}
vrrp_instance VI_1 {
#state MASTER
state BACKUP # 主、备都设成 BACKUP,主机的配置里再加下面 nopreempt 的配置,这样主机 down 掉后,原来的备机(192.168.137.48)就成了新的主机,本机再启动起来后,不会迫使 192.168.137.48 重新成为备机。192.168.137.48 在正常工作着,完全没必要做这样的切换
nopreempt #备机上不需要此配置
interface ens33 # 通过 ifconfig 得到的本机的网卡
virtual_router_id 51
#mcast_src_ip 192.168.137.48
priority 100 # 主机的 priority 的值需要比备机的值至少大50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_http_port
}
virtual_ipaddress {
192.168.200.88/24 dev ens33 scope global # 192.168.200.88 就是虚拟出来的 IP 地址,主机启动后,通过 ip a 就可以看到这个IP 地址绑定在了 ens33 这样网卡上,如果主机 down 了,备机就会拥有这个IP。
}
}
上面的配置中,大括号前面都要有空格,一开始有几个地方我没有放空格,结果,怎么都出现不了那个虚拟的IP 地址。搞了好几个小时。。。。。。
另外,用到的 check_nginx_pid.sh 内容如下(自己创建完后需要加上执行权限):
#!/bin/bash
A=`ps -C nginx --no-header |wc -l`
if [ $A -eq 0 ];then
/opt/programs/tengine/sbin/nginx
sleep 4
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
killall keepalived
fi
fi
3. 为了查看 keepalived 的日志,网上搜了一下,好像没有简单的方式,只有通过复杂的方式。如下:
(1)在 /etc/rsyslog.conf 文件末尾添加如下一行:
local0.* /var/log/keepalived.log
(2)重启日志服务: /etc/init.d/rsyslog restart
(3)启动时添加参数: -D -S 0
4. 启动 keepalived: keepalived -D -S 0 -f /etc/keepalived/keepalived.conf
网上好多都说默认的配置文件地址是 /etc/keepalived/keepalived.conf, 但是我的好像不是,不指定的话,没有用到这个配置文件。对 ubuntu 不熟,上面的命令能执行,但是不知道它到底执行的是哪个目录下的 keepalived 执行文件。
5. 启动成功后,在主机上运行 ip a 命令,可以发现类似下面的输出,出现了我们上面配置的 192.168.200.88 这个虚拟 IP 地址
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:d7:c0:62 brd ff:ff:ff:ff:ff:ff
inet 192.168.137.48/24 brd 192.168.137.255 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.200.88/24 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fed7:c062/64 scope link
6. 在主机上运行 killall keepalived,这样原来的副机就变成的主机,在原来的副机上运行第5步中的命令,可以看到 192.168.200.88 这个虚拟IP 地址。
诡异的事情来了,在别的机器竟然 ping 不通 192.168.200.88!! 网上搜了一下,可以主要检查的几点就是 http://zk2052041.blog.163.com/blog/static/1377237201533287298 里说的几点,可是我的问题依然存在,后来在搜索引擎里翻了几页,才看到有人说虚拟 IP 的网段应该设置成和真实 IP 同一个网段。我真实IP的网段是 192.168.137.XXX,我把上面的192.168.200.88 改成 192.168.137.88 后,终于成功了。
另外, nginx 的配置文件中的 server_name 应该配置成上面的虚拟 IP 的地址,别人的教程是这么写的,但是奇怪的是我本机配成不一样的地址,仍然可以正常工作,这是因为这里的 server_name 可以看作仅仅是别名,nginx 想要监听某台机器的某个端口, listen 的值应该配置成 192.168.137.88:80,只写端口号的话,表示的是本机。
server {
listen 80;
server_name 192.168.137.88;
location / {
proxy_pass http://loadbalance;
root html;
index index.html index.htm;
}
location /status {
check_status;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}