阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

CentOS7.1下生产环境Keepalived+Nginx配置

181次阅读
没有评论

共计 14382 个字符,预计需要花费 36 分钟才能阅读完成。

注:下文涉及到配置的,如无特别说明,主备机则一致!
一、环境介绍
1、这是我 CentOS 的版本,CentOS7.1,主备都为该版本
[root@localhost ~]# cat /etc/RedHat-release
CentOS Linux release 7.1.1503 (Core)
[root@localhost ~]# cat /proc/version
Linux version 3.10.0-229.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC) ) #1 SMP Fri Mar 6 11:36:42 UTC 2015

2、修改主机名并修改 host
[root@localhost ~]# hostnamectl set-hostname node-01
[root@localhost ~]# vi /etc/hosts
127.0.0.1node-01 在 127 后面添加 node-01

二、拓扑图的规划:
A)
|————IP 地址 ———–|———-|—— 软件 ——|———-|- 状态 -|
|172.21.4.51(VIP:172.21.4.44)|———-|keepalived+nginx|———-|Master|
|172.21.4.52(VIP:172.21.4.44)|———-|keepalived+nginx|———-|Backup|
|———172.21.4.91———|———-|——IIS——-|———-|-Web1-|
|———172.21.4.91———|———-|——IIS——-|———-|-Web2-|
B)
Internet–
        |
    ============= 
    | ISP Router|
    =============
        |                              |
        |                              |—- Web1 (172.21.4.91)
        |-HA-|eth0–> 172.21.4.51              |
        |            \                /
        |              \              /
        |              ===VIP(172.21.4.44)===
        |              /              \
        |            /                \
        |-HA-|eth0–> 172.21.4.52              |
                                      |—- Web2 (172.21.4.92)
                                      |
注:在网关上已针对 VIP(172.21.4.44)作了 80 端口映射。
此架构需考虑的问题:
1、Master 运行,则 Master 占有 vip 且 Nginx 能够正常服务;
2、Master 挂了,则 Backup 抢占 vip 且 Nginx 能够正常服务;
3、任何一台前端 nginx 服务挂了,则 vip 资源转移到另一台服务器上,并发送提醒邮件;
4、nginx 需要检测后端服务器的健康状态(由于应用是挂在默认网站下的虚拟目录,且无法更改,必须能够对虚拟目录进行健康检查)
5、由于应用需要 Session 保持,但由于没有做 Session 共享,实际服务器角色转换时,应用会受到一定的影响。

三、安装前的准备工作
CentOS7 环境下,默认是使用 FireWallD 服务,即使你修改了 iptables,重启又被初始化了,需要再次手动 systemctl restart  iptables.service 才能使设置的 iptables 生效,由于 FireWallD 暂时还没有熟悉使用方法且不知道他比 iptables 到底有哪些优势,保险起见,还是换回原先的 iptables

1、关闭 firewall:
[root@node-01 ~]# systemctl stop firewalld.service
# 停止 firewall
[root@node-01 ~]# systemctl disable firewalld.service 或 systemctl mask firewalld.service
# 禁止 firewall 开机启动

2、安装 iptables 防火墙
[root@node-01 ~]# yum install iptables-services -y
[root@node-01 ~]# systemctl enable iptables

3、在进行 Keepalived 和 nginx 配置前,务必将集群内的几台主机的通讯相互完全放行(并开放 80 的 Web 访问规则),否则很有可能出现脑裂或其他问题, 可直接在配置文件内加入以下语句;
[root@node-01 ~]# vi /etc/sysconfig/iptables
-A INPUT -p tcp -m state –state NEW -m tcp –dport 80 -j ACCEPT
-A INPUT -s 172.21.4.51 -j ACCEPT
-A INPUT -s 172.21.4.52 -j ACCEPT
-A INPUT -s 172.21.4.91 -j ACCEPT
-A INPUT -s 172.21.4.92 -j ACCEPT

[root@node-01 ~]# systemctl restart iptables.service

四、Keepalived 与 Nginx 的安装
1、安装 ipvsadm
[root@node-01 ~]# yum install ipvsadm
[root@node-01 ~]# ipvsadm -v
ipvsadm v1.27 2008/5/15 (compiled with popt and IPVS v1.2.1)
ipvs(IP Virtual Server) 是整个负载均衡的基础,如果没有这个基础,故障隔离与失败切换就毫无意义了。ipvs 具体实现是由 ipvsadm 这个程序来完成的。CentOS7.1 默认自带安装了。

2、安装 keepalived(其实 7.1 自带了)
[root@node-01 ~]# yum install keepalived
[root@node-01 ~]# keepalived -v
Keepalived v1.2.13 (03/06,2015)

