架構測試:HAproxy實現負載均衡,前端爲nginx+php,數據庫實現讀寫分離和高可用

架構測試:HAproxy實現負載均衡,前端爲nginx+php,數據庫實現讀寫分離和高可用

環境:

• 202.106.0.6: as client
• 202.106.0.17:as firewall 
• 202.106.0.147: as powerDNS
• 192.168.205.27: as NFS server
• 192.168.205.37: as NFS Backup server(inotify+rsync)
• 192.168.205.47: as proxysql1
• 192.168.205.57: as porxysql2
• 192.168.205.67: as MHA for manager mysql master/slave
• 192. 168.205.77: as mysql primary
• 192.168.205.87: as mysql secondary
• 192.168.205.97: as secondary 2
• 192.168.205.107: as HAproxy1
• 192.168.205.117: as HAproxy2
• 192.168.205.127: as web1 (nginx +php+wordpress)
• 192.168.205.137: as web2 (nginx +php+wordpress)
注:所有操作系統默認停用firewalld,iptable爲空,關閉selinux

版本:

  • OS: centos 7 1810 with mini install
  • poweradmin-2.1.7.tgz
  • mariadb-5.5.60(主要測試主從自動切換和讀寫分離沒有使用高版本)
  • nginx-1.16.1.tar.gz
  • php-7.3.7.tar.xz
  • wordpress-5.0.4-zh_CN.tar.gz
  • mha4mysql-manager-0.56-0.el6.noarch.rpm
  • mha4mysql-node-0.56-0.el6.noarch.rpm
    注:其它未註明均爲yum 安裝

目地:

• 實現nginx編譯安裝和支持fast-cgi, 編譯安裝php7.3支持最新的wordpress,
• 通過MHA實現主從的自動切換,通過proxysql實現讀寫的分離,並實瑞proxy的高可用性
• web靜態頁面存在nfs共享文件中,通地inotify 和rsync進行實時的備份網站的數據。
• 前端通過haproxy實現負載均衡

步驟:

1. 安裝mariadb並配置主從
2. 配置半同步複製
3. 實現MHA管理
4. 實現proxysql
5. 實現proxysql的keepalive
6. 安裝rsync server做爲nfs backup服務器
7. 安裝nginx和php
8. 安裝haproxy
9. 實現firewall DNAT
10. 測試

