Web服務器集群搭建關鍵步驟紀要


前言:本文記述了搭建一個小型web服務器集群的過程,由於篇幅所限,系統、軟件的安裝和基本配置我這里就省略了,只記敘關鍵配置和腳本內容。假如各位朋友想了解各軟件詳細配置建議查閱官方文檔。

 

需求分析:

1.整體需求:搭建一個高可用的網站服務器集群,能承受高並發請求,能抵御一般的網絡攻擊,任何一台服務器的退服不影響整個集群的運作,並且能對各服務器的運行情況作出實時監控。

2.詳細需求分析:

根據需求,計划根據以下拓撲搭建運行環境:

 

二 詳細功能描述:

1.前端服務器采用nginx實現反向代理和負載均衡,用keepalive實現HA。此部分由centos1和centos4實現,centos1作為主服務器,centos4作為熱備服務器。Nginx會根據不同的請求ip機會均等地把請求發送到后端兩台服務器,並且以ip hash的方式保持各個ip的會話。

2.后端服務器構建在centos2與centos3上,采用apache作為web發布軟件,mysql作為數據庫,測試網頁用Django來實現。兩台服務器的數據庫能夠自動同步。

3.作為熱備服務器,centos4在centos1沒有故障時並沒有業務流量,處於相對空閑的狀態,因此在centos4上配置nfs使它成為文件共享服務器,網站文件放在這台服務器上。

4.centos5作為監控服務器,運行nagios監控各服務器狀態。出現告警時通過告警通知管理員。另外centos5還作為saltstack的服務器,其他主機的軟件安裝、文件傳輸、命令運行等操作均通過saltstack批量實現。

 

三 總體部署描述:

1.各個服務器均安裝centos6.4  64位版本,采用cobbler實現批量自動安裝。

2.各個軟件均安裝最新的穩定版,centos自帶的軟件也要進行升級,例如python,Centos自帶的版本比較久,會影響Django的運行。

 

四 詳細部署描述:

1.nginx設置

Nginx在這里的作用主要是反向代理、作為用戶以及服務器之間的緩存、以及以負載均衡的方式把請求發送到后端兩台服務器。

采用編譯安裝的方式安裝nginx,具體過程就不在此記述了,不過為了更好地抵擋入侵,建議編譯前修改一下安裝文件,使入侵者難以查出nginx的版本號,修改安裝文件中的nginx.h,把相關字段修改如下:

#define NGINX_VERSION      "1.0"
#define NGINX_VER          "webserver" NGINX_VERSION

 

Nginx的配置文件如下:

user  www www;
worker_processes  2;

events {
worker_connections  12800;
use epoll;
}