3、安装当前最新稳定版 1.8.0
注 1:一开始是用 yum 安装的 nginx,结果发现后端服务器 Down 机或状态不正常时,nginx 也照常转发请求,后面 yum erase nginx 后,进行了手动安装。因为需要额外添加 nginx_upstream_check_module 模块。
注 2:安装过程会提示类型这样的错误 ./configure: error: the HTTP rewrite module requires the PCRE library.
所以先安装相应的支持库来解决。pcre,正则表达式匹配支持;zlib,用于压缩等等。
[root@node-01 ~]# yum -y install gcc-c++ pcre-devel zlib-devel

1) 为 nginx 建立一个 www 组,并建立一个不登录的账户 nginx,放入 www 用户组
[root@node-01 ~]# groupadd -f www
[root@node-01 ~]# useradd -d /var/cache/nginx -s /sbin/nologin -g www nginx
2) 建立目录用于存放 nginx 日志文件,并赋权限
[root@node-01 ~]# mkdir /var/log/nginx
[root@node-01 ~]# mkdir /usr/local/nginx
[root@node-01 ~]# chown -R nginx.www /var/log/nginx
[root@node-01 ~]# chown -R nginx.www /usr/local/nginx

3) 分别下载 nginx、额外模板及安装
[root@node-01 ~]# mkdir /nginx
[root@node-01 ~]# cd /nginx
[root@node-01 nginx]# wget http://nginx.org/download/nginx-1.8.0.tar.gz
[root@node-01 nginx]# wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.zip
[root@node-01 nginx]# tar -xvf nginx-1.8.0.tar.gz
[root@node-01 nginx]# unzip master.zip
# 在当前目录下解压出 nginx_upstream_check_module-master 这个目录

[root@node-01 nginx]# cd nginx-1.8.0/
[root@node-01 nginx-1.8.0]# patch -p1 < /nginx/nginx_upstream_check_module-master/check_1.7.5+.patch
# 由于安装版 1.8.0 稳定版,所以选 check_1.7.5+.patch 这个补丁包,其他版本相应选择即可
# 如果提示 bash: patch: 未找到命令 … 应该安装一下 patch 命令包 yum -y install patch

[root@node-01 nginx-1.8.0]# ./configure –prefix=/usr/local/nginx –user=nginx –group=www –pid-path=/run/nginx.pid –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –add-module=/nginx/nginx_upstream_check_module-master
[root@node-01 nginx-1.8.0]# make && make install

便于以后的操作,进行以下设置并制作自启动文件:
[root@node-01 ~]# ln -s /usr/local/nginx/sbin/nginx /usr/sbin/nginx
[root@node-01 ~]# vi /usr/lib/systemd/system/nginx.service
# 加下以下内容:
#———Begin————————————
[Unit]
Description=nginx – high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
#———end————————————–

[root@node-01 /]# systemctl enable nginx.service
系统启动时让 nginx.service 自启动。

4) keepalived 和 Nginx 最好也设置开机启动
[root@node-01 ~]# systemctl enable keepalived
[root@node-01 ~]# systemctl enable nginx

五、Keepalived 配置
在配置 keepalived 之前,先关闭 selinux
A、vi /etc/selinux/config
B、设置 SELINUX=disabled 保存
C、执行  setenforce 0
如果只想临时关闭,直接输入:setenforce 0
[root@node-01 ~]# vi /etc/keepalived/keepalived.conf
#############keepalived 配置 #############################################################

! Configuration File for keepalived

global_defs {
}

vrrp_script chk_nginx {
# 必须放在 track 代码的上方,否则无效,测试了几次是这个情况

  script “killall -0 nginx”
  #用 shell 命令检查 nginx 服务是否存在

  interval 1
  #时间间隔为 1 秒检测一次

  weight -15
  #当 nginx 的进程不存在了,就把当前的权重 -15
}

