Linux伺服器具有低成本、效能卓越、代碼開放等特性。越來越多的企業正在準備或已經採用Linux擔起了公司專屬應用程式伺服器的重任。本文要介紹的是筆者在實際工作中,採用Linux和其它開放套件共同部署高可靠性LDAP認證服務的執行個體。
系統所要用到的軟體包括:
◆ Red Hat 7.2;
◆ OpenLDAP 2.1,www.openldap.org;
◆ Heartbeat 1.04,www.linux-ha.org。
合理的流程提供高可靠性
OpenLDAP在該系統的網路應用體系中用於對所有應用提供統一的身份認證服務,還包括如郵件路由、地址、連絡人資訊等其它資訊的查詢。LDAP作為一種特殊的資料庫,通過對讀取、查詢操作進行特別的最佳化和處理,以保證在查詢速度方面的優勢,所以特別適合用來統一企業的各種認證服務,從而規範各種業務系統的同一登入身份和口令。當然,它的缺點和優點一樣明顯,比如不善於update、insert等操作,但是如果把它作為中央認證資料庫,則正好可以利用它的長處而迴避它的弱點。
由於系統採用了LDAP作為所有應用的中央認證資料庫,一旦該LDAP伺服器失效,則系統網路環境中所有依賴於該資料庫的應用都會受到影響,甚至停止提供相應的服務。為了避免這種情況的發生,就要通過兩台LDAP伺服器建立一個高可靠性的認證資料庫叢集,同時對其它應用系統提供統一的資料庫訪問網路介面。系統網路結構圖1。
圖1 系統網路結構圖
從圖1可以看到,整個系統分為三層:應用伺服器、資料庫中間引擎和OpenLDAP資料庫叢集。所有的應用伺服器通過資料庫中間引擎(midd)來訪問192.168.1.200,並通過這一統一的資料庫網路介面來訪問LDAP資料庫。對於系統的要求是,正常情況下master伺服器(192.168.1.100)綁定在192.168.1.200上提供服務,slave伺服器處於備機狀態,一旦master發生故障,slave能夠自動接管任務,同時通過某種通訊方式通知系統管理員(如郵件、手機簡訊)。
這裡,midd資料庫中間引擎是根據需要編寫的一個簡單工具,使用它要達到以下幾個目的:
◆ 統一應用伺服器上的應用程式訪問各種資料庫的介面。例如,以後有可能將背景LDAP資料庫換為其它資料庫,如Oracle等,這時只需要更改midd的設定檔,而不需要對應用程式進行任何更改。
◆ 通過採用進程池的方式來提供應用程式的查詢速度。midd能通過對前端應用程式的訪問負載,自動調節進程池的進程數量。同時進程池中的每個進程和背景LDAP資料庫保持一個長串連,這樣可以避免一般條件下每次查詢都要開一個串連的資源浪費和延時。
◆ 每個應用伺服器上都部署一個midd。這樣應用程式每次請求的時候都是通過本地IPC與midd進行通訊,避免了TCP方式串連的開銷。
◆ midd在兩台LDAP資料庫active-active模式下的應用模式。midd根據啟動時的參數能夠自動區別讀、寫請求,會將寫請求分配到Master LDAP資料庫上,這是由於Slave LDAP資料庫只能進行讀操作。在整個網路負載大、兩台LDAP資料庫同時提供服務的情況下,使用midd的這一模式,可以避免Slave LDAP資料庫不能更改資料導致兩台伺服器不能保質萃降奈侍狻?
根據以上流程的要求,系統必須解決兩個問題,首先是由於作為LDAP資料庫的兩台伺服器並沒有實現儲存共用,因此要求master和slave兩台資料庫伺服器的資料必須即時同步,才能保證一旦slave接管任務後能夠提供完整的服務。其次,master和slave必須能夠即時檢測對方的健康狀態,一旦發現對方有故障,自己能夠接管各種任務,包括切換虛擬IP地址、LDAP服務(變為主LDAP服務,意味著其能對寫進行操作,從而要求master伺服器恢複後必須先和slave進行一次資料同步),以及通過rsh方式來執行其它遠程應用伺服器上的midd啟動模式(在active-active模式下)。
下面就將解決以上資料同步和任務接管兩個問題。
主、從LDAP伺服器的資料同步
OpenLDAP本身提供了一種複製機制來保證網路上主、從節點之間的資料同步。slurpd精靈實現了這一功能,它通過定期活動檢查主伺服器master上的記錄檔,檢查master上的資料是否有更新。如果有更新,那麼把更新的資料傳遞到各個從伺服器。讀(查詢)請求可以由LDAP資料群中的任一伺服器應答,但寫操作(update、insert)只能在主伺服器master上進行,這就是為什麼midd資料庫中間引擎必須採用不同的啟動模式來處理讀寫的原因。
下面主要說明主、從LDAP伺服器的配置過程。有關OpenLDAP的安裝過程可以查看http://www.openldap.org上的安裝文檔,本文不再贅述。將OpenLDAP安裝到兩台伺服器上,並對它們分別進行主、從配置。
1.主LDAP伺服器(master)上的設定檔如下,這是一個簡單的配置例子。
設定檔名:slapd.conf
檔案內容:
include /Opt/LDAP/etc/openldap/schema/core.schemainclude /Opt/LDAP/etc/openldap/schema/corba.schemainclude /Opt/LDAP/etc/openldap/schema/cosine.schemainclude /Opt/LDAP/etc/openldap/schema/inetorgperson.schemainclude /Opt/LDAP/etc/openldap/schema/java.schemainclude /Opt/LDAP/etc/openldap/schema/nis.schemainclude /Opt/LDAP/etc/openldap/schema/misc.schemainclude /Opt/LDAP/etc/openldap/schema/mail.schemainclude /Opt/LDAP/etc/openldap/schema/openldap.schemaaccess to * by self write by dn.base="cn=Manager,dc=yourdomain,dc=com" write by * readpidfile /Opt/LDAP/var/slapd.pidargsfile /Opt/LDAP/var/slapd.args# ldbm database definitions#database bdbdatabase ldbmsuffix "dc=yourdomain,dc=com"rootdn "cn=Manager,dc=yourdomain,dc=com"# Cleartext passwords, especially for the rootdn, should# be avoid. See slappasswd(8) and slapd.conf(5) for details.# Use of strong authentication encouraged.rootpw test# The database directory MUST exist prior to running slapd AND# should only be accessible by the slapd/tools. Mode 700 recommended.replogfile /Opt/LDAP/var/slapd.replogdirectory /Opt/LDAP/var/ldbm# Indices to maintainaccess to attr=userPassword by self write by anonymous auth by dn.base="cn=Manager,dc=yourdomain,dc=com" write by * noneaccess to * by self write by dn.base="cn=Manager,dc=yourdomain,dc=com" write by * nodeindex objectClass eqreplica host=slave:389 binddn="cn=Manager,dc=yourdomain,dc=com" bindmethod=simple credentials=test |
2.從LDAP伺服器(slave)上的設定檔。
設定檔名:slapd.conf
檔案內容:
include /Opt/LDAP/etc/openldap/schema/core.schemainclude /Opt/LDAP/etc/openldap/schema/corba.schemainclude /Opt/LDAP/etc/openldap/schema/cosine.schemainclude /Opt/LDAP/etc/openldap/schema/inetorgperson.schemainclude /Opt/LDAP/etc/openldap/schema/java.schemainclude /Opt/LDAP/etc/openldap/schema/nis.schemainclude /Opt/LDAP/etc/openldap/schema/misc.schemainclude /Opt/LDAP/etc/openldap/schema/mail.schemainclude /Opt/LDAP/etc/openldap/schema/openldap.schemaaccess to * by self write by dn.base="cn=Manager,dc=yourdomain,dc=com" write by * readpidfile /Opt/LDAP/var/slapd.pidargsfile /Opt/LDAP/var/slapd.args# ldbm database definitions#database bdbdatabase ldbmsuffix "dc=yourdomain,dc=com"rootdn "cn=Manager,dc=yourdomain,dc=com"rootpw test#replogfile /Opt/LDAP/var/slapd.replogdirectory /Opt/LDAP/var/ldbmaccess to attr=userPassword by self write by anonymous auth by dn.base="cn=Manager,dc=yourdomain,dc=com" write by * noneaccess to * by self write by dn.base="cn=Manager,dc=yourdomain,dc=com" write by * readindex objectClass eqaccess to * by self read by dn="cn=Manager,dc=yourdomain,dc=com" write by * noneupdatedn "cn=Manager,dc=yourdomain,dc=com" |
分別對主、從LDAP資料庫進行配置後,初始化主LDAP資料庫中的資料,可以利用OpenLDAP本身提供的工具完成。
3.資料同步。
在運行主、從模式前,必須先將主、從LDAP伺服器上的資料同步。可以通過把master上的資料檔案(本例中是ldbm目錄下的所有檔案)直接拷貝到從LDAP伺服器上,實現節點資料的完全一致。
4.啟動服務
分別啟動服務,測試資料的同步是否有效。先啟動主LDAP伺服器上的兩個進程:
#/opt/LDAP/libexec/slapd -f /opt/LDAP/etc/openldap/slapd.conf -d 5 > /dev/null 2>&1 &
#/opt/LDAP/libexec/slurpd -f /opt/LDAP/etc/openldap/slapd.conf -d 5 > /dev/null 2>&1 &
然後啟動從LDAP伺服器上的進程:
#/opt/LDAP/libexec/slapd -f /opt/LDAP/etc/openldap/slapd.conf -d 5 > /dev/null 2>&1 &
對主LDAP伺服器上的資料進行各種更新操作,包括增加、刪除、修改等動作,然後在從LDAP伺服器上查看資料是否保持與主LDAP伺服器同步更新。通過以上測試,主、從LDAP資料庫伺服器已經達到了資料同步複製的效果。
使用Heartbeat實現自動檢測和任務接管
1.Linux下HA軟體簡要介紹
(1)The High Availability Linux Project
其Heartbeat軟體不僅可以作為高可靠性的HA軟體獨立使用,也可以配合其它IP分發器做Balancing Cluster應用。參見http://www.linux-ha.org。
(2)Lifekeeper
Lifekeeper是一款著名的高可靠性軟體,能支援32個節點的應用,支援Linux、x86 Solaris和Windows等作業系統。參見http://oss.missioncriticallinux.com/projects/kimberlite。
(3)SRRD
SRRD(Service Routing Redundancy Daemon),支援PKI、SSL的通訊認證。參見http://srrd.org/。
這裡選擇Linux-HA提供的Heartbeat HA軟體來實現該系統的高可靠性,軟體名Heartbeat,當前最新版本為1.2。Heartbeat通過監控幾個節點的狀態來進行管理操作,監控方式支援串列線和乙太網路作為媒介的通訊,這裡使用乙太網路鏈路。在叢集中的每個節點運行一個精靈進程,名為heartbeat。主精靈派生子進程,以對每個heartbeat媒介進行讀寫,並派生狀態進程。當檢測到節點終止時,heartbeat運行Shell指令碼實現資源任務的切換和接管,從而保證了整個系統的高可靠性。
2.下載安裝Heartbeat
可以從http://www.linux-ha.org/download/下載最新的安裝包,包括src和rpm。本例下載了heartbeat-1.0.4.tar.gz包進行安裝,具體操作如下:
#./configure -prefix=/opt/ha#make#make install |
在此過程中,系統可能會提醒安裝其它依賴軟體包,比如libnet等,按照提示進行下載安裝即可。安裝完成後在/opt/ha目錄下將產生相關子目錄。進入/opt/ha/etc/ha.d,在該目錄下建立以下檔案:ha.cf、authkeys、haresources、myexec。
3.master配置說明:
(1)ha.cf
logfile /var/log/ha-loglogfacility local0keepalive 2deadtime 30warntime 10initdead 120ucast eth0 192.168.1.101nice_failback on//保證slave變為master後,即使master恢複啟動服務也不轉移,從而保證LDAP資料同步。node masternode slave |
(2)authkeys
auth 3
3 md5 test
(3)haresources
master 192.168.1.200 myexec
(4)進入/opt/ha/etc/ha.d/resource.d,建立執行指令碼myexec。
當Heartbeat軟體監控到其它節點出現故障時,會執行該指令碼並完成以下工作:如果本機是主LDAP伺服器,則必須以某種方式(郵件或手機簡訊)來通知系統管理員,待命伺服器出現故障;如果是從伺服器監控到主伺服器不可用狀態,則必須以主LDAP模式啟動LDAP服務,並通過rsh重新啟動遠程midd啟動模式。
主LDAP伺服器上的myexec檔案內容如下:
MASNODE='master'PIDFILE=/Opt/LDAP/var/slapd.pidAPP=/Opt/LDAP/libexec/slapdSLURP=/Opt/LDAP/libexec/slurpdMASTER=/Opt/LDAP/etc/openldap/slapd.master.confSLAVE=/Opt/LDAP/etc/openldap/slapd.slave.conf. /opt/ha/etc/ha.d/shellfuncstest_start () { # first we kill everything possible ha_log "info: $0: Starting" if [ -f $PIDFILE ]; then PID=`head -1 $PIDFILE` ha_log "info: $0: Appears to already be running, killing [$PID]" kill -9 $PID > /dev/null rm $PIDFILE fi # slurpd should die when the slapd process does, but just in case: for i in `ps -ef | grep slurp | grep -v grep | awk '{print $2}' ` do kill -9 $i done # slight delay to allow for stability sleep 2 # now we will attempt to start as a master $APP -f $MASTER //啟動slapd if [ ! -f $PIDFILE ]; then ha_log "warn: $0: Slapd did not start properly" #exit 1 fi # Now we determine if this is the primary or secondary node # first wait a bit for stability sleep 10 # if we are secondary, do nothing: otherwise if [ $HA_CURHOST == $MASNODE ]; then /usr/bin/rsh slave '/opt/ha/etc/ha.d/resource.d/slapd.slave '&//啟動從伺服器上的LDAP /usr/bin/rsh mailserver '/opt/sbin/midd -m master -s slave' & //啟動midd $SLURP -f $MASTER //啟動主伺服器上的複製進程 else ha_log "warn: $0: slave node is not responding" fi}test_stop () { ha_log "info: $0: Shutting down" if [ -f $PIDFILE ]; then PID=`head -1 $PIDFILE` kill -9 $PID > /dev/null rm $PIDFILE fi # Let's be sure it's dead, Jim for i in `ps -ef | grep slap | grep -v grep | awk '{print $2}' ` do kill -9 $i done for i in `ps -ef | grep slurp | grep -v grep | awk '{print $2}' ` do kill -9 $i done}# See how we were called. case "$1" in start) test_start ;; stop) test_stop ;; restart) $0 stop $0 start ;; status) if [ -f $PIDFILE ]; then echo running else echo stopped fi ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 esacexit 0 |
(5)建立/opt/ha/etc/ha.d/resource.d/slapd.slave檔案。
#/bin/sh/opt/LDAP/libexec/slapd -f /opt/LDAP/etc/openldap/slapd.slave.conf -d 5 > /dev/null 2>&1 & |
至此,主伺服器配置完成。
slave伺服器上的配置和master伺服器的完全一樣,差別僅在於將“master”改為“slave”。同時要注意,一是兩台伺服器上必須能夠執行rsh;二是在幾個節點中,能通過設定的主機名稱互相解析到對方的IP地址。這樣,整個系統的HA就配置完成。
(6)啟動heartbeat
首先執行#kill slapd,再啟動master上的heartbeat:
#/etc/init.d/heartbeat start
然後啟動slave上的heartbeat:
#/etc/init.d/heartbeat start
執行#tail -f /var/log/ha-log,確定服務是否正常啟動。如果正常運行,那麼當前的狀態是master提供主LDAP服務;slave提供從LDAP服務。
測試
1.假設master伺服器上的heartbeat停止服務
執行#/etc/init.d/heartbeat stop。該測試期望的狀態是,由slave接替master的服務,變為主LDAP服務。可以通過查看日誌來確定是否發生了預期的結果。
在這種情況下,由於master本身沒斷線,只是heartbeat服務停止,所以當slave變為主LDAP服務時,會同時通過rsh命令把master作為從LDAP服務啟動。這時即使master重新啟動heartbeat,當前的主、從模式也不會改變,即slave伺服器還是作為主LDAP服務運行,而master伺服器作為從LDAP服務運行,從而保證了兩台伺服器的資料同步不會因此發生混亂。
2.假設master系統的網路出現故障(拔掉網線)
測試中將master的網線拔掉,但是各種進程依然在運行。當slave變為主LDAP服務時,由於slave檢測到master死去,所以在變為主LDAP服務的時候沒有啟動slurpd資料同步進程。這時更新slave上的資料,然後恢複master的網路(插上網線),觀察發現master重新變為主LDAP伺服器,slave重新變為從LDAP伺服器。這會導致資料同步出現問題,當slave是主服務時更新的資料,沒有在master中更新。
3.假設master系統完全崩潰(斷掉電源)
兩台伺服器正常啟動後,reboot主伺服器master。這時的slave會和第2種情況一樣,變為主LDAP伺服器,也沒有啟動slurpd進程。更新此時的LDAP資料庫,當master重新啟動後,在沒有啟動heartbeat進程的情況下,slave服務沒有任何變化。啟動master上的beartbeat服務,仍然沒有變化。這時,只能在保持slave為主LDAP服務的前提下,手工啟動兩個LDAP進程來恢複資料同步。具體做法是,在slave伺服器上啟動slurpd,在master伺服器上啟動slapd slave模式的服務,以達到資料同步的目的。
同步後,停止啟動master上的heartbeat,對slave上的heartbeat服務實行restart。這時的結果是滿意的,master又重新獲得了主LDAP服務的控制權,slave作為從LDAP服務進程啟動,同時不間斷LDAP服務。
通過以上測試可知,要解決的問題是第2種情況下怎樣才能保證資料同步,以及第3種情況下master伺服器啟動後slave能夠自動啟動slurpd服務。
對於第2種情況,由於兩個節點間通訊的失敗導致兩台機器都以為對方出現故障,從而試圖由自己充當主節點,最終導致資源出現競爭狀態和資料同步發生混亂。解決這個問題的一個辦法是,通過多種通訊手段來實現網路檢測,從而避免由於暫時的網路問題導致這種情況的出現。
對於第3種情況,可以不管master是否存在,只要伺服器作為主LDAP啟動時啟動slurpd進程,就可以保證slurpd進程的存在(修改slapd指令碼)。對於從故障中恢複的伺服器,可以手工啟動從LDAP服務模式,也可以放在系統啟動指令碼中,來保證恢複後LDAP服務的存在。