haproxy/nginx+keepalived負載均衡 雙機熱備 郵件報警 實戰及常見問題

jopen 9年前發布 | 16K 次閱讀 Web服務器 HAproxy

Haproxy 做http和tcp反向代理和負載均衡,keepalived 為兩臺 Haproxy 服務器做高可用/主備切換。

nginx   為內網服務器做正向代理,如果業務需求有變化,也可以部分替代 haproxy 做 http 反向代理。

如果發生主備切換,向指定郵箱發送報警郵件。

本文比較裹腳布,沒耐心的就別看了。

一、兩臺服務器,系統 CentOS6

主機名        外網IP        內網IP

lbserver_01  202.1.1.101   10.1.1.11/24

lbserver_02  202.1.1.102   10.1.1.12/24

虛擬IP        202.1.1.97    10.1.1.10/24

虛擬IP        202.1.1.98

虛擬IP        202.1.1.99

以下示例僅提供lbserver_01的配置,lbserver_02上大部分相同,不同之處會單獨注明。

二、安裝軟件包

1、配置 nginx 官方軟件源

[root@lbserver_01 ~]# vi /etc/yum.repos.d/nginx.repo

[nginx]

name=nginx repo

baseurl=http://nginx.org/packages/centos/6/x86_64/

gpgcheck=0

enabled=1

2、常用工具

[root@lbserver_01 ~]# yum -y install telnet man vim wget zip unzip ntpdate tree gcc iptraf tcpdump  bind-utils

3、服務器軟件

[root@lbserver_01 ~]# yum -y install haproxy keepalived nginx sendmail mailx

4、配置服務

[root@lbserver_01 ~]# chkconfig dnsmaq on

[root@lbserver_01 ~]# chkconfig sendmail on

[root@lbserver_01 ~]# chkconfig keepalived on

[root@lbserver_01 ~]# chkconfig haproxy on

sendmail 負責發送郵件,dnsmasq為內網提供 DNS 服務。

內網服務器如果需要上網(主要是為了安裝軟件包),需配置 DNS 和 http_proxy 環境變量,也可同時為 yum 配置proxy參數。

[root@lbserver_01 ~]# vim /etc/resolv.conf

nameserver 10.1.1.10

[root@lbserver_01 ~]# vim /etc/profile

export http_proxy=http://10.1.1.10:8000

[root@lbserver_01 ~]# vim /etc/yum.conf

proxy=http://10.1.1.10:8000

10.1.1.10:8000 這個 IP 和端口在后面的 nginx 配置文件中定義。

三、系統配置文件

1、配置命令行提示符,顯示當前完整路徑

[root@lbserver_01 ~]# vim /root/.bash_profile

PS1='[\u@\h:$PWD]# '

[root@lbserver_01 ~]# source /root/.bash_profile

[root@lbserver_01:/root]#

為新建用戶自動配置提示符

[root@lbserver_01:/root]# vim /etc/skel/.bash_profile

PS1='[\u@\h:$PWD]$ '

2、配置報警郵件發送帳號

[root@lbserver_01:/root]# vim /etc/mail.rc

set from=SendAlert@youdomain.com smtp=smtp.youdomain.com

set smtp-auth-user=SendAlert@youdomain.com smtp-auth-password=PassForSendAlert smtp-auth=login

3、配置 dnsmasq 僅為內網服務,很簡單的替換,用 sed 吧

</div>

[root@lbserver_01:/root]# sed 's/#interface=/interface=eth1/g' /etc/dnsmasq.conf -i

4、limits

[root@lbserver_01:/root]# vim /etc/security/limits.conf

</div>