vrrp_instance VI_1 {
    state MASTER
    #主 LVS 是 MASTER, 从主机时此项要改为 BACKUP,要大写

    interface enp4s0
    #LVS 监控的网络接口

    virtual_router_id 51
    #同一实例下 virtual_router_id 必须相同,MASTRE/BACKUP 设置值要一样

    priority 100
    #定义优先级,数字越大,优先级越高,把此份 Conf 拷贝到另一台机器上时,设置的 priority 值要比 MASTRE 权重值低

    advert_int 1
    #MASTER 与 BACKUP 负载均衡器之间同步检查的时间间隔,单位是秒

    authentication {
        auth_type PASS
        auth_pass 376879148
        #验证类型和密码,有 PASS 和 AH 两种,一般用 PASS,据说 AH 有问题,认证密码主备服务器之间一定要一致,否则出错
    }

    virtual_ipaddress {
        172.21.4.44
        #设置虚拟 IP, 可以有多个地址,每个地址占一行,不需掩码。注意:这个 ip 必须与我们在 lvs 客户端设定的 vip 相一致
    }

  track_script {
        chk_nginx
        #引用上面的 vrrp_script 定义的脚本名称
        }

  notify_master “/etc/keepalived/changemail.py master”
  notify_backup “/etc/keepalived/changemail.py backup”
  notify_fault “/etc/keepalived/changemail.py fault”
  #指定当切换到主、备及故障状态时,执行的脚本
}

###################################################################################

五、HA 状态切换时的邮件提醒
[root@node-02 ~]# Python -V
Python 2.7.5
[root@node-01 ~]# vi /etc/keepalived/changemail.py

########################changemail.py 利用 Python2.7 程序发邮件 ###########################

#!/usr/bin/python 
# -*- coding: UTF-8 -*-     
import smtplib 
import socket
import time
from email.MIMEText import MIMEText 
from email.Utils import formatdate 
from email.Header import Header 
import sys

# 发送邮件的相关信息,根据实际情况填写 
smtpHost = ‘smtp.exmail.qq.com’
smtpPort = ’25’
sslPort  = ‘465’
fromMail = ‘youki@appi.com’
toMail  = ‘youki@appi.com’
username = ‘youki@appi.com’
password = ‘xxxxxxx’
# 解决中文问题 
reload(sys) 
sys.setdefaultencoding(‘utf8’) 
 
# 邮件标题和内容 
subject  = socket.gethostname() + ” HA status has changed”
body    = (time.strftime(“%Y-%m-%d %H:%M:%S”)) + ” vrrp transition, ” + socket.gethostname() + ” changed to be ” + sys.argv[1]
 
# 初始化邮件 
encoding = ‘utf-8’ 
mail = MIMEText(body.encode(encoding),’plain’,encoding) 
mail[‘Subject’] = Header(subject,encoding) 
mail[‘From’] = fromMail 
mail[‘To’] = toMail 
mail[‘Date’] = formatdate() 
 
try: 
    #连接 smtp 服务器,明文 /SSL/TLS 三种方式,根据你使用的 SMTP 支持情况选择一种 
    #普通方式,通信过程不加密 
    #smtp = smtplib.SMTP(smtpHost,smtpPort)
    #smtp.ehlo() 
    #smtp.login(username,password) 
 
    #tls 加密方式,通信过程加密,邮件数据安全,使用正常的 smtp 端口 
    #smtp = smtplib.SMTP(smtpHost,smtpPort) 
    #smtp.ehlo() 
    #smtp.starttls() 
    #smtp.ehlo() 
    #smtp.login(username,password) 
 
    #纯粹的 ssl 加密方式,通信过程加密,邮件数据安全 
    smtp = smtplib.SMTP_SSL(smtpHost,sslPort) 
    smtp.ehlo() 
    smtp.login(username,password) 
 
    #发送邮件 
    smtp.sendmail(fromMail,toMail,mail.as_string()) 
    smtp.close() 
    print ‘OK’ 
except Exception: 
    print ‘Error: unable to send email’
[root@node-01 ~]#
#######################################################################################

1、上面的脚本制作完成后,记得赋权,否则无法执行。
[root@node-01 ~]# chmod +x /etc/keepalived/changemail.py

[root@node-01 ~]#scp /etc/keepalived/keepalived.conf 172.21.4.52:/etc/keepalived
把主机上的配置文件 copy 到 Backup 服务器上, 现在在两台主机上可以利用 ip addr show 命令来查看 VIP 的获取情况

2、keeplived 日志位置指定:
在主从 keeplived 节点上编译 /etc/sysconfig/keepalived 文件

[root@node-01 ~]# vi /etc/sysconfig/keepalived
将最后一行 KEEPALIVED_OPTIONS=”-D” 修改为:KEEPALIVED_OPTIONS=”-D -d -S 0″

3、修改主从节点日志配置文件 /etc/rsyslog.conf
[root@node-01 ~]# vi /etc/rsyslog.conf
加入如下配置:
#keepalived -S 0
local0.*/var/log/keepalived.log

4、重启日志服务
[root@node-01 ~]# systemctl restart rsyslog.service

5、检查 /var/log/keepalived.log 文件是否存在

