CentOS7.1下生產環境Keepalived+Nginx配置

注:下文涉及到配置的,如無特別說明,主備機則一致!

一、環境介紹

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 ([email protected]) (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 = '[email protected]'

toMail   = '[email protected]'

username = '[email protected]'

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節


以上配置自行經過各種切換測試且通過,如果有博友發現問題可與我交流,感謝閱讀!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章