您现在的位置是: 网站首页 >服务部署 >Linux应用服务配置 服务部署

【keepalived、nginx】CentOS7使用keepalived实现nginx高可用架构

admin2019年9月17日 17:11 Linux | Nginx 1341人已围观

Linux应用服务配置简介 各类Linux软件安装配置

# 系统架构 ![BLOG_20190918_104406_28](/media/blog/images/2019/09/BLOG_20190918_104406_28.png "博客图集BLOG_20190918_104406_28.png") - Nginx实现后端多台业务服务器的负载均衡,当一台Web宕机后,并不影响访问; - 多台Nginx实现高可用,配置VIP,当一台Nginx宕机后,虚拟IP自动转移到备用主机; # CentOS7配置网络 不能使用`ifconfig`,使用`ip xxx`查询IP相关的信息 ```bash # ip address ``` 可以查看到网卡名为`ens33` ## 配置动态IP 先使用动态获取IP,前提要开启DHCP,由于测试环境是VMWare,使用NAT模式即可 修改网卡配置文件 `vi /etc/sysconfig/network-scripts/ifcfg-ens33` (最后一个为网卡名称) 动态获取IP地址需要修改两处地方即可 ```bash 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 ```bash [root@centos7 ~]# ip address 1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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` (最后一个为网卡名称) ```bash 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,使用下面的命令安装即可 ```bash [root@centos7 ~]# yum install vim ``` 下面来创建测试环境,克隆当前的系统 # 使用python运行简单的Web服务 ## 业务服WebSvr1【88.129】 查看ip ```bash [root@centos7 ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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服务器 ```bash [root@centos7 ~]# vim index.html <html> <body> <h1>Web Svr 1</h1> </body> </html> ``` 启动web服务 ```bash [root@centos7 ~]# python -m SimpleHTTPServer 8080 Serving HTTP on 0.0.0.0 port 8080 ... ``` 在本地可以访问 ```bash [root@centos7 ~]# curl 192.168.88.129:8080 <html> <body> <h1>Web Svr 1</h1> </body> </html> ``` 但其他同一网段的浏览器无法访问 http://192.168.88.129:8080/ ,检查防火墙且关闭 ```bash # 查看防火墙状态 [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 ```bash [root@centos7 ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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,方便后面测试观察 ```bash [root@centos7 ~]# vim index.html # 添加下面内容 <html> <body> <h1>Web Svr 2</h1> </body> </html> ``` 关闭防火墙,启动web服务,测试同网段浏览器访问 ```bash [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 ```bash [root@centos7 ~]# ip address 1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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依赖包 ```bash [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 获取下载链接 复制下载链接,使用下面命令下载 ```bash [root@centos7 ~]# yum install wget -y # 如果没安装wget,首先需要安装 [root@centos7 ~]# wget http://nginx.org/download/nginx-1.17.3.tar.gz ``` 下载最新版的nginx,解压 ```bash [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 ```bash [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" ``` ### 编译参数说明 ```bash --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日志。 ``` ## 执行编译后安装 ```bash [root@centos7 nginx-1.17.3]# make && make install ``` ## 手动启动nginx ```bash [root@centos7 nginx-1.17.3]# /etc/nginx/sbin/nginx nginx: [emerg] getpwnam("nginx") failed # 没有nginx用户 ``` 启动失败,创建nginx用户 ```bash # 创建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页面 ![BLOG_20190918_104241_38](/media/blog/images/2019/09/BLOG_20190918_104241_38.png "博客图集BLOG_20190918_104241_38.png") ## 创建nginx启动文件 需要在`init.d`文件夹中创建nginx启动文件。 这样每次服务器重新启动`init`进程都会自动启动Nginx。 ```bash [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 ``` 校验配置文件依次输入下列命令 ```bash [root@centos7 init.d]# chkconfig --add nginx [root@centos7 init.d]# chkconfig --level 345 nginx on ``` 给这个文件添加执行权限 ```bash [root@centos7 init.d]# chmod +x nginx [root@centos7 init.d]# ls functions netconsole network nginx README ``` ## 启动Nginx服务 ```bash [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端口方法,但之前已经关闭防火墙了 ```bash # 允许80端口 firewall-cmd --permanent --add-port=80/tcp --zone=public # 重新加载防火墙配置 firewall-cmd --reload ``` ## 代理服Nginx1【88.131】 ### 修改nginx.conf配置文件 ```bash [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 ``` 查看无注释的配置文件,使用`>>`将其写入新的文件 ```bash [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配置 ```bash # 测试配置文件是否正常 [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 文件 ```bash [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 ```bash [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次。 ![BLOG_20190918_104220_37](/media/blog/images/2019/09/BLOG_20190918_104220_37.png "博客图集BLOG_20190918_104220_37.png") 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 ```bash [root@centos7 ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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】 ![BLOG_20190918_104214_50](/media/blog/images/2019/09/BLOG_20190918_104214_50.png "博客图集BLOG_20190918_104214_50.png") 新增一台nginx服务,和之前的配置一样,只需要修改 nginx.conf 即可 ```bash [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 1. 基于VRRP协议:路由器和操作系统层面的协议,虚拟路由器动态转移IP; 2. 需要安装keepalived软件; 3. 需要配置:有主备(master/backup)两个角色,可以配置多重定期监控来实现应用的高可用性; 4. 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 获取下载地址 ```bash [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,编译安装 ```bash [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`,影响不大,也可以自定义安装路径,将所有软件都安装到一个目录,如果没有该目录会自动创建 运行前配置 ```bash [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` 下查看官方示例 ```bash [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` ```bash [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中执行 ```bash [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 中的输出日志 ```bash [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 启动服务,查看服务启动情况 ```bash # 启动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 ``` 但是查看日志 ```bash [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` 中添加 ```bash script_user root enable_script_security ``` 继续处理 ```bash # 解决这个后又有下面的提示 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` 中添加 ```bash router_id chk_niginx_133 ``` 解决日志中的错误提示后,通过`service keepalived start`命令可以启动 keepalived,并且在 messages中可以查看shell中显示的日志 ```bash 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 关闭后查看日志中的输出内容 ```bash [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开机启动 ```bash [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 ### 下载配置编译安装 ```bash # 下载安装 [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`备优先级一定小于主,其他基本一致 ```bash [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 一样即可。 ```bash [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服务及开机启动 ```bash [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如果有防火墙配置 ```bash # 指定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服务器所有的配置文件里指定独一无二的多播地址,配置如下: ```bash global_defs { #全局配置 router_id LVS_19 #服务标识 vrrp_mcast_group4 224.0.0.19 #这个就是指定多播地址的配置 } ``` 1. 不同实例的通信认证密码也最好不同,以确保接管正常。 2. 另一款高可用软件Heartbeat,如果采用多播方式实现主备通信,同样会有多播地址冲突问题。 ## 测试主备Nginx自动切换 ### keepalived监控Nginx的状态 经过前面的配置,如果master主服务器的keepalived停止服务,backup从服务器会自动接管VIP对外服务;一旦主服务器的keepalived恢复,会重新接管VIP。 keepalived支持配置监控脚本,可以通过脚本监控Nginx的状态,如果状态不正常则进行一系列的操作,最终仍不能恢复Nginx则杀掉keepalived,使得从服务器能够接管服务。 ### 如何监控Nginx的状态 最简单的做法是监控Nginx进程,更靠谱的做法是检查NginX端口,最靠谱的做法是检查多个url能否获取到页面。 keepalived.conf 中`vrrp_script`配置区的script一般有2种写法: 1. 通过脚本执行的返回结果,所以脚本就需要返回`exit 0`,或`exit 1`,keepalived收到这个返回值之后,如果配置了`weight -5`这种方式,则改变优先级,keepalived继续发送通告消息,backup比较优先级再决定。这是直接监控Nginx进程的方式。 2. 脚本里面检测到异常,直接关闭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 ```bash # 主机 # 注释启动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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 ```bash # 现在启动主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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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的高可用。 # 双机高可用方案主从、双主对比 1. **Nginx+keepalived 双机主从模式**:即前端使用两台服务器,一台主服务器和一台热备服务器,正常情况下,主服务器绑定一个公网虚拟IP,提供负载均衡服务,热备服务器处于空闲状态;当主服务器发生故障时,热备服务器接管主服务器的公网虚拟IP,提供负载均衡服务;但是热备服务器在主机器不出现故障的时候,永远处于浪费状态,对于服务器不多的网站,该方案不经济实惠。*上面实验的就是该方案。* 2. **Nginx+keepalived 双机主主模式**:即前端使用两台负载均衡服务器,互为主备,且都处于活动状态,同时各自绑定一个公网虚拟IP,提供负载均衡服务;当其中一台发生故障时,另一台接管发生故障服务器的公网虚拟IP(这时由非故障机器一台负担所有的请求)。这种方案,不会造成资源的空闲,经济实惠。 ## Nginx1【88.131】配置备虚拟IP88.134 ```bash #虚拟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变化 ```bash # Nginx1 [root@centos7 keepalived]# service keepalived reload Reloading keepalived configuration (via systemctl): [ 确定 ] [root@centos7 keepalived]# ip addr 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 ```bash #虚拟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了。 ```bash # Nginx2 [root@centos7 keepalived]# service keepalived reload Reloading keepalived configuration (via systemctl): [ 确定 ] [root@centos7 keepalived]# ip add 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 ```bash [root@centos7 keepalived]# ip addr 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> 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即可。 ![BLOG_20190918_104131_31](/media/blog/images/2019/09/BLOG_20190918_104131_31.png "博客图集BLOG_20190918_104131_31.png")

很赞哦! (2)

文章交流

  • emoji
0人参与,0条评论

当前用户

未登录,点击   登录

站点信息

  • 建站时间:网站已运行2074天
  • 系统信息:Linux
  • 后台程序:Python: 3.8.10
  • 网站框架:Django: 3.2.6
  • 文章统计:256 篇
  • 文章评论:60 条
  • 腾讯分析网站概况-腾讯分析
  • 百度统计网站概况-百度统计
  • 公众号:微信扫描二维码,关注我们
  • QQ群:QQ加群,下载网站的学习源码
返回
顶部
标题 换行 登录
网站