[ 設定心得 ] 打造永遠不掛的 Phorum


作者﹕網中人 <netman@study-area.org>
常上"酷學園"的忠實學員們,相信一定還記得 4 月份的掛站事件吧? 那次的慘痛經歷讓我們丟失了四千多篇的討論文章,而其中不少是相當有參考價值的。 為甚麼沒備份及為何救不回來?背後的故事很長,有空再八掛... 但無論如何,我們絕對需要檢討的是"異地備援"的機制沒有及時建立起來, 痛定思痛,我們花了一個多月的時間從構思到設定、實作、測試 .... 數換主機之後,終於完成了一個初步的架構。 為此特地將我們的心得提供給大家參考,並希望能得到更多的朋友幫忙改良。 ------------------------------ 一﹐假設環境 ------------------------------ 1) 一台主 phorum 主機(master):1.2.3.4 2) 一台能提供 ddns update 的 DNS 主機:1.2.3.5 3) 一台次 phorum 主機(slave): 4.3.2.1 4) phorum 使用的 FQDN 為:phorum.my.org ------------------------------ 二﹐構思 ------------------------------ 1) 正常情況下,phorum 跑在 master。 然後啟動 mysql 的雙向 replication , 但兩個 phpbb 都使用 master 的 mysql (在 config.php 設), phpbb 本身的 code 用 rsync+ssh 來同步。 2) 在 slave 這邊,用 nmap 每 60 秒來掃 port 80 及 3306, 若兩個 port 都掃到,不作任何變動。 3) 若其一掃不到,將作出如下動作: 1, 發 email 通知 mail list 2, 修改 phpbb 使用本機的 mysql 3, 用 ddns 將 phorum 的 IP 改到 slave 4, 每 20 秒再用 nmap 來掃 master 的 port 4) 若 master 回來後,將作出如下動作: 1, 發 email 通知 mail list 2, 修改 phpbb 使用 master 的 mysql 3, 用 ddns 將 phorum 改到 master 4, 每 60 秒再用 nmap 來掃 master port 80 (循環動作 2 ) ------------------------------ 三﹐前提條件 ------------------------------ 1) 您會設定及使用 ssh/scp ,還有 ssh 的 RSA 認證 2) 您會設定 bind v9 的 policy update (ddns) 3) 您會設定 mysql 的 replication 4) 您會修改 shell script (bash) ------------------------------ 四﹐開始實作 ------------------------------ 4.1﹐設定 SSH 1) 在 slave 挑選一個帳號(如 kenny),確定對整個 phpBB 目錄有"寫入"權限, 且能夠從 master 端 ssh 進來(預設如此,除非您修改了)。並執行: $ mkdir ~/.ssh 2>/dev/null $ chmod 700 ~/.ssh $ touch ~/.ssh/authorized_keys $ chmod 644 ~/.ssh/authorized_keys 2) 在 master 上選一個能讀取 phpBB 目錄且能跑 crontab 的帳號(如 netman), (注:若不用 root 的話,建議為 phpBB 目錄的 owner。) 並用該身份執行: $ ssh-keygen -t rsa (按三下 enter 完成﹔不需設密碼,除非您會用 ssh-agent 。) 3) 將 master 的 RSA key 搬進 slave 那邊去: $ scp /home/netman/.ssh/id_rsa.pub kenny@4.3.2.1:/home/kenny/id_rsa.pub.1.2.34 (輸入密碼﹔若是第一次連線,在輸入密碼之前還需輸入 yes 三字。) $ ssh kenny@4.3.2.1 'cat /home/kenny/id_rsa.pub.1.2.3.4 >> /home/kenny/.ssh/authorized_keys' (再輸入密碼) $ ssh kenny@4.3.2.1 'rm /home/kenny/id_rsa.pub.1.2.3.4' (這次確定"不需"輸入密碼﹗若不成功,請參考 ssh 的文件完成。) ** 註:上述步驟也可參考如下網頁的部份內容: http://www.study-area.org/tips/vpn.htm 4.2﹐同步 phpBB * 此步驟不是必需的,若因其他目的不想想同步雙方的 phpbb 設定,那可略過。 1) 請再次確定您在 slave 使用的帳號(這裡為 kenny)對 phpBB 目錄有寫入權限, (具體路逕請自行修改): $ touch /home/phpbb/www/phpBB/new.text $ rm /home/phpbb/www/phpBB/new.text $ mv /home/phpbb/www/phpBB /home/phpbb/www/phpBB.bak 2) 用前述帳號(這裡為 netman)登入 master 主機上,執行 rsync 同步 phpBB: $ rsync -e ssh -zav /home/phpbb/www/phpBB kenny@4.3.2.1:/home/phpbb/www (注1:來源路逕請打 "/home/phpbb/www/phpBB",也就是最後的路逕不能帶 "/" ﹗) (注2:目標路逕請打 "/home/phpbb/www",也就是指到 phpBB 的上一級目錄﹗) 3) 請到 slave 端驗證同步是否成功﹔否則,請參考 rsync 文件來完成。 4) 在 master 上用前述帳號寫一個 crontab ,定期更新: $ crontab -e 1 */4 * * * /usr/bin/rsync -e ssh -zav /home/phpbb/www/phpBB kenny@4.3.2.1:/home/phpbb/www 這樣,一天會同步 6 次﹔若需調整時間間隔,請參考 crontab 文件。 4.3﹐設定 DDNS 1) 以 root 身份登入 DNS 主機,並產生 key pair: # mkdir ~/tmp # cd ~/tmp # dnssec-keygen -a HMAC-MD5 -b 128 -n HOST phorum Kphorum.+157+01326 2) 獲取 key 內容: # tail -1 Kphorum.+157+01326.key | awk '{print $7}' rTlaRxINDDD/#zUlnPadsfWA== 並請抄下來(小心別抄錯﹗大小寫是不同的哦~~~) (您也可自行打開 Kphorum.+157+01326.key 來複制) 3) 修改 /etc/named.conf ,並增加/修改如下句子: key "phorum" { algorithm hmac-md5; secret "rTlaRxINDDD/#zUlnPadsfWA=="; }; zone "my.org" { type master; file "named.my.org"; update-policy { grant phorum name phorum.my.org. A; }; }; 並重新啟動 named : # /etc/rc.d/init.d/named restart (一定要看 /var/log/messages 確定沒有 error 出現﹗) 4) 將產生的 key-pair 抄至 slave : # scp Kphorum.+157+01326.* kenny@4.3.2.1:/home/kenny (輸入密碼﹔若是第一次連線,在輸入密碼之前還需輸入 yes 三字。) 5) 轉至 slave 主機,並以前面所用的帳號(這裡為 kenny)登入,測試 ddns : $ cd $ host phorum.my.org (以確定您看到的 ip 是 master 的) $ nsupdate -k Kphorum.+157+01326.key > server 1.2.3.5 > update delete phorum.my.org A > update add phorum.my.org 0 A 4.3.2.1 > send > ^d (按下 crtl 及 d 鍵) $ host phorum.my.org (確定您看到的 ip 是 slave 的﹔若不成功,請參考 ddns 文件來完成。) 成功後請再跑 nsupdate ,將 IP 改回 master 。 ** 註:上述步驟也可參考如下網頁的部份內容: http://www.study-area.org/tips/ddns.htm 4.4﹐設定 MSQL 之 Replication 1) 在 master 上 執行 mysql ,增加 replication 帳號: # mysql -u root -p (輸入您的 mysql 密碼) mysql>GRANT FILE ON *.* TO rep_user2@4.3.2.1 IDENTIFIED BY ‘rep_password2’; mysql>\q 2) 在 master 上修改 /etc/my.cnf ,使之內容類似如下: [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock ##comment out the following line to be slave server-id=1 master-host=4.3.2.1 master-user=rep_user1 master-password=rep_password1 master-port=3306 log-slave-updates master-connect-retry=60 replicate-do-db=phpBB ##comment out the following line to be master log-bin sql-bin-update-same binlog-do-db=phpBB [mysql.server] user=mysql basedir=/var/lib [safe_mysqld] err-log=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid 3) 在 slave 上 執行 mysql ,增加 replication 帳號: # mysql -u root -p (輸入您的 mysql 密碼) mysql>GRANT FILE ON *.* TO rep_user1@1.2.3.4 IDENTIFIED BY ‘rep_password1’; mysql>\q 4) 在 slave 上修改 /etc/my.cnf ,使之內容類似如下: [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock ##comment out the following line to be slave server-id=2 master-host=1.2.3.4 master-user=rep_user2 master-password=rep_password2 master-port=3306 log-slave-updates master-connect-retry=60 replicate-do-db=phpBB ##comment out the following line to be master log-bin sql-bin-update-same binlog-do-db=phpBB [mysql.server] user=mysql basedir=/var/lib [safe_mysqld] err-log=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid 5) 請分別關閉 master 及 slave 的 mysqld : # /etc/rc.d/init.d/mysqld stop 6) 登入 master 將 mysqld 打包,並傳至 slave 那邊去 : # cd /var/lib # tar zcvf mysql.tgz mysql # scp mysql.tgz kenny@4.3.2.1:/home/kenny 7) 登入 slave ,並將 mysql 存放好: # cd /var/lib # mv mysql mysql.bak # tar zxvf /home/kenny/mysql.tgz * 注: 建議只覆蓋 /var/lib/mysql/ 目錄底下的相關子目錄, 或將 mysql.bak/mysql 再蓋回。 否則 slave mysql 的設定還需從來,如: mysql>GRANT FILE ON *.* TO rep_user1@1.2.3.4 IDENTIFIED BY ‘rep_password1’; 8) 最後,將 master 及 slave 的 mysqld 打開: # /etc/rc.d/init.d/mysqld start 9) 請以 mysql 或 phorum 來測試 replication 是否成功。 若失敗,不防將 mysql 目錄下的如下檔案砍掉: master.info *-bin.[0-9][0-9][0-9] *-bin.index 再重跑 mysqld 。 另外,/var/log/mysqld.log 的資訊也很有用,請勿略過。 至於 phpBB 的設定,請修改 /home/phpbb/www/phpBB/config.php 即可。 ** 註:上述步驟也可參考如下網頁的部份內容: http://www.study-area.org/tips/mysql_replication.htm 4.5﹐撰寫/下載 shell scripts 當前面各項測試"全部"都成功之後,接下來就是寫 shell script 的時侯了。 聰明的您應該不難寫出符合自己需求的 script , 但若您不想那麼麻煩的話,那也可以下載我寫好的 script 會去修改: 1) 請以 root 身份下載: # cd # wget http://www.study-area.org/linux/src/swap_phorum.tgz 2) 解壓縮: # tar zxvf swap_phorum.tgz 3) 您所下載的 tarball ,主要是要跑兩個 script : ddns.sh swap_phorum.sh 它們均共同使用 config 檔來設定,您只需集中修改一個地方就夠了。 # cd swap_phorum # vi config 在 config 裡面,您可參考註解說明來修改設定參數,說明如下: KEY_FILE=$w_dir/Kphpbb.+157+01326.key # ddns key 用來更新 ddns 的 key ,也就是前述步驟 4.3 所用的 key 。 UPDATE_SCR=$w_dir/nsupdate.scr # ddns template 更新 ddns 用的范本,供 ddnsh.sh 使用,不能刪除。 UPDATE_DATA=$w_dir/nsupdate.data # ddns data 更新 ddns 用的資料,由 ddns.sh 產生,可刪除。 DDNS_SCRIPT=$w_dir/ddns.sh # ddns script 更新 ddns 的 script 。 STATE_FILE=/var/run/swap_phorum # state file 供 swap_phorum.sh 參考的狀態檔,由 script 自動產生/移除。 PHPBB_DIR=/home/phpbb/www/phpBB # phpbb directory 存放 phpBB 的目錄。 PHPBB_CONF=$PHPBB_DIR/config.php # phpbb config file phpBB 的設定檔,決定用哪一個 mysql 就靠它了。 此檔會被 swap_phorum.sh 修改,除非作測試,請勿修改。 在第一次執行 swap_phorum.sh 之前,請確定它是可用的。 CONF_BAK=$PHPBB_CONF.bak.swap_phorum # phpbb config 此檔只有在第一次執行 swap_phorum.sh 時(或該檔不存在時)產生, swap_phorum.sh 會參考此檔來修改 config.conf , 因此若需修改 phpBB 的設定,請修改這此檔,並同步至 config.php 。 MAIL_LIST=phpbb@my.org # notice recipient 郵件通知信箱。請確定可收到郵件,以便及時了解 phorum 狀態。 HOST_NAME=phorum.my.org # ddns host 也就是別人連上 phorum 的 FQDN ,ddns 會修改這個 A record 。 NS_SERVER=1.2.3.4 # dns server ip DNS server 的 IP,請勿使用 FQDN 。 MASTER_HOST=1.2.3.5 # phorum master ip Master Phorum 主機的 IP ,請勿使用 FQDN。 SLAVE_HOST=4.3.2.1 # phorum slave ip Slave Phorum 主機的 IP ,請勿使用 FQDN。 NMAP=/usr/bin/nmap # nmap path nmap 程式的絕對路逕。 WGET=/usr/bin/wget # wget path wget 程式的絕對路逕。 INTERVAL=60 # seconds to waite 每次偵測 master 是否存活的時間間隔。 IF="eth0" # interface 在 swap_phorum.sh 的 code 中, 可以指定 ddns 更新 $HOST_NAME 為 master 或 slave 的 IP, 否則(若修改 code 的話),則以此界面的 IP 為準。 4) 當您完成 config 的修改之後,您可執行如下 script 來測試: ./swap_phorum.sh 若您看到 CHECK 1 的提示,則代表一切正常﹔ 若看到 CHECK 2 ,則有可能 master 那邊掛了,也有可能是網路的問題。 建議您在觀測 slave 的同時,不妨將 master 的 httpd 及 mysqld 分階段關閉玩玩看, 並檢查 config 所指定的信箱是否能正確收到訊息。 在測試時請多給點耐心,因為正常情況下 script 在每次檢測之間都會等上 1 分鐘, 要是您想加快測試速度的話,可修改 config 的 INTERVAL= 變數, 及修改 swap_phorum.sh 的 sleep 部份。 在測試過程中,您可隨時按 crtl-c 來終止 script 。 5) 一旦測試完成,您或許可以修改 rc.local 讓 script 在開機的時侯跑, 但也可打 inittab 的主意, 修改 /etc/inittab ,在最後面增加: sp:345:respawn:/root/swap_phorum/swap_phorum.sh (注意1:確定除這行外,再無其它以 sp: 開頭的句子。) (注意2:確定最後一欄的路逕與您解開的 script 路逕一致。) 然後執行: # init q 這樣,您可透過如下方式來得知 script 是否有跑起來: # ps ax | grep 'swap_phorum' 不過,若您需要修改及測試 script 的話,請先註解 inittab : ##sp:345:respawn:/root/swap_phorum/swahPphorum.sh 並重新跑 init q ,等您確定測試穩定後,再打開不遲。 ------------------------------ 五﹐一些注意 ------------------------------ * 當前的 script 是用 nmap 來掃 port ,並沒用其它 heart-beat 程式來偵測, 因此或許不準。 曾經試過用 wget 來抓 web content 來測,不過碰到 transparent proxy 會不準。 由於這是確定 master 是否存活的關鍵﹗希望有朋友願意進行改良。 * 目前的 mysql replication 只能做到"一對一"的,目前還不能做到"一對多"的同步, 但以 chain (串連方式)則可得到多份 backup 。 若有朋友解決了這個問題,希望能回報大家。 * 上述 scripts 曾經 port 到過 freebsd 上測試,但許多命令的路逕與參數均不一致, 比方 ddns 的 update 程式就很不一樣,尚需小心測試。 若有朋友願意維護 freebsd 的版本,歡迎與大家分享。 * DNS, Master Phorum, Slave Phorum 這三台主機,建議儘可能的分處異地, 要是超過兩台"同時"連不上,那整個架構就沒作用了。敬請注意。 * 實作的驗證很重要,尤其是 mysql 的同步,應多加定期檢測為宜。 若碰到問題,請首先從 log 開始著手。 若以 inittab 來 run ,在修改測試時,請先確定 init 沒有 respawn 該 script 。 ------------------------------ 六﹐後記 ------------------------------ 目前的酷學園討論區已經使用當前的設計,也通過了小規模的測試驗證。 然而,還沒機會"實質性"的考驗過此一機制(希望永遠用不著吧﹗), 故一些隱性的問題仍需交由廣大的環境測試, 為此希望各路賢能鼎力相助,發展出更好、更穩定的版本給大家使用。 ------------------------------ 七﹐展望 ------------------------------ 下一個目標將是發展 phpBB to news 的機制, 讓更多的 phorum 能夠"互通文章",以期更有效的發揮網路的功用。 若您有心參與此一計劃,或能提供建議給我們,那就請勿客氣了哦~~~ ^_^ 謝謝大家﹗ ------------------------------ 八﹐一些有用的網路資源﹕ ------------------------------ http://www.study-area.org/tips/vpn.htm http://www.study-area.org/tips/ddns.htm http://www.study-area.org/tips/mysql_replication.htm ------------------------------ 九﹐更新日期 / 文件版本﹕ ------------------------------ * May 16, 2003 / Version 0.9 beta * December 12, 2003 / Version 0.92 * December 20, 2003 / Version 0.93