當組織添加應用程式和服務時,將認證和密碼服務集中化可以增加安全性、減少管理開銷及開發人員的負擔。但是,將所有服務聚集到單個伺服器上會引起可靠性問題。對於企業認證服務,高可用性尤其關鍵,因為在許多情況中,當認證停止工作時,整個企業都將陷入停頓。
我們使用 LDAP輕量級目錄訪問協議,Lightweight Directory Access Protocol)伺服器來提供認證服務,各種應用程式都可以訂閱這些服務。為了提供高度可用的 LDAP 伺服器,我們使用來自 Linux-HAwww.linux-ha.org)倡議的 heartbeat 軟體包。我們也提供一個樣本,設定 Apache Web 服務器以使用 LDAP 認證。
關於 LDAP 的一些背景知識
我們使用 OpenLDAP 軟體包 www.openldap.org),它是幾種 Linux 分發版的組成部分。它隨 RedHat 7.1 一起提供,其當前下載版本是 2.0.11。
RFC 的 2251 和 2253 中定義了 LDAP 標準。存在幾種 LDAP 的商業實現,其中包括密西根大學University of Michigan)的實現和 Netscape 的實現。OpenLDAP 基金會是作為“為開發健壯的、商業層級的、功能完善和開放源碼的 LDAP 應用程式與開發工具套件而協力完成的工作”建立的請參閱 www.openldap.org)。OpenLDAP V1.0 於 1998 年 8 月發行。其當前主要版本是 2.02000 年 8 月 31 日發布),添加了 LDAPv3 支援。
正如所有好的網路服務一樣,LDAP 旨在跨多個伺服器運行。本文使用了 LDAP 的兩個特性 — 複製replication)和 引用referral)。
引用機制使您能跨多伺服器分割 LDAP 名稱空間,並能以階層的形式安排 LDAP 伺服器。LDAP 在一個特定目錄名稱空間中只允許有一個主伺服器。
複製由 OpenLDAP 複製精靈 slurpd驅動。slurpd 定期醒來並檢查主伺服器上的記錄檔,看是否有更新。更新隨後被傳遞到從伺服器。讀請求可以由任一伺服器應答,但更新只能在主伺服器上進行。對從伺服器的更新要求會產生一個引用訊息,該訊息會給出主伺服器的地址。跟蹤引用和重新嘗試更新是客戶機的職責。OpenLDAP 沒有內建方法來跨已複製伺服器分發查詢,因此必須使用 IP 發射器sprayer)/扇出fanout)程式如 balance)。
為了實現可靠性目標,我們將一對伺服器以群集方式組織在一起。我們可以在伺服器間使用共用儲存空間,維護一個資料副本。但為了簡單起見,我們選擇進行無共用shared-nothing)的實現。LDAP 資料庫通常很小,而且更新頻率較低提示:如果您的 LDAP 資料集確實較大,請考慮用引用將名稱空間劃分成較小的部分)。重新啟動故障節點時,對無共用設定的確需要注意:在重新啟動之前,必須將所有新的更改添加到故障節點上的資料庫。稍後,我們將示範一個樣本。
群集軟體和配置
在開始之前,讓我們澄清一個細微的混淆。大多數 HA高可用性,High Availability)群集都有一個名為“heartbeat”的系統持活system-keepalive)功能。HA 軟體使用 heartbeat 以監控群集中節點的健康狀態。Linux-HA www.linux-ha.org)組提供了開放源碼群集軟體。他們軟體包的名稱是 Heartbeat目前是 Heartbeat-0.4.9)。這可能導致一些可以理解的混淆喔,它有時也使我糊塗)。在本文中,我們將把 Linux-HA 軟體包稱為“Heartbeat”,而把一般性的概念稱為“heartbeat”。
Linux-HA 項目作為 Linux-HA HOWTOHarald Milz 撰寫)的產物於 1998 年啟動。該項目目前由 Alan Robertson 和其他許多志願開發人員領導。版本 0.4.9 於 2001 年早期發布。
Heartbeat 通過通訊媒介監控節點的可用狀態,媒介通常是串列線或乙太網路。最好有多個冗餘媒介,因此我們使用了一條串列線和一個乙太網路鏈路。每個節點運行一個精靈進程名為“heartbeat”)。主精靈派生子進程以對每個 heartbeat 媒介進行讀寫,並且派生狀態進程。當檢測到節點終止時,Heartbeat 運行 shell 指令碼以在輔助節點上啟動或停止)服務。在設計時,規定這些指令碼使用與系統 init 指令碼通常位於 /etc/init.d)相同的文法。它還提供了用於檔案系統、Web 服務器和虛擬 IP 容錯移轉的預設指令碼。
假設有兩個匹配的 LDAP 伺服器,我們可以使用幾種配置。首先,我們可以實現‘冷待命’。主節點有一個虛擬 IP 和正在啟動並執行伺服器。輔助節點處於空閑狀態。當主節點出現故障時,伺服器執行個體和 IP 會轉移到“冷”節點。這是容易實現的,但主伺服器和次要伺服器之間的資料同步卻是個問題。要解決這個問題,我們可以這樣配置群集,即在兩個節點上都配置處於運行狀態的伺服器。主節點運行主 LDAP 伺服器,輔助節點則運行從執行個體。對主伺服器的更新通過 slurpd 被立即傳遞到從伺服器。
主節點的故障使得輔助節點要響應查詢,但現在我們還不能更新。為了提供更新,在容錯移轉時,我們要重新啟動次要伺服器並將它提升為主伺服器。
這給予我們完整的 LDAP 服務,但卻增加了一個問題 — 如果向次要伺服器作出了更新,那麼在允許它重新啟動之前必須修複主伺服器。Heartbeat 支援‘nice failback’選項,該選項禁止有故障的節點在容錯移轉後重新獲得資源,這會更令人滿意。在本文中,我們手工示範重新啟動。我們的樣本配置將使用 Heartbeat 提供的虛擬 IP 工具。如果需要支援較重的查詢負載,則會用同時向主從伺服器分發查詢的 IP 發射器取代虛擬 IP。在這一情況中,對從伺服器作出的更新要求會產生引用。對引用的跟蹤不是自動的;必須將該功能構建到客戶機應用程式中。除了複製偽指令外,主節點和從節點是以完全相同的方式配置的。 主伺服器設定檔指明複製記錄檔的位置第 16 行),並且有一份從伺服器的清單,這些從伺服器是具有憑證資訊的複製目標第 34-36 行)。
34 replica host=slave5:389 35 binddn="cn=Manager,dc=lcc,dc=ibm,dc=com"; 36 bindmethod=simple credentials=secret
|
從伺服器設定檔不指明主伺服器;相反,它列出複製所需的憑證資訊第 33 行)。
33 updatedn "cn=Manager,dc=lcc,dc=ibm,dc=com"
常規 Heartbeat 準備
有幾個較好的基本 Heartbeat 配置樣本可供使用請參閱本文的結尾部分)。以下是我們的配置中相關的內容。我們的配置非常簡單,所以沒有多少內容。預設情況下,所有的設定檔都儲存在 /etc/ha.d/中。
ha.cf包含群集的全域定義。我們對所有的逾時都採用預設值。
# Timeout intervals keepalive 2 # keepalive could be set to 1 second here deadtime 10 initdead 120 # define our communications # serial serialportname ... serial /dev/ttyS0 baud 19200 # Ethernet information udpport 694 udp eth1 # and finally, our node id's # node nodename ... -- must match uname -n node slave5 node slave6
|
haresources該檔案是配置容錯移轉的地方。在檔案的底部有些有趣的東西。
slave6 192.168.10.51 slapd
我們在這裡指明了三件事。資源的主要所有者是節點‘slave6’該名稱必須與您打算設為主節點機器的‘uname -n’輸出相匹配)。我們的服務地址虛擬 IP)是‘192.168.10.51’本樣本是在專用實驗室網路完成的,所以使用 192.168 地址)。服務指令碼的名稱是‘slapd’。Hearbeat 將在 /etc/ha.d/resource.d 和 /etc/init.d 中尋找指令碼。
服務指令碼
對於簡單“冷待命”情況,我們可以不加修改地使用標準 /etc/init.d/slapd 指令碼。我們希望做一些特別的事,因此我們建立了自己的 slapd 指令碼,該指令碼儲存在 /etc/ha.d/resource.d/中。 Heartbeat 將該目錄放置在其搜尋路徑中的第一位,因此我們不必擔心會運行 /etc/init.d/slapd 指令碼。但是,您應該檢查以確保引導時不再啟動 slapd從 /etc/rc.d 樹結構除去所有 S*slapd 檔案)。首先,我們在第 17 行和第 18 行指明 slapd 伺服器的啟動設定檔。
該指令碼遵循標準 init.d 文法,因此啟動資訊包含在從第 21 行開始的 test_start() 函數中。首先,我們停止當前啟動並執行所有 slapd 執行個體。在第 39 行,我們使用主伺服器設定檔啟動主伺服器。我們的設計將遵循這樣的規則:如果主節點和輔助節點都已啟動,則在主節點上將 slapd 作為主服務指令碼啟動,在輔助節點上將 slapd 作為從服務指令碼啟動,並啟動複製精靈。如果只有一個節點啟動,則將 slapd 作為主服務指令碼啟動。將虛擬 IP 綁定到 slapd 主服務指令碼。要完成這一點,我們必須知道哪個節點正在執行該指令碼,如果是主節點,那麼我們需要知道輔助節點的狀態。重要的內容在指令碼的‘start’分支中。因為我們已經在 Heartbeat 配置中指明了主節點,所以我們知道當 test_start() 函數運行時,它運行在 Heartbeat 主節點上因為 Heartbeat 使用 /etc/init.d/ 指令碼,因此所有的指令碼都用參數“start|stop|restart”調用)。當呼叫指令碼時,Heartbeat 會設定許多環境變數。下面是我們感興趣的一個:
HA_CURHOST=slave6
可以使用‘HA_CURHOST’值來瞭解何時正在主節點slave6)上執行以及何時處於容錯移轉中HA_CURHOST 應是‘slave5’)。現在我們需要知道另一個節點的狀態。要瞭解這一點,可以“詢問” Heartbeat。我們將使用隨 Heartbeat 一同提供的 api_test.c檔案,並建立一個簡單的客戶機來“詢問”節點狀態api_test.c 檔案有許多內容都與客戶機有關,我們只需除去不需要的內容,然後添加一條輸出語句)。請注意程式中執行查詢的第 31 行。
Heartbeat 查詢原始碼清單
編譯後,我們將檔案安裝在 /etc/ha.d/resource.d/中。程式的名稱為‘other_state’。以下是訪問完整的容錯移轉指令碼的連結,我們還是從與 Heartbeat 一同提供的樣本指令碼開始,並增加少許修改:
啟動指令碼
測試
我們現在可以在兩個伺服器上都啟動 Heartbeat。Heartbeat 文檔包含一些有關測試基本設定的資訊,所以我們將不在這裡重複。在串連了兩種 heartbeat 媒介的情況下,您應該看到六個 heartbeat 進程正在運行。為了驗證容錯移轉,我們做了幾種測試。為了提供測試用的客戶機,我們建立了一個簡單的 KDE 應用程式,該應用程式查詢服務器並顯示串連的狀態。真正的客戶機在這種情況下只查詢虛擬 IP,但我們查詢所有的三個 IP,以作為示範之用。為進行該測試,我們每小時發送一萬條查詢。
S6 是主 LDAP 伺服器,S5 是活動的待命伺服器。下面的框代表虛擬 IP。在正常狀態下,S5 和 S6 都為綠色,表明成功的查詢。
首先,我們停止主節點上的 heartbeat 進程。在此情況下,從機器在 10 秒鐘的節點逾時出現後獲得資源,如日誌摘錄中所示:接管過程包括啟動指令碼中額外的 2 秒延遲。
Sep 7 10:28:21 slave5 heartbeat: info: Running /etc/ha.d/rc.d/shutdone shutdone Sep 7 10:28:32 slave5 heartbeat[3381]: WARN: node slave6: is dead Sep 7 10:28:32 slave5 heartbeat[3381]: info: Link slave6:/dev/ttyS0 dead. Sep 7 10:28:32 slave5 heartbeat[3381]: info: Link slave6:eth1 dead. Sep 7 10:28:32 slave5 heartbeat: info: Running /etc/ha.d/rc.d/status status Sep 7 10:28:32 slave5 heartbeat: info: Running /etc/ha.d/rc.d/ifstat ifstat Sep 7 10:28:32 slave5 heartbeat: info: Running /etc/ha.d/rc.d/ifstat ifstat Sep 7 10:28:32 slave5 heartbeat: info: Taking over resource group 192.168.10.51 Sep 7 10:28:32 slave5 heartbeat: info: Acquiring resource group: slave6 192.168.10.51 slapd Sep 7 10:28:32 slave5 heartbeat: info: Running /etc/ha.d/resource.d/IPaddr 192.168.10.51 start Sep 7 10:28:32 slave5 heartbeat: info: ifconfig eth0:0 192.168.10.51 netmask 255.255.255.0 \ broadcast 192.168.10.255 Sep 7 10:28:32 slave5 heartbeat: info: Sending Gratuitous Arp for 192.168.10.51 on eth0:0 [eth0] Sep 7 10:28:32 slave5 heartbeat: info: Running /etc/ha.d/resource.d/slapd start Sep 7 10:28:32 slave5 heartbeat: info: /etc/ha.d/resource.d/slapd: Starting
|
以下是應用程式的查詢流:
主節點當機,現在由輔助節點提供虛擬 IP。S5 和虛擬 IP 顯示為綠色,伺服器 S6 不可用,指標為紅色。
重新啟動群集之後,我們通過對主節點斷電來造成一次故障。在 10 秒逾時到時間以後,輔助節點再一次擷取了資源。最後,我們通過拔掉串列介面和乙太網路介面來類比兩節點之間互連的完全失敗。節點間通訊的失敗導致兩台機器都試圖充當主節點。這種情形被稱為 “裂腦split-brain)”。Heartbeat 在這種情形下的預設行為說明了為什麼 Heartbeat 需要多個使用不同媒介的互連媒介。在共用儲存空間設定中,儲存空間互連也可以作為 heartbeat 媒介使用,這減少了“裂腦”的機會。以下是來自 ha-log 的樣本,它顯示了關機過程:
heartbeat: 2001/09/07_14:49:46 info: mach_down takeover complete. heartbeat: 2001/09/07_14:50:36 ERROR: TTY write timeout on [/dev/ttyS0] (no connection?) heartbeat: 2001/09/07_14:52:53 WARN: Cluster node slave6 returning after partition heartbeat: 2001/09/07_14:52:53 info: Heartbeat shutdown in progress. heartbeat: 2001/09/07_14:52:53 ERROR: 105 lost packet(s) for [slave6] [191:297] heartbeat: 2001/09/07_14:52:53 ERROR: lost a lot of packets! heartbeat: 2001/09/07_14:52:53 info: Link slave6:eth1 up. heartbeat: 2001/09/07_14:52:53 WARN: Late heartbeat: Node slave6: interval 211920 ms heartbeat: 2001/09/07_14:52:53 info: Node slave6: status active heartbeat: 2001/09/07_14:52:53 info: Giving up all HA resources. heartbeat: 2001/09/07_14:52:53 info: Running /etc/ha.d/rc.d/status status heartbeat: 2001/09/07_14:52:53 info: Running /etc/ha.d/rc.d/ifstat ifstat heartbeat: 2001/09/07_14:52:53 info: Running /etc/ha.d/rc.d/shutdone shutdone heartbeat: 2001/09/07_14:52:53 info: Releasing resource group: slave6 192.168.10.51 slapd heartbeat: 2001/09/07_14:52:53 info: Running /etc/ha.d/resource.d/slapd stop heartbeat: 2001/09/07_14:52:53 info: /etc/ha.d/resource.d/slapd: Shutting down heartbeat: 2001/09/07_14:52:53 info: Running /etc/ha.d/resource.d/IPaddr 192.168.10.51 stop heartbeat: 2001/09/07_14:52:53 info: IP Address 192.168.10.51 released heartbeat: 2001/09/07_14:52:54 info: All HA resources relinquished. heartbeat: 2001/09/07_14:52:54 info: Heartbeat shutdown in progress. heartbeat: 2001/09/07_14:52:54 info: Giving up all HA resources. heartbeat: 2001/09/07_14:52:54 info: All HA resources relinquished. heartbeat: 2001/09/07_14:52:55 info: Heartbeat shutdown complete.
|
應在選擇逾時值時考慮這一問題。如果逾時太短,負載繁重的系統會錯誤地觸發接管,從而產生明顯的“裂腦”關機。請參閱 Linux-ha FAQ 文檔以獲得有關這一點的更多資訊。
容錯移轉後的恢複
如果當主 LDAP 伺服器當機時,對 LDAP 名稱空間進行了更新,則必須在重新啟動主伺服器之前重新同步 LDAP 資料庫。有兩種方法可做到這一點。如果可以中斷服務的話,可以在 LDAP 伺服器停止後手工複製資料庫預設情況下,資料檔案被放置在 /usr/local/var 中)。也可以使用 OpenLDAP 複製來恢複資料庫而無需服務中斷。首先,在以前的主節點上將 LDAP 伺服器作為從伺服器啟動。然後在當前主節點上啟動 slurpd 精靈。在前主節點退出服務期間收到的更改將從新主節點“推”到原來的節點上。最後,在以前的主節點上停止從 LDAP 伺服器,並啟動 Heartbeat。這將導致向原始配置進行容錯回復。
針對 Apache 的 LDAP 配置
這裡是向 LDAP 伺服器進行訂閱的應用程式樣本。該應用程式是 Apache Web 服務器,使用 mod_auth_ldap 軟體包。
結束語
本文是一個非常簡單的樣本,使用開放源碼軟體建立一些高度可用的基本網路服務。網路服務包括 LDAP)很少需要大型伺服器。由群集提供的額外可靠性以及伺服器和資料檔案的複製可以增加服務可用性。系統經曆了所有的測試,在所有情況下都在 15 秒內進行了容錯移轉。假如對系統負載和利用率有較好的理解,可以把容錯移轉時間減少到這個閾值以下。