http {
    include       mime.types; #協助部分瀏覽器(如firefox)識別網頁文件的類型
    default_type  application/octet-stream;
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    sendfile  on;#指定nginx是否調用sendfile函數來輸出文件,能提高性能。
    tcp_nopush   on;
    tcp_nodelay  on;
    keepalive_timeout 20;  #客戶端連接保持活動的超時時間
    send_timeout 20;  #指定響應客戶端的超時時間
    client_body_buffer_size 1k;  #指定客戶端請求主體緩沖區大小
    client_header_buffer_size 1k;  #指定來自客戶端請求頭的headerbuffer大小
    large_client_header_buffers 2 1k; #客戶端請求中較大的消息頭指定的緩存最大數量和大小
    server_tokens off;  #禁止在錯誤頁面上顯示nginx版本號
    client_body_timeout 20;  #設置客戶端請求主體讀取超時時間
    client_header_timeout 20; #設置客戶端請求頭讀取超時時間
    gzip  on;
    upstream WebServers{   #指定負載均衡服務器
        ip_hash;           #以ip_hash的方式保持會話
        server 10.0.0.3;     #沒有設定權重,因此兩台后端服務器將機會均等地接受請求
        server 10.0.0.2;
        }
    server {
        listen       80;
        server_name  localhost;

        location / {
            proxy_pass   http://WebServers;
            limit_conn addr 100;     #指定每個ip最多只允許建立100個連接
            limit_rate 500k;         #每個ip最大帶寬是500k
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
} error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }

 

因為后端測試網頁是用Django寫的,因此nginx就不用處理php等動態網頁的請求了。

設置完畢后,把nginx設置為開機啟動,可以用如下方式:

echo “/usr/local/nginx/sbin/nginx” >>/etc/rc.local

 

2.Keeplive設置

Keeplive的作用是在兩台服務器(centos1centos4)之間,以VRRP協議實現HA。通過虛擬出一個Virtul IP(本例子中是192.168.48.138)來對外發布業務。兩台服務器中的任一台退服了,keeplive會自動把業務轉到另一台上。在這里centos1是主服務器,centos4是備用服務器。平時的數據流量只會通過centos1,只有centos1退服了,數據流量才會割接到centos4上。

centos1上的keepalive配置:

! Configuration File for keepalived

global_defs {
   notification_email {
   test@test.com       #指定告警郵箱,當發現對端服務器退服時發郵件警報 
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0   #綁定網卡接口
    virtual_router_id 51
    mcast_src_ip 192.168.48.139   #設置本機通過哪個ip發送vrrp包     
    priority 100    #設置優先級
    advert_int 1    #檢查間隔,這里設置為1秒
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.48.138
    }
}

 

對於從服務器centos4,只需要把以上配置文件的部分內容修改即可:

state BACKUP
mcast_src_ip 192.168.48.140
priority 90

 

同樣,配置好配置文件后,把keepalive添加到開機啟動中。

對於keepalive,由於是使用VRRP協議來檢查對端是否在線的,只要對端能ping通,那么keeplive就會認為對端在線。但也有一種情況是對端服務器沒有宕機,但nginx出錯關閉了,這種情況下keepalive仍然會判斷對端在線,不會把業務割接到備用服務器。因此我們需要在服務器上運行一個腳本,監控nginx進程的狀態。假如nginx進程關閉了,先嘗試重啟nginx,無法重啟時就關閉keepalive的進程,使業務割接到備用端。腳本如下:

#!/bin/bash
#nginxStatus.sh
while :
do
    nginxStatus=`ps -C nginx --no-header |wc -l`
    if ((nginxStatus==0));then
        /usr/local/nginx/sbin/nginx
sleep 5 nginxStatus
=`ps -C nginx --no-header |wc -l` if ((nginxStatus==0));then /etc/init.d/keepalived stop fi else #當判斷到主服務器的nginx已經重新啟動后,再啟動keepalive,使業務倒置回主 #服務器 keepaliveStatus=`ps -C keepalived --no-header |wc -l` if ((keepaliveStatus==0));then /etc/init.d/keepalived start fi fi sleep 5 done

 

把這個腳本放在centos1上,設置開機后於后台運行:

echo “nohup ~/nginxStatus.sh &”>>/etc/rc.local

 

由於腳本中的while會不斷循環下去來檢查進程運行情況,因此沒必要添加進計划任務。不過謹慎起見,防止腳本意外停止,也可以在計划任務中設置每30分鍾運行一次。

 

3.后端Web服務器設置

后端web服務器運行在centos2centos3上,采用apache搭建,測試網頁使用Django編寫,網頁文件存放在共享文件服務器centos4上,分別掛載在本機的/var/www/html目錄。

saltstack批量在兩台服務器上安裝apacheapache-develwsgiDjangomysql以及升級python,過程省略。

部署好運行環境后,修改一下apache的配置文件(http.conf),把運行用戶名和組名改為apache,根目錄指向/var/www/html

接下來設置mysql,把兩台服務器的mysql設置互為主從,使得其中一台服務器的數據庫變更了,馬上同步到另一台,保證兩台服務器的數據一致。設置步驟如下:

首先設置centos2

打開centos2mysql的配置文件my.cnf,作如下修改:

[mysqld]
log-bin=MySQL-bin  #開啟二進制日志,從服務器靠讀取主服務器的二進制日志來執行同步
server-id=1  #設置為1表明這是主服務器。
binlog-ignore-db=mysql  
binlog-ignore-db=information_schema  # binlog-ignore-db用來指定忽略哪些數據庫記錄到二進制日志,這樣在同步的時候就會忽略掉這些數據庫。其中“mysql”數據庫用於記錄用戶信息,“information_schema”用於記錄整個數據庫各個庫和表的信息。

 

然后以root身份登陸mysql,執行下面命令:

grant replication slave on *.* to ‘test’@’10.0.0.3’  identified ‘test123’;

 

這命令的含義是,在10.0.0.3機器上建立一個test用戶,用戶密碼為test123,這個用戶擁有對centos2上所有數據庫的所有表同步到centos310.0.0.3)的權限。

然后執行:

show master status;

可以看到以下信息:

 

記錄好這個信息,然后以root身份登陸centos3mysql,執行下面的命令(有一點需要注意,假如同步之前需要同步的數據庫不是空的話,需要先在數據庫上加上讀鎖,把主服務器的相關數據庫導入到從數據庫中):

