一、Keepalived 简要介绍
Keepalived 是一种高性能的服务器高可用或热备解决方案, Keepalived 可以用来防止服务器单点故障的发生,通过配合 Nginx 可以实现 web 前端服务的高可用。Keepalived 以 VRRP 协议为实现基础,用 VRRP 协议来实现高可用性(HA)。 VRRP(Virtual RouterRedundancy Protocol)协议是用于实现路由器冗余的协议, VRRP 协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器 IP(一个或多个),而在路由器组内部,如果实际拥有这个对外 IP 的路由器如果工作正常的话就是 MASTER,或者是通过算法选举产生, MASTER 实现针对虚拟路由器 IP 的各种网络功能,如 ARP 请求, ICMP,以及数据的转发等;其他设备不拥有该虚拟 IP,状态是 BACKUP,除了接收 MASTER 的VRRP 状态通告信息外,不执行对外的网络功能。当主机失效时, BACKUP 将接管原先 MASTER 的网络功能。VRRP 协议使用多播数据来传输 VRRP 数据, VRRP 数据使用特殊的虚拟源 MAC 地址发送数据而不是自身网卡的 MAC 地址, VRRP 运行时只有 MASTER 路由器定时发送 VRRP 通告信息,表示 MASTER 工作正常以及虚拟路由器 IP(组), BACKUP 只接收 VRRP 数据,不发送数据,如果一定时间内没有接收到 MASTER 的通告信息,各 BACKUP 将宣告自己成为 MASTER,发送通告信息,重新进行 MASTER 选举状态。
二、方案规划
架构图
本次搭建在两台centos7服务器上:
三、搭建keepalived和nginx
安装keepalived和nginx yum -y install keepalived nginx
1、安装完成后先修改主备节点的keepalived配置文件
修改主节点node1的keepalived配置文件 vim /etc/keepalived/keepalived 修改为以下内容:
! 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 node1 #机器标识,设置为主机名
}
vrrp_script chk_http_port { #设置nginx的检测脚本
script "/etc/keepalived/chk_nginx.sh"
interval 3 #脚本执行间隔时间,注意必须要大于脚本的心跳时间
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER # 主节点为 MASTER, 对应的备份节点为 BACKUP
# nopreempt # 设置是否抢占,即主节点恢复后,是否将vip从备节点抢占过来
interface ens33 # 绑定虚拟 IP 的网络接口,与本机 IP 地址所在的网络接口相同, 我的是 ens33
virtual_router_id 51 # 虚拟路由的 ID 号, 两个节点设置必须一样
priority 100 # 节点优先级, 值范围 0-254, MASTER 要比 BACKUP 高
advert_int 1 # 组播信息发送间隔,两个节点设置必须一样, 默认 1s
authentication { # 设置验证信息,两个节点必须一致
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.114.200 # 虚拟 ip,可以定义多个
}
track_script { # 将 track_script 块加入 instance 配置块
chk_http_port # 执行 Nginx 监控的服务
}
}
修改备节点node2,keepalived配置文件 vim /etc/keepalived/keepalived 修改为以下内容:
! 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 node2 #修改标识id,设为备节点的主机名
}
vrrp_script chk_http_port {
script "/etc/keepalived/chk_nginx.sh"
interval 3
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state BACKUP #设置为备节点
interface ens33
virtual_router_id 51
priority 90 #修改权重,备节点权重比主节点低
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.114.200
}
track_script {
chk_http_port
}
}
2、创建nginx的检测脚本
vim /etc/keepalived/chk_nginx.sh
#!/bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];then
nginx
sleep 2
if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then
pkill keepalived
fi
fi
主备节点使用相同的检测脚本,为脚本赋予执行权限
chmod 755 /etc/keepalived/chk_nginx.sh
3、配置nginx
修改nginx配置文件,主备节点nginx配置一致 篇幅有限,这里nginx即作为负载均衡,也作为web服务器。正常来讲,proxy代理到的,应该为tomcat或其他后端服务。 vim /etc/nginx/ngxin.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 8888 default_server;
listen [::]:8888 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
upstream back {
server 192.168.114.128:8888 weight=1;
server 192.168.114.129:8888 weight=1;
}
server {
listen 80;
# auth_basic off;
server_name 192.168.114.200;
#error_log /var/log/nginx/wap.error.log debug;
location / {
proxy_pass http://back; #来自jsp请求交给tomcat处理
proxy_redirect off;
proxy_set_header Host $host; #后端的Web服务器可以通过X-Forwarded-For>获取用户真实IP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m; #允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数
proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 6 32k; #proxy_buffers缓冲区,网页平均在32k以下的话>,这样设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
四、启动并测试高可用
1、启动keepalived systemctl start keepalived 启动nginx nginx
2、查看绑定的虚拟IP 在主节点node1上查看 ip addr
在备节点查看
主节点和备节点同一时间只有一个能绑定这个虚拟IP
3、通过访问http://192.168.114.200/ 可以看到的访问到不通的后端服务上,表面负载均衡和虚拟ip没有问题。
4、接下来在测试高可用,停掉主节点的keepalived服务,查看虚拟ip漂移到备节点没有 node1上执行: systemctl stop keepalived.service
node2上查看ip: ip addr 发现备节点成功的接管了虚拟ip,再次访问http://192.168.114.200/ ,同样能负载到不通的后端服务。
5、测试keepalived检测nginx的脚本。 启动主节点的keepalived服务,让node1重新接管虚拟ip node1上执行: systemctl start keepalived.service
nginx检测脚本主要功能为: 检测nginx进程,如果为0,则尝试重新启动nginx,启动后再次检测,若启动失败则停止当前的keepalived服务,让虚拟ip漂移到备节点。
停止nginx,执行: nginx -s stop 通过一直搜索nginx进程可以发现,nginx停止后keepalived执行检测脚本将nginx再次拉起了。 至此,整个keepalived+nginx的负载均衡高可用搭建完成。
后续:一些搭建中遇到的问题
1、keepalived启动后,虚拟ip不能ping通 将默认的配置文件中的一下参数删除后,能正常ping通。
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
2、在测试检测nginx脚本时,修改nginx配置文件,让nginx不能启动,正常的话,主节点的keepalived服务会被脚本停掉,让虚拟IP漂移到备节点,但是停止失败,并且使用systemctl status keepalived.service查看keepalived的状态发现有个异常日志:
node1 Keepalived_vrrp[97803]: /etc/keepalived/chk_nginx.sh exited due to signal 15
查看资料发现是因为keepalived配置文件中,interval参数的原因,这个参数设置的数字必须大于检测脚本的心跳值 脚本中的sleep值为2,interval值应该大于2.