*          soft    nofile          1024

  • hard nofile 65536
  • soft nproc 2048
  • hard nproc 16384
  • soft stack 10240
  • hard stack 32768</pre>

    5、配置haproxy keepalived 日志

    以下兩個文件需要修改參數:

    [root@lbserver_01:/root]# vim /etc/sysconfig/keepalived

    KEEPALIVED_OPTIONS="-d -D -S 0"

    [root@lbserver_01:/root]# vim /etc/sysconfig/rsyslog

    SYSLOGD_OPTIONS="-r -c 2"

    以下文件需要添加兩行:

    [root@lbserver_01:/root]# vim /etc/rsyslog.conf

    local0.*    /var/log/keepalived.log
    local2.*    /var/log/haproxy.log

    keepalived日志正常,而haproxy日志目前還沒有生成,原因慢慢找吧。

    6、防火墻

    [root@lbserver_01:/root]# vim /etc/sysconfig/iptables

    # Firewall configuration written by system-config-firewall
    # Manual customization of this file is not recommended.
    *filter
    :INPUT ACCEPT [0:0]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [0:0]
    -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    -A INPUT -p icmp -j ACCEPT
    -A INPUT -i lo -j ACCEPT
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 2888 -j ACCEPT
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
    -A INPUT -m state --state NEW -s 10.1.1.0/24 -m tcp -p tcp --dport 8000 -j ACCEPT
    -A INPUT -m state --state NEW -s 10.1.1.0/24 -m tcp -p tcp --dport 53 -j ACCEPT
    -A INPUT -m state --state NEW -s 10.1.1.0/24 -m udp -p udp --dport 53 -j ACCEPT
    -A INPUT -d 224.0.0.18 -j ACCEPT
    -A INPUT -j REJECT --reject-with icmp-host-prohibited
    -A FORWARD -j REJECT --reject-with icmp-host-prohibited
    COMMIT
    • tcp 2888 是修改后的 sshd 端口,替代默認的 22 ,可以很大程度上防止無聊的小白來暴力破解。
    • tcp 80 8080 443 為內網 web 服務器做負載均衡
    • tcp 8000 僅為內網服務,是 nginx 對內正向代理
    • tcp/udp 53 僅為內網服務,提供 DNS 解析轉發
    • -A INPUT -d 224.0.0.18 -j ACCEPT 這一條非常關鍵。224.0.0.18 是 keepalived 的組播地址,確保當前主機組播自己的狀態。缺少這條指令會產生很詭異的問題,比如雙機網卡上都有虛擬IP地址,但主機是有效的;而備機接管虛擬 IP 后說啥也不還給主機了。

    7、nginx正向代理

    [root@lbserver_01:/root]# vim /etc/nginx/conf.d/default.conf

    server {
    listen       8000;
    server_name  localhost;
    resolver     10.1.1.10;
    #charset koi8-r;
    access_log  /var/log/nginx/default.access.log  main;

    location / { proxy_pass http://$http_host$request_uri; }</pre>

    配置文件其他部分保持默認就可以了。

    8、keepalived配置

    • keepalived是雙機熱備的首選。平時主機獲得虛擬IP,提供服務,備機在旁邊看著。
    • 如果主機DOWN、網絡斷、服務出現故障,則備機立刻接管虛擬IP。
    • 當主機恢復時,又會自動搶回主機地位,備機接著看。

    [root@lbserver_01:/root]# vim /etc/keepalived/keepalived.conf

    ! Configuration File for keepalived
    global_defs {
    router_id HAP_KAD1
    ! 默認配置文件里本段還有notification_email設置,我不用,所以刪掉了。
    }
    ! vrrp_script 設置檢查服務健康狀況的腳本,腳本內容見下文。
    ! interval 1 每秒運行一次
    ! weight -10 如果腳本運行結果不為0(即失敗或無結果),即說明主機haproxy服務故障,priority減10,此時備機priority比主機大,將自動選舉為主機,原主機降為備機。
    ! priority 范圍是1到254。為了避免priority不斷降低最后兩機都變為1,理論上應該再配置vrrp_script使恢復正常的服務器提升priority,提升腳本需要配 weight <正數>,但實際實驗中發現基本沒有這個必要。如果生產中兩機不斷的競相自降 priority,說明有大麻煩發生了。
    ! 檢查haproxy的腳本
    vrrp_script check-haproxy {
    script "/usr/local/bin/chk-haproxy.sh"
    interval 1
    weight -10
    }
    ! 檢查nginx的腳本
    vrrp_script check-nginx {
    script "/usr/local/bin/chk-nginx.sh"
    interval 1
    weight -10
    }
    vrrp_instance haproxy {
    ! 不設 MASTER,雙機都是 BACKUP,只根據 priority選舉主機地位。
    ! 備機 lbserver_02 的 priority 為 220
    state BACKUP
    interface eth0
    virtual_router_id 43
    priority 225
    advert_int 1
    authentication {
    auth_type PASS
    auth_pass PasswordForAuth
    }
    virtual_ipaddress {
    202.1.1.97/24
    202.1.1.98/24
    202.1.1.99/24
    }
    track_script {
    check-haproxy
    }
    ! 如果本機變為主機,則運行指定的腳本,腳本內容是使用 /etc/mail.rc 中配置的發信帳號向指定的接收郵箱發郵件。
    notify_master "/usr/local/bin/haproxy-master-change.sh"
    }
    ! 為內部正向代理設置主備切換。其實沒有必要,但是如果 nginx 要配置 http 反向代理,這部分還是必須的。
    ! 注意這里的 interface, virtual_router_id 跟上面vrrp_instance haproxy 的是不同的。
    ! virtual_ipaddress 10.1.1.10/24 ,還記得這個IP么?
    vrrp_instance internalproxy {
    state BACKUP
    interface eth1
    virtual_router_id 80
    priority 225
    advert_int 1
    authentication {
    auth_type PASS
    auth_pass PasswordForAuth
    }
    virtual_ipaddress {
    10.1.1.10/24
    }
    track_script {
    check-nginx
    }
    notify_master "/usr/local/bin/nginx-master-change.sh"
    }

    9、haproxy 配置文件

    [root@lbserver_01:/root]# vim /etc/haproxy/haproxy.cfg

    #---------------------------------------------------------------------
    # Example configuration for a possible web application.  See the
    # full configuration options online.
    #
    #   http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
    #
    #---------------------------------------------------------------------
    #---------------------------------------------------------------------
    # Global settings
    #---------------------------------------------------------------------
    global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #   by adding the '-r' option to the SYSLOGD_OPTIONS in
    #   /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #   local2.*                       /var/log/haproxy.log
    #這一條配合/etc/rsyslog.conf
    log      127.0.0.1 local2
    chroot    /var/lib/haproxy
    pidfile  /var/run/haproxy.pid
    #自定義最大連接數
    maxconn  10240
    user        haproxy
    group      haproxy
    daemon
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats
    #默認值是1024,haproxy啟動時會報錯,但并不影響服務。改成2048后據說會有一點兒性能問題。
    tune.ssl.default-dh-param 2048
    #---------------------------------------------------------------------
    # common defaults that all the 'listen' and 'backend' sections will
    # use if not designated in their block
    #---------------------------------------------------------------------
    defaults
    mode                    http
    log                  global
    option                httplog
    option                dontlognull
    option http-server-close
    option                redispatch
    retries              3
    timeout http-request    10s
    timeout queue          1m
    timeout connect      10s
    timeout client        1m
    timeout server        1m
    timeout http-keep-alive 10s
    timeout check          10s
    maxconn              8192
    #---------------------------------------------------------------------
    # main frontend which proxys to the backends
    #---------------------------------------------------------------------
    # https網站發布,server.pem 是crt文件和key文件合并而成:cat server.cer server.key | tee server.pem
    # http網站發布除了 bind *:80 無需指定服務器證書之外,其他配置相同
    # 另外,haproxy 跟 keepalived 配合時,bind 后面只能用* 。如果指定了 IP,備機haproxy將無法啟動,因為平時狀態備機是不具備虛擬IP地址的。
    frontend ssl
    mode http
    bind *:443  ssl crt /etc/haproxy/server.pem
    option httplog
    option httpclose
    # 這條可以使后端web服務器獲得用戶真實 IP,在httpd,tomcat 等日志格式配置里,用 %{X-Forwarded-For}i 記錄用戶真實 IP 。
    option forwardfor   except 127.0.0.0/8  
    stats  hide-version
    #根據域名指定后端服務器
    #   acl名稱                    條件           域名(-i 忽略大小寫)
    acl domain_starts_with_www    hdr_beg(host) -i www.example.com
    acl domain_starts_with_auth  hdr_beg(host)  -i auth.example.com
    acl domain_starts_with_shops    hdr_beg(host)   -i shops.example.com
    #這里千萬不能單獨指定 www 的backend,那樣會使所有的url規則失效。www 只能作為default后端
    use_backend auth    if domain_starts_with_auth  
    use_backend shops   if domain_starts_with_shops
    #根據域名后的路徑指定后端服務器
    acl url_users      path_beg -i /users
    acl url_topsales    path_beg    -i /topsales
    #if 后面多個 acl 時,and用空格代替, or 必須要寫
    use_backend users   if domain_starts_with_www  url_users
    use_backend topsales if domain_starts_with_www  url_topsales
    #其他不符和acl條件的統統指定給后端 www
    default_backend     www
    backend www
    #需要保持會話session的必須用source算法,即同一個外網IP的用戶始終訪問同一臺后端。
    balance source
    # haproxy 設置了服務器證書,后端真實web服務器用普通http就可以了
    server  httpd_tomcat1 10.1.1.20:80 check
    server  httpd_tomcat2 10.1.1.21:80 check
    server  httpd_tomcat1 10.1.1.22:80 check
    server  httpd_tomcat2 10.1.1.23:80 check
    backend auth
    #auth 無需保持會話,所以用隨機負載均衡算法roundrobin即可。
    balance roundrobin
    server  httpd_tomcat_auth 10.1.1.30:80 check
    server  httpd_tomcat_auth 10.1.1.31:80 check
    backend shops
    balance source
    server  httpd_tomcat_auth 10.1.1.40:80 check
    server  httpd_tomcat_auth 10.1.1.41:80 check
    server  httpd_tomcat_auth 10.1.1.42:80 check
    server  httpd_tomcat_auth 10.1.1.43:80 check
    backend users
    balance source
    server  httpd_tomcat_auth 10.1.1.50:80 check
    server  httpd_tomcat_auth 10.1.1.51:80 check
    backend topsales
    balance source
    server  httpd_tomcat_auth 10.1.1.60:80 check
    server  httpd_tomcat_auth 10.1.1.61:80 check
    #haproxy 還支持tcp反向代理
    frontend ssh *:3306
    mode        tcp
    maxconn  128
    option    tcplog
    default_backend mysql
    backend mysql
    mode        tcp
    balance  source
    server    mysql1    10.1.1.200:3306 check
    #End

    四、各種輔助腳本

    1、服務健康狀況檢查腳本

    /usr/local/bin/chk-haproxy.sh

    #!/bin/bash
    ps aux|grep "/usr/sbin/haproxy"|grep -v grep

    /usr/local/bin/chk-nginx.sh

    #!/bin/bash
    ps aux|grep nginx|egrep '(master|worker)'

    原來的chk-haproxy.sh是這樣的:

    netstat -lntp|egrep '(.*443.*haproxy|.*3306.*haproxy)'

    實驗時工作的不錯,等配好了后端服務器做壓力測試,卻突然連續收到master-change郵件。

    用top一看,主機的 netstat 進程 CPU占用率都超過 haproxy 了,達到20%+。估計是 chk-haproxy.sh 腳本發生運行失敗導致keepalived進行了主備切換,切換后主機chk-haproxy.sh腳本恢復正常,備機chk-haproxy.sh腳本可能過載,所以很快又收到master-change郵件。用 ps aux 替換 netstat 就沒有問題了。

    2、郵件通知腳本

    /usr/local/bin/haproxy-master-change.sh

    #!/bin/bash

    echo "`uptime; ip addr show eth0; echo`" | mail -s "`hostname -s` to HAPROXY master."  -c supervisor@example.com receiver-01@example.com receiver-02@example.com

    /usr/local/bin/nginx-master-change.sh

    #!/bin/bash
    echo "`uptime; ip addr show eth1; echo`" | mail -s "`hostname -s` to NGINX master." receiver-03@example.com receiver-04@example.com

    echo "...."     郵件正文,含主機名和 IP 地址,

    -s         郵件標題

    -c        抄送地址(必須寫在收件人前面)

    最后可以跟 n 個收件人地址

    3、服務器狀態查看腳本

    捕獲 keepalived 組播數據,可以看到當前主機的 priority (prio 225)。

    /usr/local/bin/kawatch.sh

    #!/bin/bash
    tcpdump -vvv -n -i eth0 dst 224.0.0.18

    運行起來是這樣的:

    tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
    23:10:14.066857 IP (tos 0xc0, ttl 255, id 7007, offset 0, flags [none], proto VRRP (112), length 52)
    202.1.1.101 > 224.0.0.18: VRRPv2, Advertisement, vrid 43, prio 225, authtype simple, intvl 1s, length 32, addrs(3): 202.1.1.97,202.1.1.98,202.1.1.99 auth "PasswordForAuth"
    23:10:15.068072 IP (tos 0xc0, ttl 255, id 7008, offset 0, flags [none], proto VRRP (112), length 52)
    202.1.1.101 > 224.0.0.18: VRRPv2, Advertisement, vrid 43, prio 225, authtype simple, intvl 1s, length 32, addrs(3): 202.1.1.97,202.1.1.98,202.1.1.99 auth "PasswordForAuth"
    23:10:16.069224 IP (tos 0xc0, ttl 255, id 7009, offset 0, flags [none], proto VRRP (112), length 52)
    202.1.1.101 > 224.0.0.18: VRRPv2, Advertisement, vrid 43, prio 225, authtype simple, intvl 1s, length 32, addrs(3): 202.1.1.97,202.1.1.98,202.1.1.99 auth "PasswordForAuth"
    ......

    以下是常用的 netstat 指令,總用懶得敲那么多字母,就精簡一下吧:

    /usr/local/bin/nsl

    #!/bin/bash
    netstat -lntp

    /usr/local/bin/nsa

    #!/bin/bash
    netstat -antp

    /usr/local/bin/nse

    #!/bin/bash
    netstat -antp|grep ESTABLISHED
    原文  http://www.cnblogs.com/panblack/p/haproxy_nginx_keepalived_mailaler

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!