change master to
master_host='10.0.0.2',
master_user='test',
master_password='test123',
master_log_file='MySQL-bin.000070',
master_log_pos=106;

 

上面的master_log_filemaster_log_pos的信息就是之前centos2上執行show master status命令后所顯示的信息。執行show slave status;命令,查看一下centos3是否已經成功成為從服務器:

 

可以看到centos3的mysql已經成為centos2(10.0.0.2)的從服務器了。至此centos3的mysql已經能主動同步centos2的數據了,我們只需要把以上操作在centos3上操作一次(先修改my.cnf,其中server-id要設為2,然后再執行創建用戶以及授權命令),就能實現兩個數據庫互為主從,相互之間自動同步。

 

4.共享文件服務器nfs

本環節中,我們需要把centos4配置成共享文件的服務器端,后端兩台web服務器的網頁內容將放在共享文件服務器上,以此保證兩台web服務器的網頁文件內容一致。

 

nfs在centos6.2上默認已安裝,我們首先在centos4的/etc目錄下新建exports文件,加入以下內容:

/home/apache/html 10.0.0.2(rw,sync)  #sync是指數據同時寫入緩存和硬盤中,執行較慢但保證數據精確
/home/apache/html 10.0.0.3(rw,sync)

 

然后在centos4上一步步執行下面的命令:

groupadd apache
useradd -g apache -s /sbin/nologin apache
passwd apache
mkdir -p /home/apache/html
#把網頁文件復制到/home/apache/html,然后再執行下面命令:
chown -R apache:apache /home/apache/html
chmod -R 700 /home/apache/html
chkconfig --level 35 nfs on
service nfs start

 

關於共享目錄的權限設置,由於后端兩台web服務器的apache都是以apacheapache這個用戶來執行的,文件的讀寫也是通過這個用戶,因此為保證數據安全,共享目錄只開放權限給這個用戶即可,其他用戶一律什么權限都不給予。另外還要把共享文件夾的所屬者設為apache:apache這個用戶。

接下來到centos2centos3兩台web服務器上作如下設置,使它們開機時自動加載共享目錄:

echo "mount -t nfs 10.0.0.4:/home/apache/html /var/www/html -o hard,bg,nfsvers=3 ">>/etc/rc.local

 

上面選項中hard表示網絡短暫中斷時會繼續嘗試連接服務器,並且不會顯示錯誤信息;

bg表示執行mount時如果無法順利mount上時,系統會將mount的操作轉移到后台並繼續嘗試mount,直到mount成功為止;

nfsvers=3表示采用第3版的nfs

 

5.nagios設置

監控軟件安裝在centos5上,負責監控其他4台服務器的情況,出現異常時發出郵件給管理員進行警報。

 

安裝過程:需要在centos5上安裝nagiosnagios插件包、nrpeapache(用於搭建監控網頁)、pnp(用於生成監控數據的分析圖表)。4台被監控的主機需要安裝nagios插件包以及nrpe,詳細安裝過程這里省略。

以下項目是對於4台服務器都需要監控的:

1.Check Swap:監控交換分區的剩余空間

2.Check Zombie Procs:監控僵屍進程的數目

3.Total Processes:監控總進程的數目

4.check-no_alowed_user:監控是否有非允許的用戶登陸

5.check-system-load:監控系統負載

 

對於nagios的工作原理,簡單來說就是:在服務端的nagios目錄下的services.cfg文件上定義需要監控各個客戶端的哪個監控項目,對應的監控腳本被放在客戶端執行,執行結果通過客戶端上的nrpe守護進程反饋給nagios服務器端。

默認情況下監控腳本返回的值所代表的的含義如下:

OK—退出代碼 0—表示服務正常地工作。

WARNING—退出代碼 1—表示服務處於警告狀態。

CRITICAL—退出代碼 2—表示服務處於危險狀態。

UNKNOWN—退出代碼 3—表示服務處於未知狀態。

 

因此,要實現上述5個監控項目,首先修改nagios服務器端(即centos5)上的services.cfg文件,添加上以下內容:

define service{
        use                      local-service
        host_name                centos1
        service_description      check-no_alowed_user
        check_command            check_nrpe!check_no_allowed_user #對於腳本在客戶端執行的命令,都要在命令前加上check_nrpe!
        notifications_enabled           1       #開啟告警功能
        flap_detection_enabled          0       #關閉抖動檢測(當數據出現較大抖動時nagios不會作出提示)
        notification_options            w,c,r   #warning、critical、recover時發出告警
        notification_interval           5       #假如服務的狀態沒有恢復正常的話,告警將每5分鍾發一次
        notification_period             24x7    #設定告警的時段,這里設置為24X7
}