注意事项:
1、输出的日志信息:/var/log/messages,更具体的日志信息输出需要在启动 keepalived 时加 -d 参数。
2、在都为 MASTER 且 priority 一样的情况下,后启的节点(service vrrp start)会取代正在运行的节点变成主用的。
3、一台为 MASTER 且 priority 较高的情况下,不受次节点 down/up 影响,并且其本身再从 down 变为 up 时,会抢夺控制权。
4、在都为 MASTER 且 priority 一样的情况下,正在运行的主节点 down(断网),次节点会自动接管,主节点再起来时不会去抢夺控制权。
#keepalived 会定时执行脚本并对脚本执行的结果进行分析,动态调整 vrrp_instance 的优先级。
# 如果脚本执行结果为 0,并且 weight 配置的值大于 0,则优先级相应的增加
# 如果脚本执行结果非 0,并且 weight 配置的值小于 0,则优先级相应的减少
# 其他情况,维持原本配置的优先级,即配置文件中 priority 对应的值。
# 这里需要注意的是:
#1)优先级“不会”不断的提高或者降低,当 track 的对象恢复时,又是一致的
#2)可以编写多个检测脚本并为每个检测脚本设置不同的 weight
#3)不管提高优先级还是降低优先级,最终优先级的范围是在[1,254],不会出现优先级小于等于 0 或者优先级大于等于 255 的情况
# 这样可以做到利用脚本检测业务进程的状态,并动态调整优先级从而实现主备切换。

六、nginx 配置

[root@node-01 nginx]# vi /usr/local/nginx/conf/nginx.conf
#############nginx 配置 #############################################################

user  nginx www;
worker_processes  2;
#nginx 进程数,建议设置为等于 CPU 总核心数

#worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
# 为每个进程分配 cpu, 将 N 个进程分配到 N 个 cpu, 可以写多个或者将一个进程分配到多个 cpu
error_log  /var/log/nginx/error.log crit;
#pid      /run/nginx.pid;

events {
        use epoll;
        #epoll 是多路复用 IO(I/O Multiplexing)中的一种方式, 但是仅用于 linux2.6 以上内核, 可以 能
        worker_connections 102400;
        #最大连接数量,根据硬件调整,理论上每台 nginx 服务器的最大连接数为 worker_processes*s
        }

