专题:Linux应用服务配置
各类Linux软件安装配置
更多内容请点击 我的博客 查看,欢迎来访。
系统架构
- Nginx实现后端多台业务服务器的负载均衡,当一台Web宕机后,并不影响访问;
- 多台Nginx实现高可用,配置VIP,当一台Nginx宕机后,虚拟IP自动转移到备用主机;
CentOS7配置网络
不能使用ifconfig
,使用ip xxx
查询IP相关的信息
# ip address
可以查看到网卡名为ens33
配置动态IP
先使用动态获取IP,前提要开启DHCP,由于测试环境是VMWare,使用NAT模式即可
修改网卡配置文件 vi /etc/sysconfig/network-scripts/ifcfg-ens33
(最后一个为网卡名称)
动态获取IP地址需要修改两处地方即可
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=dhcp # 修改
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
UUID=c6020abe-d007-4ca7-8f0c-c705f6792b09
DEVICE=ens33
ONBOOT=yes # 修改
修改后重启一下网络服务即可 systemctl restart network
接下来可以使用ssh远程连接了,查看获取到的IP
[root@centos7 ~]# ip address
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:37:71:33 brd ff:ff:ff:ff:ff:ff
inet 192.168.88.128/24 brd 192.168.88.255 scope global noprefixroute dynamic ens33
valid_lft 1598sec preferred_lft 1598sec
inet6 fe80::9d52:3661:696b:8573/64 scope link noprefixroute
valid_lft forever preferred_lft forever
配置静态IP
实际环境中,需要固定IP地址
设置静态IP地址与动态iIP差不多,也是要修改网卡配置文件 vi /etc/sysconfig/network-scripts/ifcfg-ens33
(最后一个为网卡名称)
BOOTPROTO=static
# ...
ONBOOT=yes
# 在最后加上几行,IP地址、子网掩码、网关、dns服务器
IPADDR=192.168.1.2
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=xxx.xxx.xxx.xxx
DNS2=8.8.8.8
如果习惯使用vim,使用下面的命令安装即可
[root@centos7 ~]# yum install vim
下面来创建测试环境,克隆当前的系统
使用python运行简单的Web服务
业务服WebSvr1【88.129】
查看ip
[root@centos7 ~]# ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:79:ad:91 brd ff:ff:ff:ff:ff:ff
inet 192.168.88.129/24 brd 192.168.88.255 scope global noprefixroute dynamic ens33
valid_lft 1536sec preferred_lft 1536sec
inet6 fe80::9d52:3661:696b:8573/64 scope link noprefixroute
valid_lft forever preferred_lft forever
创建html页面用于模拟web服务器
[root@centos7 ~]# vim index.html
Web Svr 1
启动web服务
[root@centos7 ~]# python -m SimpleHTTPServer 8080
Serving HTTP on 0.0.0.0 port 8080 ...
在本地可以访问
[root@centos7 ~]# curl 192.168.88.129:8080
Web Svr 1
但其他同一网段的浏览器无法访问 http://192.168.88.129:8080/ ,检查防火墙且关闭
# 查看防火墙状态
[root@centos7 ~]# firewall-cmd --state
running
# 停止firewall
[root@centos7 ~]# systemctl stop firewalld.service
[root@centos7 ~]# firewall-cmd --state
not running
# 禁止firewall开机启动
[root@centos7 ~]# systemctl disable firewalld.service
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
现在浏览器访问 http://192.168.88.129:8080/ 就正常了,页面显示Web Svr 1
业务服WebSvr2【88.130】
查看ip
[root@centos7 ~]# ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:41:d5:ed brd ff:ff:ff:ff:ff:ff
inet 192.168.88.130/24 brd 192.168.88.255 scope global noprefixroute dynamic ens33
valid_lft 1390sec preferred_lft 1390sec
inet6 fe80::9d52:3661:696b:8573/64 scope link tentative noprefixroute dadfailed
valid_lft forever preferred_lft forever
inet6 fe80::7b58:fa7c:8526:dd29/64 scope link noprefixroute
valid_lft forever preferred_lft forever
和1号配置类似,只需要把html模板改为2,方便后面测试观察
[root@centos7 ~]# vim index.html
# 添加下面内容
Web Svr 2
关闭防火墙,启动web服务,测试同网段浏览器访问
[root@centos7 ~]# systemctl stop firewalld.service
[root@centos7 ~]# systemctl disable firewalld.service
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@centos7 ~]# python -m SimpleHTTP
浏览器访问 http://192.168.88.130:8080/ ,页面显示Web Svr 2
这两台服务器都可以访问了,实际业务中,显示的内容应该是一样的,查询的是同一个数据库。
Nginx实现多个Web服务器负载均衡
Nginx是一个高性能Web服务器,通过upstream
模块可以实现多个Web服务器的负载均衡。
在克隆一台虚拟机,可以查看到它的IP
[root@centos7 ~]# ip address
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:9f:da:d2 brd ff:ff:ff:ff:ff:ff
inet 192.168.88.131/24 brd 192.168.88.255 scope global noprefixroute dynamic ens33
valid_lft 1715sec preferred_lft 1715sec
inet6 fe80::9d52:3661:696b:8573/64 scope link tentative noprefixroute dadfailed
valid_lft forever preferred_lft forever
inet6 fe80::7b58:fa7c:8526:dd29/64 scope link tentative noprefixroute dadfailed
valid_lft forever preferred_lft forever
inet6 fe80::9cb3:ef45:2493:99cb/64 scope link noprefixroute
valid_lft forever preferred_lft forever
安装nginx依赖包
[root@centos7 nginx-1.17.3]# yum install gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl-devel -y
下载nginx源码
访问 http://nginx.org/en/download.html 获取下载链接
复制下载链接,使用下面命令下载
[root@centos7 ~]# yum install wget -y
# 如果没安装wget,首先需要安装
[root@centos7 ~]# wget http://nginx.org/download/nginx-1.17.3.tar.gz
下载最新版的nginx,解压
[root@centos7 ~]# ls
index.html nginx-1.17.3.tar.gz
[root@centos7 ~]# tar -xzf nginx-1.17.3.tar.gz
[root@centos7 ~]# ls
index.html nginx-1.17.3 nginx-1.17.3.tar.gz
编译配置nginx
[root@centos7 nginx-1.17.3]# ./configure \
--prefix=/etc/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_dav_module \
--with-http_stub_status_module \
--with-threads \
--with-file-aio
# 执行完成后会看到下面回显
Configuration summary
+ using threads
+ using system PCRE library
+ using system OpenSSL library
+ using system zlib library
nginx path prefix: "/etc/nginx"
nginx binary file: "/etc/nginx/sbin/nginx"
nginx modules path: "/etc/nginx/modules"
nginx configuration prefix: "/etc/nginx"
nginx configuration file: "/etc/nginx/nginx.conf"
nginx pid file: "/var/run/nginx.pid"
nginx error log file: "/var/log/nginx/error.log"
nginx http access log file: "/var/log/nginx/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
编译参数说明
--prefix= 指向安装目录。
--sbin-path= 指定执行程序文件存放位置。
--modules-path= 指定第三方模块的存放路径。
--conf-path= 指定配置文件存放位置。
--error-log-path= 指定错误日志存放位置。
--pid-path= 指定pid文件存放位置。
--lock-path= 指定lock文件存放位置。
--user= 指定程序运行时的非特权用户。
--group= 指定程序运行时的非特权用户组。
--builddir= 指向编译目录。
--with-rtsig_module 启用rtsig模块支持。
--with-select_module 启用select模块支持,一种轮询处理方式,不推荐在高并发环境中使用,禁用:--without-select_module。
--with-poll_module 启用poll模块支持,功能与select相同,不推荐在高并发环境中使用。
--with-threads 启用thread pool支持。
--with-file-aio 启用file aio支持。
--with-http_ssl_module 启用https支持。
--with-http_v2_module 启用ngx_http_v2_module支持。
--with-ipv6 启用ipv6支持。
--with-http_realip_module 允许从请求报文头中更改客户端的ip地址,默认为关。
--with-http_addition_module 启用ngix_http_additon_mdoule支持(作为一个输出过滤器,分部分响应请求)。
--with -http_xslt_module 启用ngx_http_xslt_module支持,过滤转换XML请求 。
--with-http_image_filter_mdoule 启用ngx_http_image_filter_module支持,传输JPEG\GIF\PNG图片的一个过滤器,默认不启用,需要安装gd库。
--with-http_geoip_module 启用ngx_http_geoip_module支持,用于创建基于MaxMind GeoIP二进制文件相配的客户端IP地址的ngx_http_geoip_module变量。
--with-http_sub_module 启用ngx_http_sub_module支持,允许用一些其他文本替换nginx响应中的一些文本。
--with-http_dav_module 启用ngx_http_dav_module支持,增加PUT、DELETE、MKCOL创建集合,COPY和MOVE方法,默认为关闭,需要编译开启。
--with-http_flv_module 启用ngx_http_flv_module支持,提供寻求内存使用基于时间的偏移量文件。
--with-http_mp4_module 启用ngx_http_mp4_module支持,启用对mp4类视频文件的支持。
--with-http_gzip_static_module 启用ngx_http_gzip_static_module支持,支持在线实时压缩输出数据流。
--with-http_random_index_module 启用ngx_http_random_index_module支持,从目录中随机挑选一个目录索引。
--with-http_secure_link_module 启用ngx_http_secure_link_module支持,计算和检查要求所需的安全链接网址。
--with-http_degradation_module 启用ngx_http_degradation_module 支持允许在内存不足的情况下返回204或444代码。
--with-http_stub_status_module 启用ngx_http_stub_status_module 支持查看nginx的状态页。
--without-http_charset_module 禁用ngx_http_charset_module这一模块,可以进行字符集间的转换,从其它字符转换成UTF-8或者从UTF8转换成其它字符。它只能从服务器到客户端方向,只有一个字节的字符可以转换。
--without-http_gzip_module 禁用ngx_http_gzip_module支持,同--with-http_gzip_static_module功能一样。
--without-http_ssi_module 禁用ngx_http_ssi_module支持,提供了一个在输入端处理服务器包含文件(SSI)的过滤器。
--without-http_userid_module 禁用ngx_http_userid_module支持,该模块用来确定客户端后续请求的cookies。
--without-http_access_module 禁用ngx_http_access_module支持,提供了基于主机ip地址的访问控制功能。
--without-http_auth_basic_module 禁用ngx_http_auth_basic_module支持,可以使用用户名和密码认证的方式来对站点或部分内容进行认证。
--without-http_autoindex_module 禁用ngx_http_authindex_module,该模块用于在ngx_http_index_module模块没有找到索引文件时发出请求,用于自动生成目录列表。
--without-http_geo_module 禁用ngx_http_geo_module支持,这个模块用于创建依赖于客户端ip的变量。
--without-http_map_module 禁用ngx_http_map_module支持,使用任意的键、值 对设置配置变量。
--without-http_split_clients_module 禁用ngx_http_split_clients_module支持,该模块用于基于用户ip地址、报头、cookies划分用户。
--without-http_referer_module 禁用ngx_http_referer_modlue支持,该模块用来过滤请求,报头中Referer值不正确的请求。
--without-http_rewrite_module 禁用ngx_http_rewrite_module支持。该模块允许使用正则表达式改变URI,并且根据变量来转向以及选择配置。如果在server级别设置该选项,那么将在location之前生效,但如果location中还有更进一步的重写规则,location部分的规则依然会被执行。如果这个URI重写是因为location部分的规则造成的,那么location部分会再次被执行作为新的URI,这个循环会被执行10次,最后返回一个500错误。
--without-http_proxy_module 禁用ngx_http_proxy_module支持,http代理功能。
--without-http_fastcgi_module 禁用ngx_http_fastcgi_module支持,该模块允许nginx与fastcgi进程交互,并通过传递参数来控制fastcgi进程工作。
--without-http_uwsgi_module 禁用ngx_http_uwsgi_module支持,该模块用来使用uwsgi协议,uwsgi服务器相关。
--without-http_scgi_module 禁用ngx_http_scgi_module支持,类似于fastcgi,也是应用程序与http服务的接口标准。
--without-http_memcached_module 禁用ngx_http_memcached支持,用来提供简单的缓存,提高系统效率。
--without-http_limit_conn_module 禁用ngx_http_limit_conn_module支持,该模块可以根据条件进行会话的并发连接数进行限制。
--without-http_limit_req_module 禁用ngx_limit_req_module支持,该模块可以实现对于一个地址进行请求数量的限制。
--without-http_empty_gif_module 禁用ngx_http_empty_gif_module支持,该模块在内存中常驻了一个1*1的透明gif图像,可以被非常快速的调用。
--without-http_browser_module 禁用ngx_http_browser_mdoule支持,创建依赖于请求报头的值 。如果浏览器为modern,则$modern_browser等于modern_browser_value的值;如果浏览器为old,则$ancient_browser等于$ancient_browser_value指令分配的值;如果浏览器为MSIE,则$msie等于1。
--without-http_upstream_ip_hash_module 禁用ngx_http_upstream_ip_hash_module支持,该模块用于简单的负载均衡。
--with-http_perl_module 启用ngx_http_perl_module支持,它使nginx可以直接使用perl或通过ssi调用perl。
--with-perl_modules_path= 设定perl模块路径
--with-perl= 设定perl库文件路径
--http-log-path= 设定access log路径
--http-client-body-temp-path= 设定http客户端请求临时文件路径
--http-proxy-temp-path= 设定http代理临时文件路径
--http-fastcgi-temp-path= 设定http fastcgi临时文件路径
--http-uwsgi-temp-path= 设定http scgi临时文件路径
--http-scgi-temp-path= 设定http scgi临时文件路径
--without-http 禁用http server功能
--without-http-cache 禁用http cache功能
--with-mail 启用POP3、IMAP4、SMTP代理模块
--with-mail_ssl_module 启用ngx_mail_ssl_module支持
--without-mail_pop3_module 禁用pop3协议。
--without-mail_iamp_module 禁用iamp协议。
--without-mail_smtp_module 禁用smtp协议。
--with-google_perftools_module 启用ngx_google_perftools_mdoule支持,调试用,可以用来分析程序性能瓶颈。
--with-cpp_test_module 启用ngx_cpp_test_module支持。
--add-module= 指定外部模块路径,启用对外部模块的支持。
--with-cc= 指向C编译器路径。
--with-cpp= 指向C预处理路径。
--with-cc-opt= 设置C编译器参数,指定--with-cc-opt="-I /usr/lcal/include",如果使用select()函数,还需要同时指定文件描述符数量--with-cc-opt="-D FD_SETSIZE=2048"。 (PCRE库)
--with-ld-opt= 设置连接文件参数,需要指定--with-ld-opt="-L /usr/local/lib"。(PCRE库)
--with-cpu-opt= 指定编译的CPU类型,如pentium,pentiumpro,...amd64,ppc64...
--without-pcre 禁用pcre库。
--with-pcre 启用pcre库。
--with-pcre= 指向pcre库文件目录。
--with-pcre-opt= 在编译时为pcre库设置附加参数 。
--with-md5= 指向md5库文件目录。
--with-md5-opt= 编译时为md5库设置附加参数。
--with-md5-asm 使用md5汇编源。
--with-sha1= 指向sha1库文件目录。
--with-sha1-opt= 编译时为sha1库设置附加参数。
--with-sha1-asm 使用sha1汇编源。
--with-zlib= 指向zlib库文件目录。
--with-zlib-opt= 在编译时为zlib设置附加参数。
--with-zlib-asm= 为指定的CPU使用汇编源进行优化。
--with-libatomic 为原子内存的更新操作的实现提供一个架构。
--with-libatomic= 指向libatomic_ops的安装目录。
--with-openssl= 指向openssl安装目录。
--with-openssl-opt= 在编译时为openssl设置附加参数。
--with-debug 启用debug日志。
执行编译后安装
[root@centos7 nginx-1.17.3]# make && make install
手动启动nginx
[root@centos7 nginx-1.17.3]# /etc/nginx/sbin/nginx
nginx: [emerg] getpwnam("nginx") failed # 没有nginx用户
启动失败,创建nginx用户
# 创建nginx用户
[root@centos7 nginx-1.17.3]# useradd -r nginx
# 启动nginx
[root@centos7 nginx-1.17.3]# /etc/nginx/sbin/nginx
现在访问 http://192.168.88.131/ 可以看到nginx页面
创建nginx启动文件
需要在init.d
文件夹中创建nginx启动文件。 这样每次服务器重新启动init
进程都会自动启动Nginx。
[root@centos7 nginx]# cd /etc/init.d/
[root@centos7 init.d]# vim nginx
# 写入下面的内容
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemin
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /etc/nginx/nginx.conf
# pidfile: /var/run/nginx.pid
# user: nginx
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/etc/nginx/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/etc/nginx/nginx.conf"
lockfile=/var/run/nginx.lock
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest || return $?
stop
start
}
reload() {
configtest || return $?
echo -n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac
校验配置文件依次输入下列命令
[root@centos7 init.d]# chkconfig --add nginx
[root@centos7 init.d]# chkconfig --level 345 nginx on
给这个文件添加执行权限
[root@centos7 init.d]# chmod +x nginx
[root@centos7 init.d]# ls
functions netconsole network nginx README
启动Nginx服务
[root@centos7 init.d]# service nginx start
Reloading systemd: [ 确定 ]
Starting nginx (via systemctl): [ 确定 ]
# 查看启动状态
[root@centos7 init.d]# service nginx status
# 如果可以通过系统日志检查发生错误的原因
# 如果修改了nginx.conf配置文件,使用reload重启
[root@centos7 nginx]# service nginx reload
Reloading nginx configuration (via systemctl): Warning: nginx.service changed on disk. Run 'systemctl daemon-reload' to reload units.
[ 确定 ]
防火墙允许80端口
Linux 服务器上防火墙会端口拦截,所以需要在防火墙中开放80 端口,也可以直接关闭防火墙,这儿提供允许80端口方法,但之前已经关闭防火墙了
# 允许80端口
firewall-cmd --permanent --add-port=80/tcp --zone=public
# 重新加载防火墙配置
firewall-cmd --reload
代理服Nginx1【88.131】
修改nginx.conf配置文件
[root@centos7 nginx-1.17.3]# cd /etc/nginx/
[root@centos7 nginx]# mv nginx.conf nginx.conf.bak
# 首个字符以#开头
[root@centos7 nginx]# egrep -v '^#' nginx.conf.bak
# 首个字符已#开头,# 前面有空格
[root@centos7 nginx]# egrep -v '^#|^[ ]*#' nginx.conf.bak
# 再去掉空行
[root@centos7 nginx]# egrep -v '^#|^[ ]*#|^$' nginx.conf.bak
查看无注释的配置文件,使用>>
将其写入新的文件
[root@centos7 nginx]# egrep -v '^#|^[ ]*#|^$' nginx.conf.bak >> nginx.conf
[root@centos7 nginx]# cat nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
重新加载nginx配置
# 测试配置文件是否正常
[root@centos7 nginx]# /etc/nginx/sbin/nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# 重新加载配置文件
[root@centos7 nginx]# /etc/nginx/sbin/nginx -s reload
如果是通过service nginx start
启动的nginx,建议通过service nginx reload
来重新加载。
接下来浏览器访问 http://192.168.88.129/ 也是正常的
配置Nginx负载均衡
可以通过访问 http://192.168.88.129/ 代理显示 http://192.168.88.129:8080/ 和 http://192.168.88.130:8080/ 的页面
修改 nginx.conf 文件
[root@centos7 init.d]# cd /etc/nginx/
[root@centos7 nginx]# vim nginx.conf
# 修改为以下配置
worker_processes 1;
events {
# 并发连接数
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# websvr 服务器集群(也可以叫负载均衡池)
upstream websvr {
server 192.168.88.129:8080 weight=1;
server 192.168.88.130:8080 weight=2;
}
server {
# 监听80端口
listen 80;
# 用来指定ip地址或者域名,多个配置之间用空格分隔
server_name 192.168.88.131;
location / {
# 将所有请求交给websvr集群去处理
proxy_pass http://websvr;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
现在重启nginx
[root@centos7 nginx]# /etc/nginx/sbin/nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# 测试没问题后进行reload
[root@centos7 nginx]# /etc/nginx/sbin/nginx -s reload
# 也可以使用下面的命令重新加载
[root@centos7 nginx]# service nginx reload
Reloading nginx configuration (via systemctl): [ 确定 ]
websvr
名称可自定义,可以指明这些服务器的含义。
也就是只需要添加upstream websvr
和proxy_pass
就可以实现负载均衡。
Nginx转发原理
访问 http://192.168.88.131/ ,页面上就会出现Web Svr 1和Web Svr 2切换,会根据权重选择服务器,weight
值越大,权重越高,也就是重复刷新该页面,平均Web Svr 2出现2次,Web Svr 1出现1次。
Nginx收到请求后,将所有请求交给websvr
集群处理,假如此刻【88.129】的websvr挂掉了,也不会影响Web访问,因为Nginx会自动将请求发给【88.130】,此时刷新 http://192.168.88.129/ 页面上始终只会显示Web Svr 2。重新启动【88.129】的web服务[root@centos7 ~]# python -m SimpleHTTPServer 8080
,刷新页面,又会访问 http://192.168.88.131/ ,页面上就会出现Web Svr 1和Web Svr 2切换了。
到目前为止,仍然不能实现高可用,虽然web服务可以这样做,单点故障可以通过这种方式处理,但是如果nginx服务故障了,整个系统基本就无法访问了,那么就需要使用多台Nginx来保障。
多个Nginx协同工作,Nginx高可用【双机主从模式】
先查看新增的IP
[root@centos7 ~]# ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:7e:35:d1 brd ff:ff:ff:ff:ff:ff
inet 192.168.88.132/24 brd 192.168.88.255 scope global noprefixroute dynamic ens33
valid_lft 1776sec preferred_lft 1776sec
inet6 fe80::9d52:3661:696b:8573/64 scope link tentative noprefixroute dadfailed
valid_lft forever preferred_lft forever
inet6 fe80::7b58:fa7c:8526:dd29/64 scope link tentative noprefixroute dadfailed
valid_lft forever preferred_lft forever
inet6 fe80::9cb3:ef45:2493:99cb/64 scope link tentative noprefixroute dadfailed
valid_lft forever preferred_lft forever
可以看到增加的一台用于Nginx的服务器IP为 192.168.88.132
代理服Nginx2【88.132】
新增一台nginx服务,和之前的配置一样,只需要修改 nginx.conf 即可
[root@centos7 ~]# vim /etc/nginx/nginx.conf
events {
# 并发连接数
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# websvr 服务器集群
upstream websvr {
server 192.168.88.129:8080 weight=1;
server 192.168.88.130:8080 weight=2;
}
server {
# 监听80端口
listen 80;
# 用来指定ip地址或者域名,多个配置之间用空格分隔
server_name 192.168.88.132;
location / {
# 将所有请求交给websvr集群去处理
proxy_pass http://websvr;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
# 修改完成后重新加载nginx配置
[root@centos7 ~]# service nginx reload
Reloading nginx configuration (via systemctl): [ 确定 ]
现在访问 http://192.168.88.132/ 也可以得到和 http://192.168.88.131/ 类似的结果。
这两台Nginx服务器的IP是不同的,那怎么做才能将这两台nginx服务器一起工作呢?
了解keepalived
- 基于VRRP协议:路由器和操作系统层面的协议,虚拟路由器动态转移IP;
- 需要安装keepalived软件;
- 需要配置:有主备(master/backup)两个角色,可以配置多重定期监控来实现应用的高可用性;
- keepalived命令直接指定配置文件启动,生产环境需要配置自启动。
不仅可以做Nginx的高可用,也可以做其他的例如Mysql高可用。
一个机器可以绑定多个IP,可以在Nginx上使用keepalived绑定一个虚拟IP,当某一台Nginx出现问题,这个虚拟IP就会自动转移到另一台。
高可用故障切换转移原理
Keepalived高可用故障切换,是通过VRRP虚拟路由器冗余协议来实现的。
在Keepalived服务正常工作时,主Master节点会不断地向备节点发送(多播的方式)心跳消息,用以告诉备Backup节点自己还活着,当主Master节点发生故障时,就无法发送心跳消息,备节点无法检测到来自主Master节点心跳了,于是调用自身的接管程序,接管主Master节点的IP资源及服务。而当主Master节点恢复时,备Backup节点又会释放主节点故障时自身接管的IP资源及服务,恢复到原来的备用角色。
VRRP协议
虚拟路由冗余协议,可以认为是实现路由器高可用的协议,即将N台提供相同功能的路由器组成一个路由器组,这个组里面有一个master和多个backup,master上面有一个对外提供服务的vip(该路由器所在局域网内其他机器的默认路由/网关为该vip),master会发组播,当backup收不到vrrp包时就认为master宕掉了,这时就需要根据VRRP的优先级来选举一个backup当master。这样的话就可以保证路由器的高可用了。
keepalived主要有三个模块
分别是core、check和vrrp。
core模块为keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析。
check负责健康检查,包括常见的各种检查方式。
vrrp模块是来实现VRRP协议的。
代理服Nginx1【88.131】安装keepalived主虚拟IP88.133
下载keepalived源码
访问 https://www.keepalived.org/download.html 获取下载地址
[root@centos7 ~]# wget https://www.keepalived.org/software/keepalived-2.0.18.tar.gz
2019-09-17 09:28:21 (178 KB/s) - 已保存 “keepalived-2.0.18.tar.gz” [1015958/1015958])
[root@centos7 ~]# tar xzf keepalived-2.0.18.tar.gz
[root@centos7 ~]# ls
keepalived-2.0.18 nginx-1.17.3 index.html keepalived-2.0.18.tar.gz nginx-1.17.3.tar.gz
配置keepalived,编译安装
[root@centos7 ~]# cd keepalived-2.0.18
# 配置
[root@centos7 keepalived-2.0.18]# ./configure --prefix=/etc/keepalived
# 如果出现下面错误,安装依赖包
*** WARNING - this build will not support IPVS with IPv6. Please install libnl/libnl-3 dev libraries to support IPv6 with IPVS.
[root@centos7 keepalived-2.0.18]# yum -y install libnl libnl-devel
# 编译安装
[root@centos7 keepalived-2.0.18]# make && make install
keepalived将安装到 /etc/keepalived
目录,当然,很多教程是安装在/usr/local/keepalived
,影响不大,也可以自定义安装路径,将所有软件都安装到一个目录,如果没有该目录会自动创建
运行前配置
[root@centos7 keepalived-2.0.18]# ls
aclocal.m4 ChangeLog CONTRIBUTORS install-sh Makefile.am TODO
ar-lib compile COPYING keepalived Makefile.in
AUTHOR config.log depcomp keepalived.spec missing
bin config.status doc keepalived.spec.in README
bin_install configure genhash lib README.md
build_setup configure.ac INSTALL Makefile snap
# 从源码包中复制 keepalived 服务启动脚本到默认的目录
[root@centos7 keepalived-2.0.18]# cp keepalived/etc/init.d/keepalived /etc/init.d/
[root@centos7 keepalived-2.0.18]# chmod +x /etc/init.d/keepalived
# 从安装目录复制自启动文件到系统环境中
[root@centos7 keepalived-2.0.18]# cd /etc/keepalived/
[root@centos7 keepalived]# ls
bin etc sbin share
[root@centos7 keepalived]# cp etc/sysconfig/keepalived /etc/sysconfig/
# 复制配置文件到指定目录,也可以不复制,直接创建新的
[root@centos7 keepalived]# cp etc/keepalived/keepalived.conf /etc/keepalived/
可以在安装目录 /etc/keepalived/etc/keepalived/samples
下查看官方示例
[root@centos7 samples]# pwd
/etc/keepalived/etc/keepalived/samples
[root@centos7 samples]# ls
client.pem keepalived.conf.track_interface
dh1024.pem keepalived.conf.virtualhost
keepalived.conf.conditional_conf keepalived.conf.virtual_server_group
keepalived.conf.fwmark keepalived.conf.vrrp
keepalived.conf.HTTP_GET.port keepalived.conf.vrrp.localcheck
keepalived.conf.inhibit keepalived.conf.vrrp.lvs_syncd
keepalived.conf.IPv6 keepalived.conf.vrrp.routes
keepalived.conf.misc_check keepalived.conf.vrrp.rules
keepalived.conf.misc_check_arg keepalived.conf.vrrp.scripts
keepalived.conf.quorum keepalived.conf.vrrp.static_ipaddress
keepalived.conf.sample keepalived.conf.vrrp.sync
keepalived.conf.SMTP_CHECK root.pem
keepalived.conf.SSL_GET sample.misccheck.smbcheck.sh
keepalived.conf.status_code sample_notify_fifo.sh
主keepalived配置keepalived.conf
修改 keepalived.conf 配置文件,默认是 /etc/keepalived/keepalived.conf
,如果是其他名字,启动keepalived就需要指定配置文件 keepalived -f keepalived_xxx.conf
[root@centos7 keepalived]# pwd
/etc/keepalived
# 删除原来的配置文件后再新增创建
[root@centos7 keepalived]# rm keepalived.conf -y
[root@centos7 keepalived]# vim keepalived.conf
# 添加下面的内容
global_defs {
# (VI_1) the virtual router id must be set,运行keepalived的机器的一个标识,通常可设为hostname。故障发生时,发邮件时显示在邮件主题中的信息
router_id chk_niginx_133
# default user 'keepalived_script' for script execution does not exist - please create.需添加下面配置
script_user root
enable_script_security
}
vrrp_script chk_nginx {
# 指定监控脚本,检测nginx服务是否正常运行
script "/etc/keepalived/chk_nginx.sh"
# 指定监控时间,每10s执行一次
interval 10
# 脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5
# weight -5
# # 检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间)
# fall 2
# 检测1次成功就算成功。但不修改优先级
# rise 1
}
# keepalived在同一virtual_router_id中priority(0-255)最大的会成为master,也就是接管VIP,当priority最大的主机发生故障后,priority较小将会接管。
vrrp_instance VI_1 {
# 指定keepalived的角色,主机设置为MASTER,备用机设置为BACKUP,注意这里的state指定instance(Initial)的初始状态,就是说在配置好后,这台服务器的初始状态就是这里指定的,但这里指定的不算,还是得要通过竞选通过优先级来确定。如果这里设置为MASTER,但如若他的优先级不及另外一台,那么这台在发送通告时,会发送自己的优先级,另外一台发现优先级不如自己的高,那么他会就回抢占为MASTER。
state MASTER
# 指定HA监测网络的接口。centos7使用 ip addr 获取
interface ens33
# 发送多播数据包时的源IP地址,这里实际上就是在哪个地址上发送VRRP通告,这个非常重要,一定要选择稳定的网卡端口来发送,这里相当于heartbeat的心跳端口,如果没有设置那么就用默认的绑定的网卡的IP,也就是interface指定的IP地址
# mcast_src_ip 192.168.88.xx
# 主备的virtual_router_id必须一样,可以设置为IP后一组:must be between 1 & 255
virtual_router_id 133
# 优先级值,在同一个vrrp_instance下, MASTRE 一定要高于 BAUCKUP,MASTER恢复后,BACKUP自动交接
priority 100
# VRRP 广播周期秒数,如果没检测到该广播,就被认为服务挂了,将切换主备
advert_int 1
# 设置验证类型和密码。主从必须一样
authentication {
# 设置vrrp验证类型,主要有PASS和AH两种
auth_type PASS
# 加密的密码,两台服务器一定要一样,才能正常通信
auth_pass passwd
}
track_script {
# 执行监控的服务,引用VRRP脚本,即在 vrrp_script 部分指定的名字。定期运行它们来改变优先级
chk_nginx
}
virtual_ipaddress {
# VRRP HA 虚拟地址 如果有多个VIP,继续换行填写
192.168.88.133
}
}
指定虚拟IP: 192.168.88.133 需要为未使用,配置完成后可通过 http://192.168.88.133/ 访问后端服务。
主keepalived配置监控脚本chk_nginx.sh
创建一个脚本,用于在keepalived中执行
[root@centos7 keepalived]# pwd
/etc/keepalived
[root@centos7 keepalived]# vim chk_nginx.sh
# 添加下面脚本
#!/bin/bash
# 查看是否有 nginx进程 把值赋给变量counter
counter=`ps -C nginx --no-header |wc -l`
# 如果没有进程值得为 0
if [ $counter -eq 0 ];then
# 尝试启动nginx
echo "Keepalived Info: Try to start nginx" >> /var/log/messages
/etc/nginx/sbin/nginx
sleep 3
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
# 输出日至道系统消息
echo "Keepalived Info: Unable to start nginx" >> /var/log/messages
# 如果还没没启动,则结束 keepalived 进程
# killall keepalived
# 或者停止
/etc/init.d/keepalived stop
exit 1
else
echo "Keepalived Info: Nginx service has been restored" >> /var/log/messages
exit 0
fi
else
# 状态正常
echo "Keepalived Info: Nginx detection is normal" >> /var/log/messages;
exit 0
fi
# 接下来授予执行权限
[root@centos7 keepalived]# chmod +x chk_nginx.sh
# 测试脚本是否正常使用
[root@centos7 keepalived]# ./chk_nginx.sh
执行前可以通过下面命令实时查看 messages 中的输出日志
[root@centos7 keepalived]# tail -f /var/log/messages
# 如果nginx关闭
Keepalived Info: Try to start nginx
Keepalived Info: Nginx service has been restored
# nginx正常打开
Keepalived Info: Nginx detection is normal
当nginx检测正常,就会返回0;检测没有了,返回1,但是keepalived似乎不是检测这个返回值来实现转移,而是检测keepalived服务是否存在,来释放本地VIP后,最终转移虚拟IP,到另一台服务器。
启动keepalived服务及开机启动
启动keepalived
启动服务,查看服务启动情况
# 启动keepalived
[root@centos7 keepalived]# service keepalived start
Starting keepalived (via systemctl): [ 确定 ]
# 查看进程不存在,说明没有启动成功
[root@centos7 keepalived]# ps -aux |grep keepalived
root 30574 0.0 0.1 112724 1000 pts/0 R+ 13:31 0:00 grep --color=auto keepalived
但是查看日志
[root@centos7 keepalived]# tail -f /var/log/messages
Sep 17 13:28:00 centos7 Keepalived_vrrp[30570]: WARNING - default user 'keepalived_script' for script execution does not exist - please create.
在 global_defs
中添加
script_user root
enable_script_security
继续处理
# 解决这个后又有下面的提示
Sep 17 13:47:48 centos7 Keepalived_vrrp[30675]: (Line 18) number '88133' outside range [1, 255]
Sep 17 13:47:48 centos7 Keepalived_vrrp[30675]: (Line 18) (VI_1): VRID '88133' not valid - must be between 1 & 255
Sep 17 13:47:48 centos7 Keepalived_vrrp[30675]: (VI_1) the virtual router id must be set
在 global_defs
中添加
router_id chk_niginx_133
解决日志中的错误提示后,通过service keepalived start
命令可以启动 keepalived,并且在 messages中可以查看shell中显示的日志
Keepalived Info: Nginx detection is normal
Keepalived Info: Nginx detection is normal
Keepalived Info: Nginx detection is normal
Keepalived Info: Nginx detection is normal
每10s检测1次。
测试关闭nginx
关闭后查看日志中的输出内容
[root@centos7 keepalived]# /etc/nginx/sbin/nginx -s stop
# 正在尝试重启nginx成功
Keepalived Info: Try to start nginx
Keepalived Info: Nginx service has been restored
Keepalived Info: Nginx detection is normal
切记在脚本中如果通过 /etc/nginx/sbin/nginx
命令启动的nginx,也需要使用 /etc/nginx/sbin/nginx -s stop
管理,如果使用的``
访问 http://192.168.88.133/ 也是可以正常显示的,也就是绑定的IP成功了
设置keepalived开机启动
[root@centos7 keepalived]# chkconfig keepalived on
注意:正在将请求转发到“systemctl enable keepalived.service”。
Created symlink from /etc/systemd/system/multi-user.target.wants/keepalived.service to /usr/lib/systemd/system/keepalived.service
# 或者是这两命令配置开机自启动
[root@centos7 keepalived]# systemctl enable keepalived
代理服Nginx2【88.132】安装keepalived备虚拟IP88.133
下载配置编译安装
# 下载安装
[root@centos7 ~]# wget https://www.keepalived.org/software/keepalived-2.0.18.tar.gz
[root@centos7 ~]# tar xzf keepalived-2.0.18.tar.gz
[root@centos7 ~]# cd keepalived-2.0.18
[root@centos7 keepalived-2.0.18]# yum -y install libnl libnl-devel
[root@centos7 keepalived-2.0.18]# ./configure --prefix=/etc/keepalived
[root@centos7 keepalived-2.0.18]# make && make install
# 复制配置文件
[root@centos7 keepalived-2.0.18]# cp keepalived/etc/init.d/keepalived /etc/init.d/
[root@centos7 keepalived-2.0.18]# chmod +x /etc/init.d/keepalived
[root@centos7 keepalived-2.0.18]# cd /etc/keepalived/
[root@centos7 keepalived]# cp etc/sysconfig/keepalived /etc/sysconfig/
备keepalived配置keepalived.conf
注意需要改变的内容:state BACKUP
、priority 90
备优先级一定小于主,其他基本一致
[root@centos7 keepalived]# pwd
/etc/keepalived
[root@centos7 keepalived]# vim keepalived.conf
global_defs {
# (VI_1) the virtual router id must be set
router_id chk_niginx_133
# default user 'keepalived_script' for script execution does not exist - please create.需添加下面配置
script_user root
enable_script_security
}
vrrp_script chk_nginx {
# 指定监控脚本
script "/etc/keepalived/chk_nginx.sh"
# 指定监控时间,每10s执行一次
interval 10
}
vrrp_instance VI_1 {
# 主机设置为MASTER,备用机设置为BACKUP
state BACKUP
# 监测网卡名称,centos7使用 ip addr 获取
interface ens33
# 主备的virtual_router_id必须一样,可以设置为IP后一组:must be between 1 & 255
virtual_router_id 133
# 权重值 MASTRE 一定要高于 BAUCKUP
priority 90
# VRRP 广播周期秒数,如果没检测到该广播,就呗认为服务挂了,将切换主备
advert_int 1
authentication {
# 加密
auth_type PASS
# 加密的密码,两台服务器一定要一样,不然会出错
auth_pass passwd
}
track_script {
# 执行监控的服务
chk_nginx
}
virtual_ipaddress {
# VIP 虚拟IP地址
192.168.88.133
}
}
备keepalived配置监控脚本chk_nginx.sh
脚本和主keepalived的 chk_nginx.sh 一样即可。
[root@centos7 keepalived]# vim chk_nginx.sh
#!/bin/bash
# 查看是否有 nginx进程 把值赋给变量counter
counter=`ps -C nginx --no-header |wc -l`
# 如果没有进程值得为 0
if [ $counter -eq 0 ];then
# 尝试启动nginx
echo "Keepalived Info: Try to start nginx" >> /var/log/messages
/etc/nginx/sbin/nginx
sleep 3
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
# 输出日至道系统消息
echo "Keepalived Info: Unable to start nginx" >> /var/log/messages
# 如果还没没启动,则结束 keepalived 进程
# killall keepalived
# 或者停止
/etc/init.d/keepalived stop
exit 1
else
echo "Keepalived Info: Nginx service has been restored" >> /var/log/messages
exit 0
fi
else
# 状态正常
echo "Keepalived Info: Nginx detection is normal" >> /var/log/messages;
exit 0
fi
[root@centos7 keepalived]# chmod +x chk_nginx.sh
[root@centos7 keepalived]# ./chk_nginx.sh
# 在系统消息中显示:Keepalived Info: Nginx detection is normal
启动keepalived服务及开机启动
[root@centos7 keepalived]# service keepalived start
Starting keepalived (via systemctl): [ 确定 ]
# 查看日志
Sep 17 14:34:31 centos7 Keepalived_vrrp[24328]: VRRP_Script(chk_nginx) succeeded
Sep 17 14:34:31 centos7 Keepalived_vrrp[24328]: (VI_1) Entering BACKUP STATE
Keepalived Info: Nginx detection is normal
Keepalived Info: Nginx detection is normal
# 设置开机启动
[root@centos7 keepalived]# systemctl enable keepalived
Created symlink from /etc/systemd/system/multi-user.target.wants/keepalived.service to /usr/lib/systemd/system/keepalived.service.
keepalived如果有防火墙配置
# 指定keepalived配置的网卡:ens33,固定的VRRP广播地址:224.0.0.18
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ens33 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 --out-interface ens33 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --reload
# 查看配置的规则
firewall-cmd --direct --get-rules ipv4 filter INPUT
firewall-cmd --direct --get-rules ipv4 filter OUTPUT
解决多组Keepalived服务器在一个局域网的冲突问题
当在同一个局域网内部署了多组Keepalived服务器对,而又未使用专门的心跳线通信时,可能会发生高可用接管的严重故障问题。之前已经讲解过Keepalived高可用功能是通过VRRP协议实现的,VRRP协议默认通过IP多播的形式实现高可用对之间的通信,如果同一个局域网内存在多组Keepalived服务器对,就会造成IP多播地址冲突问题,导致接管错乱,不同组的Keepalived都会使用默认的224.0.0.18作为多播地址。此时的解决办法是,在同组的Keepalived服务器所有的配置文件里指定独一无二的多播地址,配置如下:
global_defs { #全局配置
router_id LVS_19 #服务标识
vrrp_mcast_group4 224.0.0.19 #这个就是指定多播地址的配置
}
- 不同实例的通信认证密码也最好不同,以确保接管正常。
- 另一款高可用软件Heartbeat,如果采用多播方式实现主备通信,同样会有多播地址冲突问题。
测试主备Nginx自动切换
keepalived监控Nginx的状态
经过前面的配置,如果master主服务器的keepalived停止服务,backup从服务器会自动接管VIP对外服务;一旦主服务器的keepalived恢复,会重新接管VIP。
keepalived支持配置监控脚本,可以通过脚本监控Nginx的状态,如果状态不正常则进行一系列的操作,最终仍不能恢复Nginx则杀掉keepalived,使得从服务器能够接管服务。
如何监控Nginx的状态
最简单的做法是监控Nginx进程,更靠谱的做法是检查NginX端口,最靠谱的做法是检查多个url能否获取到页面。
keepalived.conf 中vrrp_script
配置区的script一般有2种写法:
- 通过脚本执行的返回结果,所以脚本就需要返回
exit 0
,或exit 1
,keepalived收到这个返回值之后,如果配置了weight -5
这种方式,则改变优先级,keepalived继续发送通告消息,backup比较优先级再决定。这是直接监控Nginx进程的方式。 - 脚本里面检测到异常,直接关闭keepalived进程,backup机器接收不到advertisement会抢占IP。这是检查NginX端口的方式。
对于改变keepalived优先级方式:
通过shell脚本判断,但有异常时exit 1
,正常退出exit 0
,然后keepalived根据动态调整的 vrrp_instance
优先级选举决定是否抢占VIP:
- 如果脚本执行结果为0,并且
weight
配置的值大于0,则优先级相应的增加,例如weight -5
,则priority 100
变为priority 105
- 如果脚本执行结果为1,并且
weight
配置的值小于0,则优先级相应的减少,例如weight -5
,则priority 100
变为priority 95
- 其他情况,原本配置的优先级不变,即配置文件中priority对应的值。
提示:
- 优先级不会不断的提高或者降低,可以编写多个检测脚本并为每个检测脚本设置不同的
weight
(在配置中列出就行) - 不管提高优先级还是降低优先级,最终优先级的范围在[1,254],不会出现优先级小于等于0或者优先级大于等于255的情况
在MASTER节点的 vrrp_instance 中 配置 nopreempt
,当它异常恢复后,即使它 priority
更高也不会抢占,这样可以避免正常情况下做无谓的切换,以上可以做到利用脚本检测业务进程的状态,并动态调整优先级从而实现主备切换。
测试虚拟IP转移
在转移过程中可以通过ap addr
查看到指定的网卡会出现2个IP,即一个为原本的IP,另一个为转移后的虚拟IP。
关闭主Nginx1
# 主机
# 注释启动nginx的代码,也就是把 chk_nginx.sh脚本中的/etc/nginx/sbin/nginx注释掉,不让其发生异常时自动启动
# 然后停止nginx
[root@centos7 keepalived]# /etc/nginx/sbin/nginx -s stop
# 可以看到主机停掉keepalived
Keepalived Info: Nginx detection is normal
Keepalived Info: Nginx detection is normal
Keepalived Info: Nginx detection is normal
Keepalived Info: Try to start nginx
Keepalived Info: Unable to start nginx
Sep 17 14:46:04 centos7 Keepalived[32308]: Stopping
Sep 17 14:46:04 centos7 systemd: Stopping LVS and VRRP High Availability Monitor...
Sep 17 14:46:04 centos7 Keepalived_vrrp[32309]: (VI_1) sent 0 priority
Sep 17 14:46:04 centos7 Keepalived_vrrp[32309]: (VI_1) removing VIPs.
Sep 17 14:46:05 centos7 Keepalived_vrrp[32309]: Stopped - used 0.002880 user time, 0.030797 system time
Sep 17 14:46:05 centos7 Keepalived[32308]: Stopped Keepalived v2.0.18 (07/26,2019)
Sep 17 14:46:05 centos7 systemd: Stopped LVS and VRRP High Availability Monitor.
# IP信息变化
[root@centos7 ~]# ip add
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:9f:da:d2 brd ff:ff:ff:ff:ff:ff
inet 192.168.88.131/24 brd 192.168.88.255 scope global noprefixroute dynamic ens33
valid_lft 1047sec preferred_lft 1047sec
# 备机继续提供服务,已经变为MASTER
Keepalived Info: Nginx detection is normal
Keepalived Info: Nginx detection is normal
Keepalived Info: Nginx detection is normal
Sep 17 14:46:04 centos7 Keepalived_vrrp[24328]: (VI_1) Backup received priority 0 advertisement
Sep 17 14:46:05 centos7 Keepalived_vrrp[24328]: (VI_1) Receive advertisement timeout
Sep 17 14:46:05 centos7 Keepalived_vrrp[24328]: (VI_1) Entering MASTER STATE
Sep 17 14:46:05 centos7 Keepalived_vrrp[24328]: (VI_1) setting VIPs.
Sep 17 14:46:05 centos7 Keepalived_vrrp[24328]: Sending gratuitous ARP on ens33 for 192.168.88.133
Sep 17 14:46:05 centos7 Keepalived_vrrp[24328]: (VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.88.133
Sep 17 14:46:05 centos7 Keepalived_vrrp[24328]: Sending gratuitous ARP on ens33 for 192.168.88.133
Sep 17 14:46:05 centos7 Keepalived_vrrp[24328]: Sending gratuitous ARP on ens33 for 192.168.88.133
Sep 17 14:46:05 centos7 Keepalived_vrrp[24328]: Sending gratuitous ARP on ens33 for 192.168.88.133
Sep 17 14:46:05 centos7 Keepalived_vrrp[24328]: Sending gratuitous ARP on ens33 for 192.168.88.133
Sep 17 14:46:10 centos7 Keepalived_vrrp[24328]: Sending gratuitous ARP on ens33 for 192.168.88.133
Sep 17 14:46:10 centos7 Keepalived_vrrp[24328]: (VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.88.133
Sep 17 14:46:10 centos7 Keepalived_vrrp[24328]: Sending gratuitous ARP on ens33 for 192.168.88.133
# IP信息变化
[root@centos7 ~]# ip add
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:7e:35:d1 brd ff:ff:ff:ff:ff:ff
inet 192.168.88.132/24 brd 192.168.88.255 scope global noprefixroute dynamic ens33
valid_lft 1790sec preferred_lft 1790sec
inet 192.168.88.133/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::9d52:3661:696b:8573/64 scope link tentative noprefixroute dadfailed
也就是主Nginx1停了后,虚拟IP 88.133 自动从 Nginx1(主) 转移到Nginx2(备)
重启主Nginx1
# 现在启动主Nginx
[root@centos7 keepalived]# /etc/nginx/sbin/nginx
[root@centos7 keepalived]# service keepalived start
Starting keepalived (via systemctl): [ 确定 ]
# 主机
Sep 17 14:47:31 centos7 Keepalived[32435]: Command line: '/etc/keepalived/sbin/keepalived' '-D'
Sep 17 14:47:31 centos7 Keepalived[32435]: Opening file '/etc/keepalived/keepalived.conf'.
Sep 17 14:47:31 centos7 systemd: PID file /run/keepalived.pid not readable (yet?) after start.
Sep 17 14:47:31 centos7 Keepalived[32436]: Starting VRRP child process, pid=32437
Sep 17 14:47:31 centos7 systemd: Started LVS and VRRP High Availability Monitor.
Sep 17 14:47:31 centos7 Keepalived_vrrp[32437]: Registering Kernel netlink reflector
Sep 17 14:47:31 centos7 Keepalived_vrrp[32437]: Registering Kernel netlink command channel
Sep 17 14:47:31 centos7 Keepalived_vrrp[32437]: Opening file '/etc/keepalived/keepalived.conf'.
Sep 17 14:47:31 centos7 Keepalived_vrrp[32437]: Assigned address 192.168.88.131 for interface ens33
Sep 17 14:47:31 centos7 Keepalived_vrrp[32437]: Assigned address fe80::9d52:3661:696b:8573 for interface ens33
Sep 17 14:47:31 centos7 Keepalived_vrrp[32437]: Registering gratuitous ARP shared channel
Sep 17 14:47:31 centos7 Keepalived_vrrp[32437]: (VI_1) removing VIPs.
Sep 17 14:47:31 centos7 Keepalived_vrrp[32437]: VRRP sockpool: [ifindex(2), family(IPv4), proto(112), unicast(0), fd(11,12)]
Keepalived Info: Nginx detection is normal
Sep 17 14:47:31 centos7 Keepalived_vrrp[32437]: VRRP_Script(chk_nginx) succeeded
Sep 17 14:47:31 centos7 Keepalived_vrrp[32437]: (VI_1) Entering BACKUP STATE
Sep 17 14:47:32 centos7 Keepalived_vrrp[32437]: (VI_1) received lower priority (90) advert from 192.168.88.132 - discarding
Sep 17 14:47:33 centos7 Keepalived_vrrp[32437]: (VI_1) received lower priority (90) advert from 192.168.88.132 - discarding
Sep 17 14:47:34 centos7 Keepalived_vrrp[32437]: (VI_1) received lower priority (90) advert from 192.168.88.132 - discarding
Sep 17 14:47:34 centos7 Keepalived_vrrp[32437]: (VI_1) Receive advertisement timeout
Sep 17 14:47:34 centos7 Keepalived_vrrp[32437]: (VI_1) Entering MASTER STATE
Sep 17 14:47:34 centos7 Keepalived_vrrp[32437]: (VI_1) setting VIPs.
Sep 17 14:47:34 centos7 Keepalived_vrrp[32437]: Sending gratuitous ARP on ens33 for 192.168.88.133
Sep 17 14:47:34 centos7 Keepalived_vrrp[32437]: (VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.88.133
Sep 17 14:47:34 centos7 Keepalived_vrrp[32437]: Sending gratuitous ARP on ens33 for 192.168.88.133
Sep 17 14:47:34 centos7 Keepalived_vrrp[32437]: Sending gratuitous ARP on ens33 for 192.168.88.133
Sep 17 14:47:34 centos7 Keepalived_vrrp[32437]: Sending gratuitous ARP on ens33 for 192.168.88.133
Sep 17 14:47:35 centos7 Keepalived_vrrp[32437]: Sending gratuitous ARP on ens33 for 192.168.88.133
Sep 17 14:47:39 centos7 Keepalived_vrrp[32437]: Sending gratuitous ARP on ens33 for 192.168.88.133
Sep 17 14:47:39 centos7 Keepalived_vrrp[32437]: (VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.88.133
Sep 17 14:47:39 centos7 Keepalived_vrrp[32437]: Sending gratuitous ARP on ens33 for 192.168.88.133
Sep 17 14:47:39 centos7 Keepalived_vrrp[32437]: Sending gratuitous ARP on ens33 for 192.168.88.133
# IP信息变化
[root@centos7 ~]# ip add
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:9f:da:d2 brd ff:ff:ff:ff:ff:ff
inet 192.168.88.131/24 brd 192.168.88.255 scope global noprefixroute dynamic ens33
valid_lft 1725sec preferred_lft 1725sec
inet 192.168.88.133/32 scope global ens33
valid_lft forever preferred_lft forever
# 备机,自动变为BACKUP
Keepalived Info: Nginx detection is normal
Keepalived Info: Nginx detection is normal
Keepalived Info: Nginx detection is normal
Sep 17 14:47:34 centos7 Keepalived_vrrp[24328]: (VI_1) Master received advert from 192.168.88.131 with higher priority 100, ours 90
Sep 17 14:47:34 centos7 Keepalived_vrrp[24328]: (VI_1) Entering BACKUP STATE
Sep 17 14:47:34 centos7 Keepalived_vrrp[24328]: (VI_1) removing VIPs.
# IP信息变化
[root@centos7 ~]# ip add
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:7e:35:d1 brd ff:ff:ff:ff:ff:ff
inet 192.168.88.132/24 brd 192.168.88.255 scope global noprefixroute dynamic ens33
valid_lft 1637sec preferred_lft 1637sec
也就是主Nginx1重新开启后,虚拟IP 88.133 自动从 Nginx2(备) 转移到 Nginx1(主),让主机提供服务。
另外假如Nginx1服务器死机了,或者断电关机,虚拟IP也会自动转移到Nginx2服务器上,业务服务依然不会受影响。
这样就实现了Nginx的高可用。
双机高可用方案主从、双主对比
- Nginx+keepalived 双机主从模式:即前端使用两台服务器,一台主服务器和一台热备服务器,正常情况下,主服务器绑定一个公网虚拟IP,提供负载均衡服务,热备服务器处于空闲状态;当主服务器发生故障时,热备服务器接管主服务器的公网虚拟IP,提供负载均衡服务;但是热备服务器在主机器不出现故障的时候,永远处于浪费状态,对于服务器不多的网站,该方案不经济实惠。上面实验的就是该方案。
- Nginx+keepalived 双机主主模式:即前端使用两台负载均衡服务器,互为主备,且都处于活动状态,同时各自绑定一个公网虚拟IP,提供负载均衡服务;当其中一台发生故障时,另一台接管发生故障服务器的公网虚拟IP(这时由非故障机器一台负担所有的请求)。这种方案,不会造成资源的空闲,经济实惠。
Nginx1【88.131】配置备虚拟IP88.134
#虚拟IP2, 本机作为Backup
vrrp_instance VI_2 {
state BACKUP
interface ens33
virtual_router_id 134
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass passwd2
}
# track_script { # 执行上面检测nginx进程脚本
# chk_nginx
# }
virtual_ipaddress { #虚拟ip
192.168.88.134
}
}
配置好后进行reload,观察IP变化
# Nginx1
[root@centos7 keepalived]# service keepalived reload
Reloading keepalived configuration (via systemctl): [ 确定 ]
[root@centos7 keepalived]# ip addr
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:9f:da:d2 brd ff:ff:ff:ff:ff:ff
inet 192.168.88.131/24 brd 192.168.88.255 scope global noprefixroute dynamic ens33
valid_lft 1204sec preferred_lft 1204sec
inet 192.168.88.133/32 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.88.134/32 scope global ens33
valid_lft forever preferred_lft forever
Nginx2【88.132】配置主虚拟IP88.134
#虚拟IP2, 本机作为Master
vrrp_instance VI_2 {
state MASTER
interface ens33
virtual_router_id 134
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass passwd2
}
# track_script { # 执行上面检测nginx进程脚本
# chk_nginx
# }
virtual_ipaddress { #虚拟ip
192.168.88.134
}
}
配置好后观察IP变化,由于Nginx2为虚拟IP2 88.134 的主机,那么Nginx2配置成功后,88.134就会自动从Nginx1转移到Ngixn2了。
# Nginx2
[root@centos7 keepalived]# service keepalived reload
Reloading keepalived configuration (via systemctl): [ 确定 ]
[root@centos7 keepalived]# ip add
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:7e:35:d1 brd ff:ff:ff:ff:ff:ff
inet 192.168.88.132/24 brd 192.168.88.255 scope global noprefixroute dynamic ens33
valid_lft 1792sec preferred_lft 1792sec
inet 192.168.88.134/32 scope global ens33
valid_lft forever preferred_lft forever
看Nginx1的IP
[root@centos7 keepalived]# ip addr
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:9f:da:d2 brd ff:ff:ff:ff:ff:ff
inet 192.168.88.131/24 brd 192.168.88.255 scope global noprefixroute dynamic ens33
valid_lft 1055sec preferred_lft 1055sec
inet 192.168.88.133/32 scope global ens33
valid_lft forever preferred_lft forever
此时 http://192.168.88.133/ 和 http://192.168.88.134/ 都可以访问到。
这种配置下有两个Virtual IP,两个机器互为主备,最后DNS服务器把域名解析至两个Virtual IP即可。