美文网首页中间件
【keepalived、nginx】CentOS7使用keepa

【keepalived、nginx】CentOS7使用keepa

作者: 吾星喵 | 来源:发表于2019-09-18 13:24 被阅读0次

    专题:Linux应用服务配置

    各类Linux软件安装配置

    更多内容请点击 我的博客 查看,欢迎来访。

    系统架构

    BLOG_20190918_104406_28
    • 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: <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 (最后一个为网卡名称)

    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: <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服务器

    [root@centos7 ~]# vim index.html
    
    <html>
    <body>
    <h1>Web Svr 1</h1>
    </body>
    </html>
    

    启动web服务

    [root@centos7 ~]# python -m SimpleHTTPServer 8080
    Serving HTTP on 0.0.0.0 port 8080 ...
    

    在本地可以访问

    [root@centos7 ~]# curl 192.168.88.129:8080
    <html>
    <body>
    <h1>Web Svr 1</h1>
    </body>
    </html>
    

    但其他同一网段的浏览器无法访问 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: <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,方便后面测试观察

    [root@centos7 ~]# vim index.html
    
    # 添加下面内容
    <html>
    <body>
    <h1>Web Svr 2</h1>
    </body>
    </html>
    

    关闭防火墙,启动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: <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依赖包

    [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页面

    BLOG_20190918_104241_38

    创建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 websvrproxy_pass就可以实现负载均衡。

    Nginx转发原理

    访问 http://192.168.88.131/ ,页面上就会出现Web Svr 1Web Svr 2切换,会根据权重选择服务器,weight值越大,权重越高,也就是重复刷新该页面,平均Web Svr 2出现2次,Web Svr 1出现1次。

    BLOG_20190918_104220_37

    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 1Web Svr 2切换了。

    到目前为止,仍然不能实现高可用,虽然web服务可以这样做,单点故障可以通过这种方式处理,但是如果nginx服务故障了,整个系统基本就无法访问了,那么就需要使用多台Nginx来保障。

    多个Nginx协同工作,Nginx高可用【双机主从模式】

    先查看新增的IP

    [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

    新增一台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

    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 获取下载地址

    [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 BACKUPpriority 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    #这个就是指定多播地址的配置
    }
    
    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

    # 主机
    # 注释启动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

    # 现在启动主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

    #虚拟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: <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

    #虚拟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: <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

    [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

    相关文章

      网友评论

        本文标题:【keepalived、nginx】CentOS7使用keepa

        本文链接:https://www.haomeiwen.com/subject/afqkuctx.html