概述
使用keepalived完成主备部署,但由于nginx的负载均衡功能, 使得这两台服务器在应用方面是互为主主。使用这种部署方案的结果就是: 不管keepalived将请求分发到哪台服务器上都不会造成资源的浪费。
一、 keepalived主备搭建
1.1 准备工作
- 使用两台服务器来完成主备部署
- 两台服务器参数
操作系统 | 网卡 | ip | 名称 |
---|---|---|---|
centos 7 64位 | ens33 | 192.168.213.136 | 设备A |
centos 7 64位 | ens33 | 192.168.213.137 | 设备B |
1.2 搭建步骤
1.2.1 安装keepalived
- 设备A安装keepalived
-
安装前置库
yum install -y gcc pcre pcre-devel openssl openssl-devel gd gd-devel
=> 为了源码安装软件, 比如: nginx、redis等等 -
临时关闭防火墙: systemctl stop firewalld
-
yum install keepalived
-
修改配置文件
/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 127.0.0.1 #邮件服务器IP smtp_connect_timeout 30 router_id keepalived1 #本机路由ID标识 } vrrp_instance VI_1 { state MASTER # 主实例 interface ens33 # ens33的网卡, 使用ifconfig命令中查看 virtual_router_id 51 # 虚拟路由id, 要和副实例一致 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.213.188 #虚拟ip, 后面将根据这个ip来访问应用程序 } }
-
使用
service keepalived start
来启动服务 -
使用
service keepalived status
来查看服务实例
会在控制台中看到许多**Sending gratuitous ARP on ens33 for 192.168.213.188 **
的信息, 表示启动成功
若报错:Unable to load ipset library - libipset.so.11: cannot open shared object file: No such file or directory
, 则执行命令安装ipset,yum install ipset
, 安装完后再执行service keepalived status
来验证是否执行成功
-
- 设备B安装keepalived
- 步骤基本一致, 需要注意的几个的地方
- 是将
keepalivec.conf
的vrrp_instance VI_1节点的state改成BACKUP
, 标识它是备用的 router_id
要设置成与主实例不同, 主实例为keepalived1, 副实例改成keepalived2即可- 设置priority为50(比设备A的底就行)
- 验证它是否启动: 与上述
3,4
步一致
-
验证主备功能
- 使用nginx来实现,分别在设备A和设备B中安装nginx, 做如下操作
wget http://nginx.org/download/nginx-1.16.1.tar.gz
tar -zxvf nginx-1.16.1.tar.gz
mv nginx-1.16.1 /usr/local/nginx
cd /usr/local/nginx
./configure
(此步骤要有c语言的编译环境, )make && make install
cd html
- 设备A执行:
echo "keepalived1" > test.html
; 设备B执行:echo "keepalived2" > test.html
; mkdir /usr/local/nginx/logs
=> 创建日志文件夹, 否则nginx启动不了
10./usr/local/nginx/sbin/nginx
- 浏览器访问 192.168.213.188 /test.html
- 可以发现它在页面渲染出来的内容一直是keepalived
- 在设备A中执行如下命令:
service keepalived stop
- 再次在浏览器访问192.168.213.188/test.html
- 可以发现它渲染出来的内容变成了keepalived2,
- 由此证明, 备实例生效了
- 在设备A中执行如下命令:
service keepalived start
- 再次在浏览器中访问192.168.213.188/test.html
- 发现渲染出来的内容又变成了keepalived1
- 使用nginx来实现,分别在设备A和设备B中安装nginx, 做如下操作
-
如果运行结果和上述文字描述的一致的话, 那么
keepalived
主备部署搭建成功了
1.2.2 添加nginx负载均衡功能
-
设备A
-
修改nginx默认配置(/usr/local/nginx/conf/nginx.conf)为如下内容:
user root; worker_processes 8; worker_rlimit_nofile 65535; events { use epoll; worker_connections 4000; } http { include mime.types; default_type application/octet-stream; #charset utf-8; #默认编码 sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 120; include /usr/local/nginx/conf/upstream.conf; include /usr/local/nginx/conf/conf.d/*.conf; }
-
新建**/usr/local/nginx/conf/upstream.conf**文件, 并填充如下内容
upstream load_balancing{ server 192.168.213.136; # 用来访问设备A的nginx server 192.168.213.137; # 用来访问设备B的nginx }
-
新增**/usr/local/nginx/conf/conf.d/index.conf**文件, 并填充如下内容
server { listen 80; server_name 192.168.213.136; # nginx所在主机的ip root /usr/local/nginx/html; # 80端口访问的资源根路径 index index.html index.htm; location / { try_files $uri $uri/ /index.html; # vue.js 单页面配置 } location /api/ { #代理调用api解决跨域问题调用问题 proxy_set_header Host $http_host; # 一定要加这个, 设置请求的真实ip, 否则有可能请求后台项目出现400错误 proxy_pass http://load_balancing/; # 负载均衡指向upstream设置的域名 } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one location ~ /\.ht { deny all; } # location ~* \.(png|jpg|jpeg|gif|ico)$ { # expires 30d; # access_log off; # } location ~* \.(js|css|html|htm|txt)$ { expires 30d; access_log off; } #error_page 404 /404.html; access_log /usr/local/nginx/logs/access.log; # 80端口访问日志路径,如果没有/usr/local/nginx/logs/这个路径, 需要手动创建 error_log /usr/local/nginx/logs/error.log; # 80端口错误日志路径 }
-
-
设备B
- 操作与设备A完全一致, 但有一个地方不同
- 在创建
/usr/local/nginx/conf/conf.d/index.conf
文件时, 要将server_name需要改成192.168.213.137
- 在创建
- 操作与设备A完全一致, 但有一个地方不同
-
测试
- 在设备A中修改
/usr/local/nginx/html/index/html内容
, 修改Welcome to nginx!
为Welcome to nginx! Keepalived1
- 分别在浏览器中请求
192.168.213.188/api
, 浏览器应该会在Welcome to nginx! Keepalived1
和Welcome to nginx!
交替显示 - 若能交替显示, 则表示负载均衡成功, 并且主备的nginx都带有负载均衡功能, 就算把设备A的
keepalived
服务关掉, 也会交替显示, 因为此时进入的是备实例的nginx - 运行结果图
注意, 在使用负载均衡没使用静态资源test.html做例子是因为nginx的负载均衡同时用到了它的反向代理, 当使用反向代理后,要想访问一些静态资源是需要添加一些配置, 因为没添加这方面的配置所以使用的是nginx默认的index.html页面来做实验了。
- 在设备A中修改
1.2.3 关于上面步骤的不足点
- 设备A或者设备B重启后, 只有keepalived会自动启动(因为是通过yum安装的, 它自动设置了自动启动), 但此时它的nginx并没有自动启动, 所以在访问虚拟ip
192.168.6.188/api
时, 它检测到设备A的keepalived
服务还在(因为上面设置了, 设备A为主实例), 所以不会将请求分发到设备B去。 可是此时设备A中的nginx是挂的, 所以页面也挂了。 - 解决方案:
- 产生这个的原因: 因为设备A的keepalived的服务还在, 导致请求不会分发到设备B去, 因为设备A的nginx是挂的, 所以页面也挂了
- 根据产生原因,我们可以从两个大方向去解决这个问题
- 保证请求要进设备A
- 那么我们可以设置开机启动ngxin — 这个问题秒解决
- 或者利用keepalived自带执行脚本功能,需要在keepalived中配置下面一段代码
vrrp_script chk_http_port { script "/usr/sbin/nginx.sh" # nginx.sh脚本为启动nginx服务, 代码很简单, 就是验证没有nginx服务就启动它 interval 3 # 每隔3秒执行一次 weight -5 fall 2 rise 1 }
- 保证请求要进设备B
- 或者利用keepalived自带执行脚本功能,需要在keepalived中配置下面一段代码
vrrp_script chk_http_port { script "/usr/sbin/shutdown.sh" # shutdown.sh脚本为检测没有nginx进程, 则停止keepalived interval 3 # 每隔3秒执行一次 weight -5 fall 2 rise 1 }
- 或者利用keepalived自带执行脚本功能,需要在keepalived中配置下面一段代码
- 保证请求要进设备A