define service{
        use                        local-service,services-pnp #對於添加上services-pnp的服務,nagios將調用pnp把服務返回的數據畫成圖表。
        host_name                  centos1
        service_description        check-system-load
        check_command              check_nrpe!check_load
        notifications_enabled         1
        flap_detection_enabled        0
        notification_options          w,c,r
        notification_interval         5
        notification_period           24x7
}


define service{
        use                         local-service,services-pnp
        host_name                   centos1
        service_description         Total Processes
        check_command               check_nrpe!check_total_procs
        notifications_enabled           1
        flap_detection_enabled          0
        notification_options            w,c,r
        notification_interval           5
        notification_period             24x7
}


define service{
        use                     local-service,services-pnp
        host_name               centos1
        service_description     Check Zombie Procs
        check_command           check_nrpe!check_zombie_procs
        notifications_enabled           1
        flap_detection_enabled          0
        notification_options            w,c,r
        notification_interval           5
        notification_period             24x7
}

define service{
        use                     local-service,services-pnp
        host_name               centos1
        service_description     Check Swap
        check_command           check_nrpe!check_swap
        notifications_enabled           1
        flap_detection_enabled          0
        notification_options            w,c,r
        notification_interval           5
        notification_period             24x7
}

 

以上寫出了描述centos1監控服務的描述,其他3台服務器的描述都是一樣的,只是host_name不一樣,限於篇幅,這里就不把剩余部分列出了。

接下來修改客戶端的設置,同樣以centos1為例,修改nagios目錄下的nrpe.cfg文件,添加以下內容(部分內容默認已經存在的,修改的時候需要注意有沒有重復):

command[check_swap]=/usr/local/nagios/libexec/check_swap -w 20% -c 10% #-w后面的參數告訴腳本當交換空間小於20%時,返回warming狀態(即返回1),-c后面的參數告訴腳本當交換空間小於10%時,返回critical狀態(即返回2)
command[check_load]=/usr/local/nagios/libexec/check_load -w 1.8,1.5,1.2 -c 2.5,2,1.8
command[check_zombie_procs]=/usr/local/nagios/libexec/check_procs -w 5 -c 10 -s Z
command[check_total_procs]=/usr/local/nagios/libexec/check_procs -w 150 -c 200
command[check_no_allowed_user]=/usr/local/nagios/libexec/check_no_allowed_user.py –a cjyfff

 

上面這5個命令對應的腳本中,check_no_allowed_user.py是我編寫的腳本,另外4個是nagios自帶的。check_no_allowed_user.py的作用是檢測是否有允許用戶以外的用戶登錄系統。使用方法是腳本后面加上選項-a,然后添加允許登錄的用戶列表(格式是-a user1,user2...,root默認已添加到允許列表,因此無需添加root)。當允許用戶列表以外的用戶登錄時,將會觸發nagios的critial告警。這個腳本的內容如下:

#! /usr/bin/env python
#coding=utf-8
#check_no_allowed_user.py
import os, sys, getopt

def Usage():
    print "Usage:\n\tpython check_no_allowed_user.py [-h|--help][-a|--add allowedUser01,allowUser02...]\n"
    print "\tTo creat the allowed user list,please use this format:-a user1,user2...."
    print "\tAny user(s) not in allowed user list login this system will alter Nagios." 
    sys.exit(3)

def CheckUser(args):
    a = os.popen("who").read() #這里a被賦值成一個包含換行符的字符串
                             #下面需要以換行符分隔把a建成列表,然后提取列表元素的第一個字段,這才是
                             #我們所需要的當前用戶名
    b = list(a.split("\n"))
    c = []
    i = 0
    while i<len(b)-1:
        c.append(b[i].split(" ")[0])
        i += 1
    userList = set(c)
    allowedList = list(args.split(","))  #創建允許用戶的列表
    allowedList.append("root")         #允許用戶的列表中默認添加上root
    #print allowedList
    rs = [user for user in userList if user not in allowedList] #查出在當前用戶列表中但不在允許列表中的用戶
    #print rs

    if rs :
        print "Detected NO ALLOWED user(s)%s"%rs
        sys.exit(2)
    else:
        print "All user is ALLOWED."
        sys.exit(0)

try:
    options, args = getopt.getopt(sys.argv[1:], "ha:", ["help", "add="])
except getopt.GetoptError:
    Usage()        