http {
        include      /usr/local/nginx/conf/mime.types;
        default_type  application/octet-stream;
        log_format  main  ‘$remote_addr – $remote_user [$time_local] “$request” ‘
                      ‘$status $body_bytes_sent “$http_referer” ‘
                      ‘”$http_user_agent” “$http_x_forwarded_for”‘;

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
   
    #tcp_nopush    on;
   
    server_tokens off;
    #nginx 隐藏版本号

    keepalive_timeout  65;

    proxy_intercept_errors on;
    #表示使 nginx 阻止 HTTP 应答代码为 400 或者更高的应答

    gzip on;
    #该指令用于开启或关闭 gzip 模块(on/off)

    gzip_min_length 1k;
    #设置允许压缩的页面最小字节数,页面字节数从 header 头得 content-length 中进行获取。默认值是 0,不管页面多大都压缩。建议设置成大于 1k 的字节数,小于 1k 可能会越压越大。

    gzip_buffers 4 8k;
    #设置系统获取几个单位的缓存用于存储 gzip 的压缩结果数据流。4 8k 代表以 8k 为单位,安装原始数据大小以 16k 为单位的 4 倍申请内存。

    gzip_http_version 1.1;
    #识别 http 的协议版本(1.0/1.1)

    gzip_comp_level 3;
    #gzip 压缩比,1 压缩比最小处理速度最快,9 压缩比最大但处理速度最慢(传输快但比较消耗 cpu)

gzip_types text/plain text/css application/json application/Javascript application/x-javascript text/javascript text/xml application/xml application/xml+rss;
    #匹配 mime 类型进行压缩,无论是否指定,”text/html”类型总是会被压缩的,经实测对本网站的图片压缩后,积极反而增大,所以取消图片类的压缩。

gzip_vary on;
    #和 http 头有关系,加个 vary 头,给代理服务器用的,有的浏览器支持压缩,有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的 HTTP 头来判断,是否需要压缩

    upstream MyApp{
              ip_hash;
              #1. 轮询(默认): 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端 除
              #2.weight: 指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不 况
              #3.ip_hash: 每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后题
              #4.fair(第三方): 按后端服务器的响应时间来分配请求,响应时间短的优先分配

              server 172.21.4.91:80 max_fails=2 fail_timeout=10s;
              server 172.21.4.92:80 max_fails=2 fail_timeout=10s;
              #max_fails 默认为 1,fail_timeout 默认为 10 秒,默认情况下后端服务器在 10 秒内出错 1 次认为服务器异常将停止转发
              check interval=3000 rise=2 fall=2 timeout=1000 type=http;
              #对条目中的所有节点, 每 3 秒检测 1 次,请求 2 次正常则标记该机状态为 UP
              check_http_send “GET /appicrm HTTP/1.0\r\n\r\n”;
              #检测网址子目录,在这里为 http://mail.appi.cn/appicrm
                    }
    server
        {
          listen      80;
          server_name  mail.appi.cn;
          charset utf-8;
          location ~ .*\.(ico|gif|jpg|jpeg|png|bmp|swf|js|css|htm|html)$
                  {
                    access_log image.log;
                    expires 14d;
                    root /usr/local/nginx/proxy_cache;
                    proxy_store on;
                    proxy_temp_path /usr/local/nginx/proxy_cache_image;
                    if (!-e $request_filename)
                    #文件和目录不存在的时候重定向
                      {proxy_pass http://MyApp;}
                      #rewrite ^(.*) http://www.test.com/test/$domain/ break;
                    }
                    #last:重新将 rewrite 后的地址在 server 标签中执行
                    #break:将 rewrite 后的地址在当前 location 标签中执行

      location / {
              rewrite ^/(.*)$ /appicrm/$1 last;
              }
         
          location ~* ^/appicrm/.*$ {
                            proxy_set_header        Host $host;
                            proxy_set_header        REMOTE-HOST $remote_addr;
                            proxy_set_header        X-Real-IP $remote_addr;
                            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                            proxy_pass              http://MyApp;
                            client_max_body_size    10m;
                            client_body_buffer_size 128k;
                            proxy_connect_timeout  90;
                            proxy_send_timeout      90;
                            proxy_read_timeout      90;
                            proxy_buffer_size      4k;
                            proxy_buffers          4 32k;
                            proxy_busy_buffers_size 64k;
                            proxy_temp_file_write_size 64k;
                            }
      location /webstatus {
                    check_status;
                    access_log off;
                    error_log off;
                    auth_basic “Restricted”;
                    auth_basic_user_file  /usr/local/nginx/conf/htpasswd/test;
                    #allow IP;
                    #deny all;
                    }

      error_page  500 502 503 504  /50x.html;
      location = /50x.html {
      root  html;
      }
  }
}
[root@localhost ~]#
###################################################################################
 
有几个需要注意的问题:
1、如下提示的 Pid 错误 
7 月 15 18:11:24 localhost.localdomain systemd[1]: Failed to read PID from file /var/run/nginx.pid: Invalid argument
解决:注释掉 /usr/lib/systemd/system/nginx.service 文件内的指定 PID 路径那一行,后面 find nginx 的 PID 实际存的位置后再修改回正常的,或干脆注释掉,因为我的修改了后面又出错了。nginx 安装的时候指定的位置居然不正确,不知道为何!网上有很多解决方法包括国外网站都说要安装各种支持文件,经测试都是错误答案。
2、Webstatus 这个状态查询页面,你肯定不希望所有人都能访问,所以需要加密
[root@node-01 ~] mkdir /usr/local/nginx/conf/htpasswd/
[root@node-01 ~] htpasswd -c /usr/local/nginx/conf/htpasswd/test Youki
New password:
Re-type new password:
Adding password for user auth_user
[root@node-01 ~] vi /usr/local/nginx/conf/nginx.conf
auth_basic “Restricted”;
auth_basic_user_file  /usr/local/nginx/conf/htpasswd/test;

将以上两句加入 /webstatus 节

以上配置自行经过各种切换测试且通过,如果有博友发现问题可与我交流,感谢阅读!

LVS/DR + Keepalived 搭建负载均衡集群 http://www.linuxidc.com/Linux/2015-06/118647.htm

LVS+Keepalived 实现四层负载及高可用  http://www.linuxidc.com/Linux/2015-02/112695.htm

LVS+Keepalived 高可用负载均衡集群架构实验  http://www.linuxidc.com/Linux/2015-01/112560.htm

Heartbeat+LVS 构建高可用负载均衡集群  http://www.linuxidc.com/Linux/2014-09/106964.htm

CentOS 7 上配置 LVS + Keepalived + ipvsadm http://www.linuxidc.com/Linux/2014-11/109237.htm

Keepalived 高可用集群搭建 http://www.linuxidc.com/Linux/2014-09/106965.htm

Keepalived 的详细介绍:请点这里
Keepalived 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-07/120179.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计14382字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中