安裝mariadb,實現主從

  1. 通過腳本yum真接安裝mariadb在77,87,97上,安裝完成後自動重啓
    [root@master data]#vi maridb_yum.sh 
    #!/bin/bash
    ID=`ip a show dev eth0 | sed -r '3!d;s@(.*inet)(.*)(/.*)@\2@' | cut -d. -f4`
    rpm -q mariadb-server ||yum install -y mariadb-server
    [ -d /data/mysql ] || mkdir -p /data/mysql
    [ -d /data/logs ] || mkdir -p /data/logs
    chown mysql:mysql /data/{mysql,logs}
    sed -i 's@datadir=/var/lib/mysql@datadir=/data/mysql@' /etc/my.cnf
    grep "log-bin" /etc/my.cnf || sed -i '/\[mysqld\]/a log-bin=/data/logs/bin' /etc/my.cnf
    rep "innodb_file_per_table" /etc/my.cnf || sed -i '/\[mysqld\]/a innodb_file_per_table = on' /etc/my.cnf
    grep "skip_name_resolve" /etc/my.cnf || sed -i '/\[mysqld\]/a skip_name_resolve = on' /etc/my.cnf
    grep "server-id" /etc/my.cnf || sed -i "/\[mysqld\]/a server-id=$ID" /etc/my.cnf
    service mariadb restart
  2. 修改slave數據庫的配置
    [root@slave1 ~]#vi /etc/my.cnf
    [mysqld]
    read_only
    relay_log_purge=0          
    [root@slave1 ~]#systemctl restart mariadb   
    [root@slave2 ~]#vi /etc/my.cnf
    [mysqld]     
    read_only
    [root@slave2 ~]#systemctl restart mariadb
  3. 在主服務器上記錄複製位置
    MariaDB [(none)]> show master logs;
  4. 在主服務器創建同步帳號
    MariaDB [(none)]> grant replication slave on *.* to repluser'192.168.205.%' identified by 'centos';
  5. 分別在從服務器上修改change master to
    CHANGE MASTER TO
    MASTER_HOST='192.168.205.77',
    MASTER_USER='repluser',
    MASTER_PASSWORD='centos',
    MASTER_PORT=3306,
    MASTER_LOG_FILE='bin.000003',  #此文件跟據主上的show master logs
    MASTER_LOG_POS=245;               #此位置跟據主上的show master logs
  6. 在所有的從節點上啓動i/o線和relay線程
    MariaDB [(none)]> satar slave
    MariaDB [(none)]> show slave status;

    配置半同步複製

  7. 記錄半同步插件的文件名稱
    [root@master ~]#rpm -ql mariadb-server
    /usr/lib64/mysql/plugin/semisync_master.so
    /usr/lib64/mysql/plugin/semisync_slave.so
  8. 在主服務器和從服務器上安裝半同步插件
    MariaDB [(none)]> install plugin rpl_semi_sync_master soname 'semisync_master.so';
  9. 查看半同步的狀態
    MariaDB [(none)]> show global variables like '%semi%' ;
    +------------------------------------+-------+
    | Variable_name                      | Value |
    +------------------------------------+-------+
    | rpl_semi_sync_master_enabled       | OFF   | #半同步默認off
    | rpl_semi_sync_master_timeout       | 10000 | #超時毫秒,10秒
    | rpl_semi_sync_master_trace_level   | 32    |
    | rpl_semi_sync_master_wait_no_slave | ON    |
    +------------------------------------+-------+
    4 rows in set (0.00 sec)
  10. 啓用半同步
    MariaDB [(none)]> set global rpl_semi_sync_master_enabled=on;
    Query OK, 0 rows affected (0.00 sec)
  11. 查看半同步狀態信息
    MariaDB [(none)]> show global status like '%semi%';
    +--------------------------------------------+-------+
    | Variable_name                              | Value |
    +--------------------------------------------+-------+
    | Rpl_semi_sync_master_clients               | 0     |
    | Rpl_semi_sync_master_net_avg_wait_time     | 0     |
    | Rpl_semi_sync_master_net_wait_time         | 0     |
    | Rpl_semi_sync_master_net_waits             | 0     |
    | Rpl_semi_sync_master_no_times              | 0     |
    | Rpl_semi_sync_master_no_tx                 | 0     |
    | Rpl_semi_sync_master_status                | ON    |
    | Rpl_semi_sync_master_timefunc_failures     | 0     |
    | Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
    | Rpl_semi_sync_master_tx_wait_time          | 0     |
    | Rpl_semi_sync_master_tx_waits              | 0     |
    | Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
    | Rpl_semi_sync_master_wait_sessions         | 0     |
    | Rpl_semi_sync_master_yes_tx                | 0     |
    +--------------------------------------------+-------+
    14 rows in set (0.00 sec)
  12. 在所有的從節點安裝slave semi插件;
    MariaDB [(none)]> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
    Query OK, 0 rows affected (0.00 sec)
    MariaDB [(none)]> show plugins;
    …
    | rpl_semi_sync_slave            | ACTIVE   | REPLICATION        | semisync_slave.so | GPL     |
    +--------------------------------+----------+--------------------+-------------------+---------+
    43 rows in set (0.00 sec)
  13. 查看所有從節點的半同步狀態,並啓用半同步狀態,需要重新啓動線程,再查看半同步狀態是on纔可以
    MariaDB [(none)]> show global variables like '%semi%';
    +---------------------------------+-------+
    | Variable_name                   | Value |
    +---------------------------------+-------+
    | rpl_semi_sync_slave_enabled     | OFF   |
    | rpl_semi_sync_slave_trace_level | 32    |
    +---------------------------------+-------+
    2 rows in set (0.00 sec)
    MariaDB [(none)]> set global rpl_semi_sync_slave_enabled=on; 
    Query OK, 0 rows affected (0.00 sec)
    MariaDB [(none)]> show global variables like '%semi%';      
    +---------------------------------+-------+
    | Variable_name                   | Value |
    +---------------------------------+-------+
    | rpl_semi_sync_slave_enabled     | ON    |
    | rpl_semi_sync_slave_trace_level | 32    |
    +---------------------------------+-------+
    2 rows in set (0.00 sec)
    MariaDB [(none)]> stop slave;
    Query OK, 0 rows affected (0.00 sec)
    MariaDB [(none)]> start slave;
    Query OK, 0 rows affected (0.00 sec)
    MariaDB [(none)]> show global status like '%semi%';  
    +----------------------------+-------+
    | Variable_name              | Value |
    +----------------------------+-------+
    | Rpl_semi_sync_slave_status | ON    |
    +----------------------------+-------+
    1 row in set (0.00 sec)
  14. 此時查看主節點的狀態
    MariaDB [(none)]> show global status like '%semi%';
    +--------------------------------------------+-------+
    | Variable_name                              | Value |
    +--------------------------------------------+-------+
    | Rpl_semi_sync_master_clients               | 2     | #表示已經有兩個客戶端,說明成功
    | Rpl_semi_sync_master_net_avg_wait_time     | 0     |
    | Rpl_semi_sync_master_net_wait_time         | 0     |
    | Rpl_semi_sync_master_net_waits             | 0     |
    | Rpl_semi_sync_master_no_times              | 0     |
    | Rpl_semi_sync_master_no_tx                 | 0     |
    | Rpl_semi_sync_master_status                | ON    | #狀態是on表半同步打開
    | Rpl_semi_sync_master_timefunc_failures     | 0     |
    | Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
    | Rpl_semi_sync_master_tx_wait_time          | 0     |
    | Rpl_semi_sync_master_tx_waits              | 0     |
    | Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
    | Rpl_semi_sync_master_wait_sessions         | 0     |
    | Rpl_semi_sync_master_yes_tx                | 0     |
    +--------------------------------------------+-------+
    14 rows in set (0.00 sec)

    實現MHA管理

  15. 安裝從mha網站下載的mha rpm軟件包,依賴包要去epel下載,所以要啓用epel源
    [root@MHA ~]#yum install mha4mysql-manager-0.56-0.el6.noarch.rpm mha4mysql-node-0.56-0.el6.noarch.rpm 
  16. 所有節點上安裝node包,無論主不是從,mha都會當做一個node來看
    [root@master ~]#yum install mha4mysql-node-0.56-0.el6.noarch.rpm 
    [root@slave1 data]#yum install mha4mysql-node-0.56-0.el6.noarch.rpm 
    [root@slave2 data]#yum install mha4mysql-node-0.56-0.el6.noarch.rpm 
  17. 在主服務器上創建帳號做爲mha的監控帳號使用
    MariaDB [(none)]> grant all on *.* to mhauser@'192.168.205.%' identified by 'centos';
  18. 由於主從在切換時,MHA要修改配置文件等,所以需要ssh key驗證,我們採用速的方法,直接在本地產生key和authorized文件一併複製到所有節點
    [root@MHA ~]#ssh-keygen 
    [root@MHA ~]#ssh-copy-id 192.168.205.67
    [root@MHA ~]#cat .ssh/authorized_keys 
    [root@MHA ~]#scp -r .ssh 192.168.205.77:/root/
    [root@MHA ~]#scp -r .ssh 192.168.205.87:/root/
    [root@MHA ~]#scp -r .ssh 192.168.205.97:/root/
  19. MHA配置文件沒有,我們直接按照如下創建
    [root@MHA ~]#mkdir /etc/mha
    [root@MHA ~]#vim /etc/mha/app1.cnf
    [server default]
    master_binlog_dir=/data/logs/ 
    user=mhauser      #這個帳號爲mha監控mysql的帳號
    password=centos  #帳號的密碼
    manager_workdir=/data/mastermha/app1/   #配置文件的存放位置
    manager_log=/data/mastermha/app1/manager.log   #日誌的存放位置
    remote_workdir=/data/mastermha/app1/             
    ssh_user=root           #SSH key連接的用戶名
    repl_user=repluser     #複製帳號,也就是我們上面創建的複製帳號名
    repl_password=centos  #複製帳號的密碼
    ping_interval=1         #檢測間隔爲每一秒
    [server1]   #定議節點服務器
    hostname=192.168.205.77  
    candidate_master=1
    [server2]
    hostname=192.168.205.87  
    [server3]
    hostname=192.168.205.97  
    candidate_master=1   #表示當主不可用時優先提升爲主的從服務器
  20. 啓動之前進行檢查ssh,repl複製是否準備好, 如果successful 我們可以進行下一步。
    [root@MHA ~]#masterha_check_ssh --conf=/etc/mha/app1.cnf
    [root@MHA ~]#masterha_check_repl --conf=/etc/mha/app1.cnf
  21. 起動進程,此進程前臺運行,當主節點失敗時切換完成後它會終止,所以要想持續要重啓進程
    [root@MHA ~]#masterha_manager --conf=/etc/mha/app1.cnf
    Mon Aug 12 23:33:22 2019 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
    Mon Aug 12 23:33:22 2019 - [info] Reading application default configuration from /etc/mha/app1.cnf..
    Mon Aug 12 23:33:22 2019 - [info] Reading server configuration from /etc/mha/app1.cnf..

    實現proxysql

  22. 我們直接在兩個proxysql服務器上創建yum源來安裝proxysql
    cat <<EOF | tee /etc/yum.repos.d/proxysql.repo
    [proxysql_repo]
    name= ProxySQL YUM repository
    #baseurl=https://repo.proxysql.com/ProxySQL/proxysql-2.0.x/centos/\$releasever
    baseurl=https://repo.proxysql.com/ProxySQL/proxysql-1.4.x/centos/\$releasever
    gpgcheck=1
    gpgkey=https://repo.proxysql.com/ProxySQL/repo_pub_key
    EOF
  23. 因爲proxysql是一個基於輕量的數據庫配置的,所以我們需要一個sql客戶端來連接設置proxysql
    [root@proxysql1 ~]#yum install proxysql mariadb
    [root@proxysql2 ~]#yum install proxysql mariadb
  24. 啓動服務器查看端口,其中6032爲proxysql的數據庫端口,6033爲proxysql的用戶連接端口
    [root@proxysql1 ~]#service proxysql start
    [root@proxysql2 ~]#service proxysql start
    [root@proxysql1 ~]#ss -ntl
    State       Recv-Q Send-Q                 Local Address:Port                                Peer Address:Port              
    LISTEN      0      128                                *:6032                                           *:*                  
    LISTEN      0      128                                *:6033                                           *:*                  
    LISTEN      0      128                                *:6033                                           *:*                  
    LISTEN      0      128                                *:6033                                           *:*                  
    LISTEN      0      128                                *:6033                                           *:*              
  25. proxysql默認的用戶名和密碼是admin admin, 監聽端口爲6032,
    [root@proxysql1 ~]#mysql -uadmin -padmin -P6032 -h127.0.0.1 
  26. 在所有的proxysql註冊sql server的節點,包括所有的主從節點,使有和insert插入記錄到mysql_servers庫用
    MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port) values(10,'192.168.205.77',3306);
    MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port) values(10,'192.168.205.87',3306);
    MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port) values(10,'192.168.205.97',3306);
    MySQL [(none)]> load mysql servers to runtime;
    MySQL [(none)]> save mysql servers to disk;
  27. 查看一下我們剛纔添加的主機記錄是否在庫中
    MySQL [(none)]> select * from mysql_servers;
  28. 由於proxysql是查看主和從的數據的read_only來判讀誰是主誰是從的,所以建立一賬號用來連接到主和從服務器上,我們要在主節點上建立這個帳號,它會複製到從節點上
    MariaDB [(none)]> grant replication client on *.* to monitor@'192.168.205.%' identified by 'centos';
  29. 在所有的proxysql服務器設置監控賬號,保存狀態
    MySQL [(none)]> set mysql-monitor_username='monitor';
    MySQL [(none)]> set mysql-monitor_password='centos'; 
    MySQL [(none)]> load mysql variables to runtime; 
    MySQL [(none)]> save mysql variables to disk;
  30. 查看一下相關的日誌,以前出錯的原因是因爲默認沒使用monitor密碼是monitor進行連接(在proxysql.cnf中可以看到),所以會出錯,當你添加完帳號就成功了,
    MySQL [(none)]> select * from mysql_server_connect_log;
    MySQL [(none)]> select * from mysql_server_ping_log;
  31. 需要修改的是main庫中的mysql_replication_hostgroups表,該表有3個字段:writer_hostgroup, reader_hostgroup,comment, 指定寫組的id爲10,讀組的id爲20
    MySQL [(none)]> insert into mysql_replication_hostgroups values(10,20,"test");
    MySQL [(none)]> load mysql servers to runtime; 
    MySQL [(none)]> save mysql servers to disk;
  32. proxySQL會跟據剛纔連接帳號判斷read_only並自動的把三個服務器按讀寫組加到這個表中了
    MySQL [(none)]> select hostgroup_id,hostname,port,status,weight from mysql_servers;
    MySQL [(none)]> select * from mysql_server_read_only_log;
  33. 在主服務器上設置一個帳號用來測試
    MySQL [(none)]> grant all on *.* to sqluser@'192.168.205.%' identified by 'centos'; 
  34. 在proxysql服務器上設置這個帳號的缺省組爲10
    MySQL [(none)]> insert into mysql_users(username,password,default_hostgroup) values('sqluser','centos',10);
    MySQL [(none)]> load mysql users to runtime;
    MySQL [(none)]> save mysql users to disk;
  35. 此時proxysql還是不知道那些sql語句算讀,那些爲寫,我們要定義好,讓它來區別併發送到不同的組服務器上,其中10爲寫,20組爲讀
    MySQL [(none)]>insert into mysql_query_rules
    (rule_id,active,match_digest,destination_hostgroup,apply) VALUES
    (1,1,'^SELECT.*FOR UPDATE$',10,1),(2,1,'^SELECT',20,1);  
    MySQL [(none)]>load mysql query rules to runtime;
    MySQL [(none)]>save mysql query rules to disk; 
  36. 查看一下你添加的規則
    MySQL [(none)]>select rule_id,active,match_digest,destination_hostgroup,apply from mysql_query_rules;
  37. 測試連接並實現讀,可以看到一會調度到87,一會調度到97
    mysql -usqluser -pcentos -P6033 -h127.0.0.1 -e 'select @@server_id'
  38. 如果使用事務不能發送到讀服務器,只會發送到主服務器
    mysql -usqluser -pcentos -P6033 -h127.0.0.1 -e 'begin;select @@server_id;commit'   
    mysql -usqluser -pcentos -P6033 -h127.0.0.1 -e 'create database testdb' 
    mysql -usqluser -pcentos testdb -P6033 -h127.0.0.1 -e 'create table t1(id int)'
  39. 我們可以用下列查詢看調度是否成功,並調度到那臺服務器上
    select hostgroup hg,sum_time,count_star,digest_text from stats_mysql_query_digest order by sum_time desc; 

    實現proxysql的keepalive

  40. 使用yum安裝keepalvie,psmisc,psmisc中有個命令爲killall可以檢測到進程的狀態,keepalive會使用這個做爲腳本檢測進行是否運行
    [root@proxysql1 ~]#yum install keepalived ipvsadm psmisc
    [root@proxysql2 ~]#yum install keepalived ipvsadm psmisc
  41. 修改keepalive配置文件
    [root@proxysql1 ~]#vi /etc/keepalived/keepalived.conf   
    global_defs {
    notification_email {
     root@localhost
    }
    notification_email_from keepalived@localhost
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    router_id LVS_1
    vrrp_mcast_group4 224.0.0.100
    }
    # Script used to check if Proxy is running
    vrrp_script check_proxy {                    #定義腳本測試proxysql的進程,如果進程down實現主備切換
    script "killall -0 proxysql"     #監控進程
    interval 2                                       #每二秒監控一次
    weight -30                                      #進程down時priority減30
    fall 2
    rise 1
    }
    vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 45
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.205.45/24 dev eth0 label eth0:0
    }
    track_script {
      check_proxy
    }
    }
    [root@proxysql1 ~]#systemctl start keepalived
  42. 修改proxysql2的keepalive
    [root@proxysql2 ~]#vi /etc/keepalived/keepalived.conf
    global_defs {
    notification_email {
     root@localhost
    }
    notification_email_from keepalived@localhost
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    router_id LVS_2
    vrrp_mcast_group4 224.0.0.100
    }
    # Script used to check if Proxy is running
    vrrp_script check_proxy {
    script "killall -0 proxysql"
    interval 2
    weight -30
    fall 2
    rise 1
    }
    vrrp_instance VI_1 {
    state BACKUP 
    interface eth0
    virtual_router_id 45
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.205.45/24 dev eth0 label eth0:0
    }
    track_script {
      check_proxy
    }
    }
    [root@proxysql2 ~]#systemctl start keepalived
  43. 在proxysql1上查看IP,可以看到vip 192.168.205.45, 停掉服務,看一下IP
    [root@proxysql1 ~]#ip a
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:37:f9:93 brd ff:ff:ff:ff:ff:ff
    inet 192.168.205.47/24 brd 192.168.205.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet 192.168.205.45/24 scope global secondary eth0:0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe37:f993/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
    [root@proxysql1 ~]#systemctl stop proxysql
  44. 在proxysql2上查看可以看到vip 192.168.205.45已經飄到了proxysql2上
    [root@proxysql2 ~]#ip a
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:cf:e5:bb brd ff:ff:ff:ff:ff:ff
    inet 192.168.205.57/24 brd 192.168.205.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet 192.168.205.45/24 scope global secondary eth0:0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fecf:e5bb/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
  45. 我們測試一下能否通過web server通過連接vip連接到後端的服務器,從而實現讀寫分離
    [root@web1 data]#mysql -uwordpress -pcentos -P6033 -h192.168.205.45

    安裝rsync server做爲nfs backup服務器

  46. 安裝rsync服務
    [root@nfs2 data]#yum install rsync
  47. 編輯rsyncd.conf文件,讓rsyncc以daemon的方式運行
    [root@nfs2 data]#vi /etc/rsyncd.conf
    uid = root  #以什麼身份開啓服務
    gid = root
    use chroot = no   
    max connections = 0  #不限制連接
    ignore errors                #忽略錯誤
    exclude = lost+found/
    log file = /var/log/rsyncd.log
    pid file = /var/run/rsyncd.pid
    lock file = /var/run/rsyncd.lock
    reverse lookup = no  反向解析名稱與ip
    hosts allow = 192.168.205.0/24  充許連接的主機列表
    [backup]   起名子
    path = /data/www/
    comment = webserver www backup
    read only = no  可以寫
    auth users = rsync
    secrets file = /etc/rsync.pass  密碼文件
  48. 服務器端生成驗證文件
    [root@nfs2 data]#echo "rsync:centos" > /etc/rsync.pass
    [root@nfs2 data]#chmod 600 /etc/rsync.pass
  49. 服務器端準備目錄
    [root@nfs2 data]#mkdir /data/www
  50. 服務器端啓動rsync服務
    [root@nfs2 data]#systemctl start rsyncd 

    啓用NFS服務器

  51. 啓用epel
    [root@nfs1 data]#yum install inotify-tools  nfs-utils rsync
  52. 創建目錄
    [root@nfs1 data]#mkdir /data/www
  53. 創建用戶nginx用戶
    [root@nfs1 data]# useradd -s /sbin/nologin nginx -u 2000
    [root@nfs1 data]# id nginx
    uid=2000(nginx) gid=2000(nginx) groups=2000(nginx)
  54. 修改NFS配置文件,共享www目錄
    [root@nfs1 data]# vi /etc/exports
    /data/www 192.168.205.0/24(rw,all_squash,anonuid=2000,anongid=2000)    
    [root@nfs1 data]# systemctl restart nfs-server
  55. 將NFS服務器配置爲rsync的客戶端,先配置密碼文件
    [root@nfs1 data]#echo "centos" > /etc/rsync.pass
    [root@nfs1 data]#chmod 600 /etc/rsync.pass
  56. 安裝inotify實現實時同步數據,客戶端創建inotify_rsync.sh腳本
    [root@nfs1 data]#cat inotify_rsync.sh 
    #!/bin/bash
    SRC='/data/www/'
    DEST='[email protected]::backup'
    inotifywait -mrq --timefmt '%Y-%m-%d %H:%M' --format '%T %w %f' \
    -e create,delete,moved_to,close_write,attrib ${SRC} | \
    while read DATE TIME DIR FILE;do
    FILEPATH=${DIR}${FILE}
    rsync -az --delete --password-file=/etc/rsync.pass $SRC $DEST && echo "At ${TIME} \
    on ${DATE}, file $FILEPATH was backuped up via rsync" >> /var/log/changelist.log
    done
  57. 將腳本文件存在rc.local中,啓動進會自動執行
    [root@nfs1 data]#chmod +x inotify_rsync.sh
    [root@nfs1 data]#vi /etc/rc.d/rc.local
    /data/inotify_rsync.sh &   
    [root@nfs1 data]#chmod +x /etc/rc.d/rc.local
  58. 在web server中實現掛載,安裝nfs-utils工具纔可以mount NFS文件系統
    [root@web1 ~]#yum install nfs-utils 
    [root@web2 ~]#yum install nfs-utils
  59. 測試連接NFS服務器的共享文件
    [root@web1 ~]#showmount -e 192.168.205.27
    Export list for 192.168.205.27:
    /data/www 192.168.205.0/24
    [root@web1 ~]#mount 192.168.205.27:/data/www /data/www
    [root@web2 ~]#mount 192.168.205.27:/data/www /data/www
    [root@web1 ~]#df
    [root@web2 ~]#df
  60. 在兩個web server中將mount寫入到fstab文件中,實現開機自動mount
    [root@web1 ~]##vi /etc/fstab
    192.168.205.27:/data/www  /app/httpd24/htdocs nfs defaults  0 0 

    安裝nginx和php

  61. 複製nginx和php源碼文件到一個目錄中在兩個web服務器上
    nginx-1.16.1.tar.gz
    php-7.3.7.tar.xz
  62. 執行nginx安裝腳本在同一個目錄中
    [root@web2 ~]#cat nginx_install_bin.sh 
    #!/bin/bash
    #########################
    #difination variables
    #########################
    TMP_DIR=`pwd`
    NGINX="nginx-1.16.1.tar.gz"
    NGINX_DIR=`echo "$NGINX" |rev | cut -d. -f3- | rev`
    INS_DIR="/apps/nginx"
    ##########################
    #Packges check and install
    ##########################
    pkg(){
    for i in $PKGS; do
    rpm -q $i &> /dev/null && echo "Packge `rpm -q $i` is installed" || yum -y install $i
    done
    }
    #####################
    #NGINX INSTALLATION
    #1.unarchive binary 
    ####################
    #install dependency packges,just add packges name to variable PKGS separate by SPACE.
    #Example PKGS="libaio gcc glibc"  
    nginx_ins(){
    PKGS="gcc pcre-devel openssl-devel zlib-devel"
    pkg
    cd $TMP_DIR
    [ -e $TMP_DIR/$NGINX ] || wget -c http://nginx.org/download/$NGINX
    tar xf $TMP_DIR/$NGINX
    cd $NGINX_DIR
    ./configure \
    --prefix=$INS_DIR \
    --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-http_gzip_static_module \
    --with-http_realip_module \
    --with-pcre \
    --with-threads \
    --with-file-aio \
    --with-stream \
    --with-stream_ssl_module \
    --with-stream_realip_module
    if [ $? -eq 0 ]; then
    make -j 4 && make install
    cd $TMP_DIR
    rm -rf $HTTPD_DIR
    else
    echo "please remake and make install"
    fi
    id nginx || useradd nginx -s /sbin/nologin -u 2000
    chown nginx:nginx -R $INS_DIR
    echo "$INS_DIR/sbin/nginx" >> /etc/rc.d/rc.local
    chmod +x /etc/rc.d/rc.local
    ln -s $INS_DIR/sbin/nginx /sbin/nginx
    nginx
    }
    ###############
    #OPTIONS SELECT
    ###############
    case $1 in 
    install)
    nginx_ins
    ;;
    remove)
    nginx_rm
    ;;
    *)
    echo "Useage $0 $1 install|remove"
    ;;
    esac
    [root@web2 ~]#./nginx_install_bin.sh install
  63. 執行如下腳本安裝php
    [root@web2 ~]#cat apache_php_install.sh 
    #!/bin/bash
    #########################
    #difination variables
    #########################
    TMP_DIR=`pwd`
    APR="apr-1.7.0.tar.bz2"
    APR_UTIL="apr-util-1.6.1.tar.bz2"
    HTTPD="httpd-2.4.39.tar.bz2"
    PHP="php-7.3.7.tar.xz"
    HTTPD_DIR=`echo "$HTTPD" |rev | cut -d. -f3- | rev`
    APR_DIR=`echo "$APR" |rev | cut -d. -f3- | rev`
    APR_UTIL_DIR=`echo "$APR_UTIL" | rev | cut -d. -f3- | rev`
    PHP_DIR=`echo "$PHP" | rev | cut -d. -f3- | rev`
    INS_HTTPD_DIR=/app/httpd24
    INS_PHP_DIR=/app/php
    ##########################
    #Packges check and install
    ##########################
    pkg(){
    for i in $PKGS; do
    rpm -q $i &> /dev/null && echo "Packge `rpm -q $i` is installed" || yum -y install $i
    done
    }
    #####################
    #APACHE INSTALLATION
    #1.unarchive binary 
    ####################
    #install dependency packges,just add packges name to variable PKGS separate by SPACE.
    #Example PKGS="libaio gcc glibc"  
    httpd_ins(){
    PKGS="gcc prce-devel openssl-devel expat-devel lbzip2"
    pkg
    cd $TMP_DIR
    if [ -e $TMP_DIR/$HTTPD ]; then
        tar xf $HTTPD
    else
        echo "file $HTTPD does not exist, pleases download it" 
        exit
    fi
    if [ -e $TMP_DIR/$APR ]; then
        tar xf $APR 
        mv $APR_DIR $HTTPD_DIR/srclib/apr
    else
        echo "file $APR does not exist, pleases download it"
        exit
    fi
    if [ -e $TMP_DIR/$APR_UTIL ]; then
        tar xf $APR_UTIL
    mv $APR_UTIL_DIR $HTTPD_DIR/srclib/apr-util
    else
        echo "file $APR_UTIL does not exist, pleases download it"
        exit
    fi
    ########################
    #2.make and make install
    ########################
    id apache||useradd -r -s /sbin/nologin apache
    cd $HTTPD_DIR
    ./configure \
    --prefix=$INS_HTTPD_DIR \
    --enable-so \
    --enable-ssl \
    --enable-cgi \
    --enable-rewrite \
    --with-zlib \
    --with-pcre \
    --with-included-apr \
    --enable-modules=most \
    --enable-mpms-shared=all \
    --with-mpm=prefork
    if [ $? -eq 0 ]; then
        make -j 4 && make install
        cd $TMP_DIR
        rm -rf $HTTPD_DIR
    else
        echo "please remake and make install"
    fi
    #####################
    #3. modify config files
    ######################
    sed -ri 's@^(.*) daemon$@\1 apache@' $INS_HTTPD_DIR/conf/httpd.conf
    sed -ri 's@DirectoryIndex@DirectoryIndex index.php @' $INS_HTTPD_DIR/conf/httpd.conf
    sed -ri 's@#(LoadModule proxy_module modules/mod_proxy.so)@\1@' $INS_HTTPD_DIR/conf/httpd.conf
    sed -ri 's@#(LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so)@\1@' $INS_HTTPD_DIR/conf/httpd.conf
    sed -ri 's@#(LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so)@\1@' $INS_HTTPD_DIR/conf/httpd.conf
    cat >> $INS_HTTPD_DIR/conf/httpd.conf <<-EOF
    AddType application/x-httpd-php .php
    AddType application/x-httpd-php-source .phps
    ProxyRequests Off
    ProxyPassMatch "^/.*\.php(/.*)?$" "fcgi://localhost:9000/app/httpd24/htdocs/"
    EOF
    echo "PATH=$INS_HTTPD_DIR/bin:\$PATH" > /etc/profile.d/httpd.sh
    source /etc/profile.d/httpd.sh
    echo "$INS_HTTPD_DIR/bin/apachectl start" >> /etc/rc.d/rc.local
    chmod +x /etc/rc.d/rc.local
    apachectl start
    }
    #########################
    #PHP INSALLATION
    #1. unarchive install packge
    #########################
    php_ins(){
    PKGS="libxml2-devel bzip2-devel libmcrypt-devel gd-devel"
    pkg
    cd $TMP_DIR
    echo $TMP_DIR
    if [ -e $TMP_DIR/$PHP ]; then
        tar xvf $PHP
    else
        echo "files $PHP does not exist, pleases download it"
        exit
    fi
    #######################
    #2. make and make install
    #######################
    cd $PHP_DIR/
    ./configure \
    --prefix=$INS_PHP_DIR \
    --enable-mysqlnd \
    --with-mysqli=mysqlnd \
    --with-pdo-mysql=mysqlnd \
    --with-openssl \
    --with-freetype-dir \
    --with-jpeg-dir \
    --with-png-dir \
    --with-zlib \
    --with-libxml-dir=/usr \
    --with-config-file-path=/etc \
    --with-config-file-scan-dir=/etc/php.d \
    --enable-mbstring \
    --enable-xml \
    --enable-sockets \
    --enable-fpm \
    --enable-maintainer-zts \
    --disable-fileinfo  \
    --with-gd \
    --with-imap\
    --with-ldap\
    --with-odbcver\
    --with-iodbc\
    --with-pear\
    --with-libxml-dir\
    --with-xmlrpc\
    --enable-mbstring\
    --with-mhash\
    --with-gettext
    if [ $? -eq 0 ]; then 
        make && make install
    else
        echo "please re make and make install"
    fi
    ######################
    #3. modify config file
    ######################
    cp php.ini-production /etc/php.ini
    cp sapi/fpm/init.d.php-fpm  /etc/init.d/php-fpm 
    chmod +x /etc/init.d/php-fpm
    cd $INS_PHP_DIR/etc
    cp php-fpm.conf.default php-fpm.conf
    cd php-fpm.d/
    cp www.conf.default www.conf
    sed -ri 's@(^.*) = nobody@\1 = apache@' $INS_PHP_DIR/etc/php-fpm.d/www.conf
    chkconfig --add php-fpm
    service php-fpm start
    cd $TMP_DIR
    rm -rf $PHP_DIR  
    echo '<?php phpinfo(); ?>' > /app/httpd24/htdocs/index.php 
    }
    ##################
    #4. remove PHP
    #################
    rmphp(){
    service php-rpm stop
    rm /app/php -rf
    rm /etc/php.ini -f
    chkconfig --del php-fpm
    rm /etc/init.d/php-fpm -f
    }
    ################
    #5. remove HTTPD
    ################
    rmhttpd(){
    apachectl stop
    rm /app/httpd24 -rf
    sed -i '/\/app\/http24\/bin\/apachectl start/d' /etc/rc.d/rc.local
    rm /etc/profile.d/httpd.sh
    }
    ###############
    #OPTIONS SELECT
    ###############
    case $1 in 
    install)
        case $2 in
                httpd)
                httpd_ins
                ;;
        php)
                php_ins
                ;;
        *)
                echo "Useage $0 $1 httpd|php"
                ;;
        esac
        ;;
    remove)
        case $2 in
                php)
                rmphp
                ;;
                httpd)
          rmhttpd
                ;;
                *)
                echo "Useage $0 $1 httpd|php"
                ;;
        esac
        ;; 
    *)
        echo "Useage $0 <install|remove> <php|httpd>"
        ;;
    esac
    [root@web2 ~]#./apache_php_install.sh install php
  64. 修改nginx配置文件
    [root@web2 ~]#vi /etc/nginx/nginx.conf
    server {
        listen       80;
        server_name  www.zhaoli.com;
        location / {
            root   /data/www;
            index  index.php index.html index.htm;
        }
        location ~ \.php$ {
            root           /data/www;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
     }
  65. 修改php配置文件
    [root@web2 ~]#vi /app/php/etc/php-fpm.d/www.conf
    user = nginx
    group = nginx
    listen = 127.0.0.1:9000
    listen.owner = nginx
    listen.group = nginx
    listen.mode = 0660
  66. 將所有配置文件複製到所有的web server中並啓動服務
    [root@web2 ~]#nginx -s reload
    [root@web2 ~]#service php-fpm restart
  67. 解壓縮文件 wordpress-5.0.4-zh_CN.tar.gz
    [root@web1 data]#tar xf wordpress-5.0.4-zh_CN.tar.gz -C www
  68. 在主服務器上創建wordpress數據庫及用戶名和密碼
    MariaDB [(none)]> CREATE DATABASE wordpress;
    MariaDB [(none)]> GRANT ALL PRIVILEGES ON wordpress.* TO "wordpress"@"192.168.205.%" IDENTIFIED BY "centos";
    MariaDB [(none)]> FLUSH PRIVILEGES;
  69. 同樣我也需要將這個帳號在所有的proxysql服務器授權
    [root@proxysql1 ~]#mysql -uadmin -padmin -P6032 -h127.0.0.1
    [root@proxysql2 ~]#mysql -uadmin -padmin -P6032 -h127.0.0.1
    所有proxysql中執行如下:
    MySQL [(none)]> insert into mysql_users(username,password,default_hostgroup) values('wordpress','centos',10);
    MySQL [(none)]> load mysql users to runtime;
    MySQL [(none)]> save mysql users to disk; 
  70. 修改wordpress配置文件
    [root@web1 www]#cp wp-config-sample.php wp-config.php
    [root@web1 www]#vi wp-config.php 
    define('DB_NAME', 'wordpress');
    define('DB_USER', 'wordpress');
    define('DB_PASSWORD', 'centos');
    define('DB_HOST', '192.168.205.45:6033');      #注意這裏要添加proxysql vip的地址,端口爲6033             
  71. 生成密鑰,可以使用網站https://api.wordpress.org/secret-key/1.1/salt/ 自動生成,然後直接替換即可
    [root@web1 www]#vi wp-config.php                                                                 
    define('AUTH_KEY',         ']xRUezwud7/sl9n{5Qv-=VM|uoqaFauAuc3|6wy<w7Dg0qUC7{.4%#>o+HfjC!I+');
    define('SECURE_AUTH_KEY',  '=e[P3g1~S|:+J@I)f-(:MTf3~h+;hQCg?wuk50NMP)Dgoj3X kL@BDDk%&;zed^`');
    define('LOGGED_IN_KEY',    'f,B`O^3qW20-,`k>dHdW8Bt^/]HZ5 -sA1rz$x:|x3R3~!j*}^mw?0|N)YTO<usi');
    define('NONCE_KEY',        'x/7V-u*8K^d-|3a&L}/V&2b9K}G+r-q&A7NCWin}h3dP1P( /X;fRzqG1U[,;F_C');
    define('AUTH_SALT',        'U,kjv 5&srgsePiCJOxUxc+>HkX#B3:fWbQ;[n^5FD)-4r9C!/+Swwv:k~~HZ|-l');
    define('SECURE_AUTH_SALT', ';=3HS/eY&DRN0p1_->e#]%h#x=*Q?Zj]A*tC=@*H$9_T%+SF+!w0?b}f/`#K&[h&');
    define('LOGGED_IN_SALT',   'iVWA_K4+X&guJiXc90L4UnQ-#E7+q--rH1_`nhdbSzlC2X.}}R11aua{>8 <hQv:');
    define('NONCE_SALT',       'z4,S7_]&70?7^p[o>$n7tJAq]?12ngpfi(]Cl{zfKs>!.Y?9|4@59{R*Q<k(Hg_.');
  72. 此時我們可以直接訪問web1或web2來測試
    架構測試:HAproxy實現負載均衡,前端爲nginx+php,數據庫實現讀寫分離和高可用
    架構測試:HAproxy實現負載均衡,前端爲nginx+php,數據庫實現讀寫分離和高可用

    安裝haproxy

  73. 在所有的proxy server上安裝HAproxy和keepalived
    [root@haproxy1 ~]#yum install haproxy keepalived
    [root@haproxy2 ~]#yum install haproxy keepalived
  74. 修改proxysql1的keepalive配置
    [root@haproxy1 ~]#vi /etc/keepalived/keepalived.conf 
    global_defs {
    notification_email {
     [email protected]
     [email protected]
     [email protected]
    }
    notification_email_from [email protected]
    smtp_server 192.168.200.1
    smtp_connect_timeout 30
    router_id LVS_1
    vrrp_skip_check_adv_addr
    vrrp_strict
    vrrp_iptables
    vrrp_garp_interval 0
    vrrp_gna_interval 0
    }
    # Script used to check if HAProxy is running
    vrrp_script check_haproxy {
    script "killall -0 haproxy"
    interval 2
    weight -30
    fall 2
    rise 1
    }
    vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 111
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.205.111/24 dev eth0 label eth0:0
    }
    track_script {
        check_haproxy
    }
    }
  75. 修改proxysql2的keepalived配置
    [root@haproxy2 ~]#vi /etc/keepalived/keepalived.conf 
    global_defs {
    notification_email {
     [email protected]
     [email protected]
     [email protected]
    }
    notification_email_from [email protected]
    smtp_server 192.168.200.1
    smtp_connect_timeout 30
    router_id LVS_2
    vrrp_skip_check_adv_addr
    vrrp_strict
    vrrp_iptables
    vrrp_garp_interval 0
    vrrp_gna_interval 0
    }
    # Script used to check if HAProxy is running
    vrrp_script check_haproxy {
    script "killall -0 haproxy"
    interval 2
    weight -30
    fall 2
    rise 1
    }
    vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 111
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.205.111/24 dev eth0 label eth0:0
    }
    track_script {
        check_haproxy
    }
    }
  76. 啓動服務
    [root@haproxy1 ~]#systemctl enable keepalived
    [root@haproxy1 ~]#systemctl start keepalived 
    [root@haproxy2 ~]#systemctl enable keepalived
    [root@haproxy2 ~]#systemctl start keepalived  
  77. 修改haproxy配置文件在所有的haproxy server上
    [root@haproxy1 ~]#vi /etc/haproxy/haproxy.cfg 
    defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    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                 3000
    listen web-80
    bind 192.168.205.111:80
    server web1 192.168.205.127:80 check inter 3s fall 3 rise 5
    server web1 192.168.205.137:80 check inter 3s fall 3 rise 5  
  78. 啓動服務
    [root@haproxy1 ~]#systemctl enable haproxy
    [root@haproxy1 ~]#systemctl start haproxy 
    [root@haproxy1 ~]#ss -ntl
    State       Recv-Q Send-Q    Local Address:Port                   Peer Address:Port              
    LISTEN      0      128     192.168.205.111:80                                *:*
  79. 將haprox配置文件複製到haproxy2上並啓動服務
    [root@haproxy1 ~]#scp /etc/haproxy/haproxy.cfg 192.168.205.117:/etc/haproxy/
    [root@haproxy2 ~]#systemctl enable haproxy 
    [root@haproxy2 ~]#systemctl start haproxy 
  80. 我們發現沒有監聽192.168.205.111:80端口,因爲默認不會監聽不存在IP的端口
    [root@haproxy2 ~]#ss -ntl
    State       Recv-Q Send-Q    Local Address:Port                   Peer Address:Port              
    LISTEN      0      128                   *:22                                *:*                  
    LISTEN      0      100           127.0.0.1:25                                *:*                  
    LISTEN      0      128                  :::22                               :::*                  
    LISTEN      0      100                 ::1:25                               :::*                
  81. 修改內核參數可以實現監聽,重啓haproxy, 可以看到haproxy2也實現了監聽, 同樣我也需要在haproxy1上加上這個選項否則主失效的情況下,再切回來情況下,haproxy會出錯,無法啓動
    [root@haproxy2 ~]#sysctl -a | grep bind
    net.ipv4.ip_nonlocal_bind = 0
    [root@haproxy2 ~]#vi /etc/sysctl.conf 
    net.ipv4.ip_nonlocal_bind = 1
    [root@haproxy2 ~]#sysctl -p
    net.ipv4.ip_nonlocal_bind = 1
    [root@haproxy2 ~]#systemctl restart haproxy
    [root@haproxy2 ~]#ss -ntl
    State       Recv-Q Send-Q    Local Address:Port                   Peer Address:Port              
    LISTEN      0      128     192.168.205.111:80                                *:*         
  82. 通過192.168.205.111訪問web服務器,發現沒有問題
    架構測試:HAproxy實現負載均衡,前端爲nginx+php,數據庫實現讀寫分離和高可用
  83. 如果停掉haproxy1的keepalive, 再測試
    架構測試:HAproxy實現負載均衡,前端爲nginx+php,數據庫實現讀寫分離和高可用
    [root@haproxy1 ~]#systemctl stop keepalived
  84. 恢復keepalived,嘗試停掉haproxy,再測試,發現vip已經切到haproxy2上
    [root@haproxy1 ~]#systemctl stop haproxy
    [root@haproxy2 ~]#ip a
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:05:be:a7 brd ff:ff:ff:ff:ff:ff
    inet 192.168.205.117/24 brd 192.168.205.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet 192.168.205.111/24 scope global secondary eth0:0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe05:bea7/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
             ![](https://s1.51cto.com/images/blog/201908/18/9abcbc4b6e8b6cce0a6e4b36b117b4ee.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

    實現firewall

  85. 爲了簡化我們使用一臺linux的iptables做爲DNAT,確保關閉firewald
    [root@centos7 ~]#iptables -t nat -A PREROUTING -s 0/0 -d 202.106.0.17 -p tcp --dport 80 -j DNAT --to-destination 192.168.205.111:80 
  86. 開啓ip轉發功能
    [root@centos7 network-scripts]#cat /proc/sys/net/ipv4/ip_forward
    0
    [root@centos7 network-scripts]#sysctl -w net.ipv4.ip_forward=1
    net.ipv4.ip_forward = 1
    [root@centos7 ~]#vi /etc/sysctl.conf 
    net.ipv4.ip_forward = 1
  87. 安裝iptables service實現自動保存
    [root@centos7 ~]#yum install iptables-services
    [root@centos7 ~]#iptables-save >/etc/sysconfig/iptables
    [root@centos7 ~]#systemctl enable iptables.service 
  88. 注意,Haproxy的默認網關要指向firewall, 兩個webserver也默認網關也要指定firewall, 原因在於webserver回包時直接回到網關,實際是不是這樣,有待考證,但我加了網站才能夠正常訪問
    [root@haproxy1 ~]#ip r
    default via 192.168.205.17 dev eth0 proto static metric 102 
    [root@haproxy2 ~]#ip r
    default via 192.168.205.17 dev eth0 proto static metric 102 
    [root@web1 ~]#ip r a default via 192.168.205.17 dev eth0
    [root@web1 ~]#ip r
    default via 192.168.205.17 dev eth0 
    [root@web2 ~]#ip r a default via 192.168.205.17 dev eth0
    [root@web2 ~]#ip r
    default via 192.168.205.17 dev eth0

    實現powerdns

  89. 安裝包:基於EPEL源
    yum install -y pdns pdns-backend-mysql mariadb-server
  90. 創建數據庫
    CREATE DATABASE powerdns;
    GRANT ALL ON powerdns.* TO 'powerdns'@'127.0.0.1' IDENTIFIED BY 'centos'; 
    USE powerdns;
  91. 創建powerdns數據庫中的表 (參考https://doc.powerdns.com/md/authoritative/backend-generic-mysql/)
    CREATE TABLE domains (
    id                    INT AUTO_INCREMENT,
    name                  VARCHAR(255) NOT NULL,
    master                VARCHAR(128) DEFAULT NULL,
    last_check            INT DEFAULT NULL,
    type                  VARCHAR(6) NOT NULL,
    notified_serial       INT DEFAULT NULL,
    account               VARCHAR(40) DEFAULT NULL,
    PRIMARY KEY (id)
    ) Engine=InnoDB;
    CREATE UNIQUE INDEX name_index ON domains(name);
    CREATE TABLE records (
    id                    BIGINT AUTO_INCREMENT,
    domain_id             INT DEFAULT NULL,
    name                  VARCHAR(255) DEFAULT NULL,
    type                  VARCHAR(10) DEFAULT NULL,
    content               VARCHAR(64000) DEFAULT NULL,
    ttl                   INT DEFAULT NULL,
    prio                  INT DEFAULT NULL,
    change_date           INT DEFAULT NULL,
    disabled              TINYINT(1) DEFAULT 0,
    ordername             VARCHAR(255) BINARY DEFAULT NULL,
    auth                  TINYINT(1) DEFAULT 1,
    PRIMARY KEY (id)
    ) Engine=InnoDB;
    CREATE INDEX nametype_index ON records(name,type);
    CREATE INDEX domain_id ON records(domain_id);
    CREATE INDEX recordorder ON records (domain_id, ordername);
    CREATE TABLE supermasters (
    ip                    VARCHAR(64) NOT NULL,
    nameserver            VARCHAR(255) NOT NULL,
    account               VARCHAR(40) NOT NULL,
    PRIMARY KEY (ip, nameserver)
    ) Engine=InnoDB;
    CREATE TABLE comments (
    id                    INT AUTO_INCREMENT,
    domain_id             INT NOT NULL,
    name                  VARCHAR(255) NOT NULL,
    type                  VARCHAR(10) NOT NULL,
    modified_at           INT NOT NULL,
    account               VARCHAR(40) NOT NULL,
    comment               VARCHAR(64000) NOT NULL,
    PRIMARY KEY (id)
    ) Engine=InnoDB;
    CREATE INDEX comments_domain_id_idx ON comments (domain_id);
    CREATE INDEX comments_name_type_idx ON comments (name, type);
    CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);
    CREATE TABLE domainmetadata (
    id                    INT AUTO_INCREMENT,
    domain_id             INT NOT NULL,
    kind                  VARCHAR(32),
    content               TEXT,
    PRIMARY KEY (id)
    ) Engine=InnoDB;
    CREATE INDEX domainmetadata_idx ON domainmetadata (domain_id, kind);
    CREATE TABLE cryptokeys (
    id                    INT AUTO_INCREMENT,
    domain_id             INT NOT NULL,
    flags                 INT NOT NULL,
    active                BOOL,
    content               TEXT,
    PRIMARY KEY(id)
    ) Engine=InnoDB;
    CREATE INDEX domainidindex ON cryptokeys(domain_id);
    CREATE TABLE tsigkeys (
    id                    INT AUTO_INCREMENT,
    name                  VARCHAR(255),
    algorithm             VARCHAR(50),
    secret                VARCHAR(255),
    PRIMARY KEY (id)
    ) Engine=InnoDB;
    CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);
  92. 配置PowerDNS使用mariadb作爲後臺數據存儲
    vim /etc/pdns/pdns.conf,查找到包含launch= 的行,修改並添加下面的內容
    launch=gmysql
    gmysql-host=localhost
    gmysql-port=3306
    gmysql-dbname=powerdns
    gmysql-user=powerdns
    gmysql-password=centos
  93. 啓動服務
    systemctl start pdns
    systemctl enable pdns
  94. 安裝httpd和php相關包
    yum -y install httpd php php-devel php-gd php-mcrypt php-imap php-ldap php-mysql php-odbc php-pear php-xml php-xmlrpc php-mbstring php-mcrypt php-mhash gettext wget
    systemctl start httpd
    systemctl enable httpd
  95. 下載poweradmin程序,並解壓縮到相應目錄
    cd /var/www/html
    wget http://downloads.sourceforge.net/project/poweradmin/poweradmin-2.1.7.tgz
    tar xvf poweradmin-2.1.7.tgz
    mv poweradmin-2.1.7 /var/www/html/poweradmin
  96. 訪問下面地址,啓動PowerAdmin的網頁安裝嚮導,選擇英文然後 go to step2:
    http://192.168.205.147/poweradmin/install/
  97. 提供先前配置的數據庫詳情,同時爲Poweradmin設置管理員密碼
    Username: 爲上面91步創建的用戶名,此處應該爲powerdns
    password:爲上面91步創建的密碼應該爲centos
    database type :爲myql
    hostname: 爲mysql主服務器的IP
    DB port: 爲默認的3306
    database: 爲上面9步創建的數據庫名稱powerdns
    poweradmin adminstrator pasword: 此處爲powerdns會自動創建一個web管理員名爲admin的用戶,此爲admin的密碼
    ![](https://s1.51cto.com/images/blog/201908/18/7303b2a90bee69f83f76dc57ac8fb40c.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
  98. 爲Poweradmin創建一個受限用戶,powerDNS會使用這個帳戶來更新powerdns數據庫,上面的只是用來連接數據庫,此處爲真正更新時使用的帳戶
    Username:更新的用戶名
    Password:上述用戶的密碼
    Hostmaster:當創建SOA記錄指定默認主機管理員
    Primary nameserver:主域名服務器,此處應該爲192.168.205.17
    Secondary namesever: 輔域名服務器,  沒有輔助服務器,可以不添
    ![](https://s1.51cto.com/images/blog/201908/18/05bb63fd89a7dc0815c02b09b7c87778.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
  99. 跟據上面的輸入,他會自動產生sql語句,按照下面頁面說明,在數據庫中192.168.205.147創建用戶並授權
    MariaDB [powerdns]> GRANT SELECT, INSERT, UPDATE, DELETE ON powerdns.* TO 'poweradmin'@'127.0.0.1' IDENTIFIED BY 'centos1';
    ![](https://s1.51cto.com/images/blog/201908/18/4762d849166002482c4a4ee39ceac66c.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
  100. 按下面頁面說明,創建config.in.php文件內容
    架構測試:HAproxy實現負載均衡,前端爲nginx+php,數據庫實現讀寫分離和高可用
    vim /var/www/html/poweradmin/inc/config.inc.php
  101. 刪除install目錄
    rm -rf /var/www/html/poweradmin/install/
    ![](https://s1.51cto.com/images/blog/201908/18/03be72e059fce1f020afe135101d67c1.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
  102. 登錄http://202.106.0.17/poweradmin/
    username:admin
    password:admin 參看第96步
  103. 添加主機記錄在powerdns上
    架構測試:HAproxy實現負載均衡,前端爲nginx+php,數據庫實現讀寫分離和高可用
  104. 在客戶端的windows中測試dns解析
    架構測試:HAproxy實現負載均衡,前端爲nginx+php,數據庫實現讀寫分離和高可用
    架構測試:HAproxy實現負載均衡,前端爲nginx+php,數據庫實現讀寫分離和高可用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章