for o,r in options:
    if o in ("-h", "--help"):
        Usage()
    if o in ("-a", "--add"):
        #print type(r)
        CheckUser(r)

 

另外,對於centos1centos4兩台前端服務器,還需要添加2項監控服務:

80port:監控80端口的情況

CheckNginxState:監控nginx進程是否啟動

 

同樣,以centos1為例,修改centos5上的services.cfg,添加上以下內容:

define service{
        use                     local-service,services-pnp
        host_name               centos1
        service_description     80port
        check_command           check_tcp!80 #這個命令是通過服務器端的腳本來監控客戶端的80端口的,因此無需加上check_nrpe!,客戶端也不需要存在這個命令對應的腳本。
}

define service{
        use                             local-service
        host_name                       centos1
        service_description             CheckNginxState
        check_command                   check_nrpe!check_nginx
}

 

然后修改centos1上的nrpe.cfg,添加上以下內容:

command[check_nginx]=/usr/local/nagios/libexec/check_nginx.sh

 

這里的check_nginx.sh也是我自己編寫的腳本,腳本內容如下:

#!/bin/bash
#check_nginx.sh
use_age="This script is for checking nginx status,if nginx is stop Nagios will alarm."
if (($#!=0));then
    echo $use_age
    exit 3
fi
a=`ps -C nginx --no-header |wc -l`
if ((a!=0));then
    echo "nginx is running."
    exit 0
else
    echo "nginx is NOT running."
    exit 2
fi

 

對於centos4這台共享文件服務器,還需要增加一個監控項目,監控硬盤的容量大小,這里可以用nagios自帶的check_disk腳本,方法和上面一樣的,這里就不在敘述了。

對於作為后端web服務器的centos2centos3,也很有必要監控服務器上apache以及mysql是否正在運行。監控腳本很簡單,只需要把上面check_nginx.sh中“a=`ps -C nginx --no-header |wc -l`”修改一下,把“nginx”替換為“httpd”和“mysqld”即可。

最后,客戶端都設置好監控設置了,作為服務器端,也可以為centos5增加監控內容,服務器端的監控腳本同樣放在服務器端的libexec/下,監控服務是在localhost.cfg中定義的。

謹記添加自己寫的腳本后要把用戶改為nagios:nagios,並且增加執行權限。

最終配置完畢后,打開nagios監控頁面的效果圖如下:

 

6、安全設置

為了減少ssh密碼被暴力破解的風險,在各個服務器上把ssh端口從默認的22端口更改為其他端口(本例子中改為2002),並且在/etc/hosts.allow中指定允許sshd通信的ip,在/etc/hosts.deny中添加sshd:ALL

考慮到服務器都是在內網環境,已經能隔絕外網的很多攻擊,並且開啟防火牆的話會影響服務器之間數據轉發速度,因此我在這4台服務器上都關閉iptables,僅在centos5上開啟。在實際生產環境中,依靠在集群前面的防火牆對集群進行進一步保護。

centos5的iptables腳本如下:

!#/bin/bash
#centos5-iptables.sh
iptables -F
iptables -X
iptables -Z
iptables -P INPUT DROP
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

iptables -A INPUT -p icmp -j ACCEPT#允許icmp協議包通過
iptables -A INPUT -s 192.168.48.139 -j ACCEPT
iptables -A INPUT -s 192.168.48.140 -j ACCEPT
iptables -A INPUT -s 10.0.0.2 -j ACCEPT
iptables -A INPUT -s 10.0.0.3 -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dport 22,80 -j ACCEPT
/etc/rc.d/init.d/iptables save

 

結語:

最后我用apache benchmark測試了一下網站。雖然是在虛擬機環境,測試數據沒多大參考價值,但是通過測試也可以看看在高並發的環境下,那些服務器負荷最大。經測試,在100並發的環境下,雖然網頁還能打開,但是nagios已經失去了后端兩台web服務器的響應,提示request timeout了,其他兩台服務器的負載還是很低,說明在高並發的環境下,后端的web服務器負荷最大,也是重點需要優化的對象。

這個實驗環境存在一個不足,那就是共享文件只放在一台服務器上,容易造成單邊,建議條件許可的情況下可使用分布式存儲系統,例如MFS

另外在搭建實驗環境的過程中還有2點待日后跟進:

1、優化apache的性能,讓后端服務器能應付更大並發。

2、Mysql的主從同步存在延遲問題,可能會導致主、從數據庫不一致。這個查看網上資料可以通過插件來解決,下一步嘗試接觸這些插件的使用方法。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM