在多臺主機中監視和分析大量的信息——CPU 是否超載?網絡接口是否滿負荷?——是一項繁重的工作。不過一個好的解決方案可能只有幾步之遙!開放源代碼 Nagios 項目(請參見參考資料)可以非常方便地解決複雜的監視和通知需求。
瞭解 Nagios 的關鍵在於,它並不是監視和跟蹤“普通的”測量數據,如 CPU 使用率,該工具將所有的信息簡化爲“工作”、“可疑的”和“故障”狀態。這可以幫助操作員根據預定義的和可配置的標準,重點關注最重要和最關鍵的問題。
Nagios 內置了報告停機時間的功能,在跟蹤服務水平協議 (SLA) 的實現時,這可能是非常有用的。正如本文稍後將要說明的,Nagios 還提供了停機自動擴大功能、服務和主機依賴關係,這篇介紹性的文章將主要討論您可以輕鬆地爲基本的監視需求編寫小的、自定義的內容。
安裝
大多數 Linux® 分發版中都內置了 Nagios 安裝。在這種情況下,安裝工作可以很好地與 Apache Web 服務器進行集成。要激活或者更新這種配置,您需要運行下面的命令:
或者 apt-get install nagios-text
。可以從 NagiosExchange 免費下載用於 AIX® 平臺的二進制文件(請參見參考資料)。
對於其他平臺,可以從 Nagios.org 下載 Nagios 的源代碼(請參見參考資料)。生成新的 Nagios 需要一些標準開發工具:
- 工具
gcc
make
autoconf
automake
- 可執行文件
- 包(庫和 Header)
許多與簡單網絡管理協議相關的(SNMP 相關的)插件還需要 Perl 和 Net::SNMP 包。
在安裝和設置了 Nagios 之後,您應該可以使用缺省的 http://your.host.name/nagios
URL 訪問 Nagios。圖 1 顯示了哪些主機和服務已啓動或者停止。
圖 1. Tactical Monitoring Overview 屏幕
配置 Nagios
在缺省情況下,所有的 Nagios 配置文件都位於 /etc/nagios
目錄。爲了方便起見,可能將與 Apache 相關的配置文件符號鏈接到 Apache 配置目錄。可以將配置分爲多個文件,每個文件用於配置中不同的部分。
首先需要設置的組件是聯繫人和聯繫人組。聯繫人是那些接收主機或服務停止運行的通知的人員。在缺省情況下,Nagios 提供了尋呼機和電子郵件通知方式。通過擴展,允許通過 Jabber 和許多其他方式進行通知,這在某些情況下是非常方便的。
聯繫人存儲在 contacts.cfg
文件中,並且定義如下:
清單 1. 配置 1:基本聯繫人信息
define contact{
contact_name jdoe
alias John Due
service_notification_commands notify-by-email
host_notification_commands host-notify-by-emailes
email [email protected]
}
|
將聯繫人劃分成組:在主機或服務狀態發生更改時,Nagios 並不指定需要通知的人員,而是通知相關的組。有時甚至可以對某個人員進行多次定義,以指定不同的通知命令或地址,然後向用戶所在的聯繫組添加聯繫該人員的所有方式(請參見清單 2)。
清單 2. 配置 2:分組的聯繫人
define contactgroup{
contactgroup_name server-admins
alias Server Administrators
members jdoe,albundy
}
|
下一個步驟是配置需要由 Nagios 進行監視的主機。應該添加所有包含監視或檢查是否正處於活動狀態的服務的主機。存儲主機信息的配置文件是 hosts.cfg
。下面是一個主機定義的示例:
清單 3. 配置 3:添加新主機
define host{
host_name ubuntu_1_2
alias Ubuntu test server
address 192.168.1.2
check_command check-host-alive
max_check_attempts 20
notifications_enabled 1
event_handler_enabled 0
flap_detection_enabled 0
process_perf_data 1
retain_status_information 1
retain_nonstatus_information 1
notification_interval 60
notification_period 24x7
notification_options d,u,r
}
|
Nagios 配置的最後一步是爲配置的主機定義服務。這個示例使用了一個預定義的“ping”Nagios 插件,它將發送 Internet 控制信息協議(Internet Control Message Protocol,ICMP)回顯請求以確定主機是否有響應。
清單 4. 配置 4:添加新服務
define service{
use service-template
host_name ubuntu_1_2
service_description PING
check_period 24x7
contact_groups server-admins
notification_options c,r
check_command check_ping!300.0,20%!1000.0,60%
}
|
在完成了這個配置工作之後,重新啓動您的 Nagios 守護進程,稍等幾秒鐘讓 Nagios 進行初始化,然後,證實 Web 管理接口中 ping 服務的可見性。
如何編寫 Nagios 插件
Nagios 的最激動人心的方面是可以輕鬆地編寫您自己的插件,只需要瞭解一些簡單的指導原則即可。爲了管理插件,Nagios 每次在查詢一個服務的狀態時,產生一個子進程,並且它使用來自該命令的輸出和退出代碼來確定具體的狀態。退出狀態代碼的含義如下所示:
- OK —退出代碼 0—表示服務正常地工作。
- WARNING —退出代碼 1—表示服務處於警告狀態。
- CRITICAL —退出代碼 2—表示服務處於危險狀態。
- UNKNOWN —退出代碼 3—表示服務處於未知狀態。
最後一種狀態通常表示該插件無法確定服務的狀態。例如,可能出現了內部錯誤。
下面提供了一個 Python 示例腳本,用於檢查 UNIX® 平均負載。它假定 2.0 以上的級別表示警告狀態,而 5.0 以上的級別表示危險狀態。這些值都採用了硬編碼的方式,並且始終使用最近一分鐘的平均負載。
清單 5. Python 插件—示例工作插件
#!/usr/bin/env python
import os,sys
(d1, d2, d3) = os.getloadavg()
if d1 >= 5.0:
print "GETLOADAVG CRITICAL: Load average is %.2f" % (d1)
sys.exit(2)
elif d1 >= 2.0:
print "GETLOADAVG WARNING: Load average is %.2f" % (d1)
sys.exit(1)
else:
print "GETLOADAVG OK: Load average is %.2f" % (d1)
sys.exit(0)
|
在編寫了這個小的可執行插件之後,接下來是使用 Nagios 註冊該插件,並創建一個檢查平均負載的服務定義。
這項工作也是非常簡單的:使用下面的內容創建一個名爲 /etc/nagios-plugins/config/mygetloadavg.cfg
的文件,根據下面的示例,向 services.cfg
文件添加一個服務。請記住,必須在 hosts.cfg
配置文件中定義 localhost
。
清單 6. 示例插件—使用 Nagios 進行註冊
define command{
command_name check_mygetloadavg
command_line /path/to/check_getloadavg
}
|
清單 7. 創建一個使用示例插件的服務
define service{
use service-template
host_name localhost
service_description LoadAverage
check_period 24x7
contact_groups server-admins
notification_options c,r
check_command check_mygetloadavg
}
|
編寫一個完整的插件
前面的示例說明了一個採用“硬編碼”方式插件的限制,它不支持運行時配置。在實際中,通常最好的方式是創建一個可配置的插件。通過這種方式,您可以創建和維護一個插件,使用 Nagios 將其註冊爲單個插件,並且傳遞參數以便爲特定的情況自定義警告和危險水平。下一個示例還包括一則使用消息;經過證實,對於由幾個不同的開發人員或者管理員所使用或維護的插件,這是非常有價值的。
另一個好的實踐是捕獲所有的異常,並後退以報告 UNKNOWN 服務狀態,以便 Nagios 能夠正確地管理有關這個情況的通知。那些允許異常“失敗”的插件通常會退出,並返回值 1;對於 Nagios,這表示一個 WARNING 狀態。請確保您的插件能夠正確地區分 WARNING 和 UNKNOWN。請注意,例如,在將其作爲 UNKNOWN 結果處理可能出現錯誤的情況下,通常可以禁用至少某些 WARNING 通知。
用 Python 編寫一個插件
上述的建議—運行時參數化、一則使用消息,以及經過改進的異常處理—將得到示例插件的源代碼,這段代碼要比前面的長几倍。但是您可以更安全地對錯誤進行處理,並且能夠在更廣泛的範圍內重用該插件。
清單 8. Python 插件—獲取平均負載的完整插件
#!/usr/bin/env python
import os
import sys
import getopt
def usage():
print """Usage: check_getloadavg [-h|--help] [-m|--mode 1|2|3] \
[-w|--warning level] [-c|--critical level]"
Mode: 1 - last minute ; 2 - last 5 minutes ; 3 - last 15 minutes"
Warning level defaults to 2.0
Critical level defaults to 5.0"""
sys.exit(3)
try:
options, args = getopt.getopt(sys.argv[1:],
"hm:w:c:",
"--help --mode= --warning= --critical=",
)
except getopt.GetoptError:
usage()
sys.exit(3)
argMode = "1"
argWarning = 2.0
argCritical = 5.0
for name, value in options:
if name in ("-h", "--help"):
usage()
if name in ("-m", "--mode"):
if value not in ("1", "2", "3"):
usage()
argMode = value
if name in ("-w", "--warning"):
try:
argWarning = 0.0 + value
except Exception:
print "Unable to convert to floating point value\n"
usage()
if name in ("-c", "--critical"):
try:
argCritical = 0.0 + value
except Exception:
print "Unable to convert to floating point value\n"
usage()
try:
(d1, d2, d3) = os.getloadavg()
except Exception:
print "GETLOADAVG UNKNOWN: Error while getting load average"
sys.exit(3)
if argMode == "1":
d = d1
elif argMode == "2":
d = d2
elif argMode == "3":
d = d3
if d >= argCritical:
print "GETLOADAVG CRITICAL: Load average is %.2f" % (d)
sys.exit(2)
elif d >= argWarning:
print "GETLOADAVG WARNING: Load average is %.2f" % (d)
sys.exit(1)
else:
print "GETLOADAVG OK: Load average is %.2f" % (d)
sys.exit(0)
|
爲了使用這個新的插件,需要使用下面的方法來註冊 /etc/nagios-plugins/config/mygetloadavg2.cfg
:
清單 9. Python 插件—使用 Nagios 進行註冊
define command{
command_name check_mygetloadavg2
command_line /path/to/check_getloadavg2 -m $ARG1$ -w $ARG2$ -c $ARG3$
}
|
另外,根據下面的示例,在 services.cfg
文件中添加或者更改服務條目。請注意,使用感嘆號 !
來分隔插件參數。與前面一樣,必須在 hosts.cfg
配置文件中定義 localhost
。
清單 10. 創建一個使用 Python 插件的服務
define service{
use service-template
host_name localhost
service_description LoadAverage2
check_period 24x7
contact_groups server-admins
notification_options c,r
check_command check_mygetloadavg2!1!3.0!6.0
}
|
用 Tcl 編寫一個插件
最後的示例是使用 Tcl 編寫的一個插件,它使用簡單對象訪問協議 (SOAP) 和 Web 服務描述語言 (WSDL) 檢查 xmenthods.net 的匯率。SOAP 爲該插件提供了匯率的當前值,並將這些值與配置的範圍進行比較。如果該值不屬於警告的範圍,那麼它將被認爲是 OK。如果該值大於或者小於警告級別,但是並沒有超過危險極限,則將狀態設置爲 WARNING。否則將其設置爲 CRITICAL,除非出現了網絡錯誤,在這種情況下將狀態設置爲 UNKNOWN。
該插件可以識別不同的可配置參數,以便能夠檢查不同範圍的匯率。它還可以用於檢查各個國家的各種匯率。
清單 11. Tcl 插件—驗證當前匯率
#!/usr/bin/env tclsh
# parse arguments
package require cmdline
set options {
{country1.arg "" "Country 1"}
{country2.arg "" "Country 2"}
{lowerwarning.arg "" "Lower warning limit"}
{upperwarning.arg "" "Upper warning limit"}
{lowercritical.arg "" "Lower critical limit"}
{uppercritical.arg "" "Upper critical limit"}
}
array set opt [cmdline::getoptions argv $options {: [options]}]
# if the user did not supply all arguments, show help message
for each necessary [array names opt] {
if {$opt($necessary) == ""} {
set argv "-help"
catch {cmdline::getoptions argv $options {: [options]}} usage
puts stderr $usage
exit 3
}
}
# load TclWebServices package
package require WS::Client
if {[catch {
# download WSDL
WS::Client::GetAndParseWsdl \
http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl \
{} currency
# create stub commands
WS::Client::CreateStubs currency
# download the actual exchange rate
set result [lindex \
[currency::getRate "England" "Japan"] 1]
} error]} {
# if downloading the rate failed for some reason, report it
puts "EXCHANGERATE UNKNOWN: $error"
exit 3
}
if {($result < $opt(lowercritical)) || ($result > $opt(uppercritical))} {
puts "EXCHANGERATE CRITICAL: rate is $result"
exit 2
}
if {($result < $opt(lowerwarning)) || ($result > $opt(upperwarning))} {
puts "EXCHANGERATE WARNING: rate is $result"
exit 1
}
puts "EXCHANGERATE OK: rate is $result"
exit 0
|
現在,您需要註冊這個命令,以便 Nagios 知道如何調用它。爲了完成這項工作,可以使用與前面類似的配置和命令定義來創建一個名爲 /etc/nagios-plugins/config/exchangerate.cfg
的文件:
command_line /path/to/check_exchangerate
-country1 $ARG1$ -country2 $ARG2$ -lowercritical \
$ARG3$ -lowerwarning $ARG4$ -upperwarning $ARG5$ -uppercritical $ARG6$
|
在下面的示例中,假定該命令的名稱爲 check_exchangerate
。
接下來,創建一個使用剛剛創建的插件來監視匯率的服務。下面是服務定義,它將該服務與 localhost
服務器關聯起來。儘管這個檢查並不真正地關聯於任何物理主機,但是需要將它綁定到一臺主機。如果這個檢查涉及到調用受信任的網絡中的服務器的 SOAP 方法,那麼您可以添加需要進行監視的實際服務器,並且在這個示例中,應該將服務綁定到該服務器。清單 12 中的代碼檢查 英鎊對日元的匯率,並驗證匯率位於 225 到 275 之間。
清單 12. 添加 Tcl 插件作爲一個新的服務
define service{
use service-template
host_name localhost
service_description EXCHANGERATE
check_period 24x7
contact_groups other-admins
notification_options c,r
check_command check_exchangerate!England!Japan!200!225!275!300
}
|
結束語
您可以使用 Nagios 監視所有類型的硬件和軟件。您可以編寫自己的插件,這使得能夠監視與 Nagios 服務器進行通信的各種對象。正如您可以使用管理命令行參數和退出狀態的任何計算語言一樣,存在各種各樣的可能性。
高級系統管理員可以使用 Tcl 或者任何其他語言來擴展 SOAP 示例,以便與內部網 Web 服務進行通信,並編寫插件以驗證該服務行爲的正確性。
還可以使用 C 插件或者將 C 嵌入到您最喜歡的動態語言中(對於 Python,使用 Pyinline
;對於 Perl,使用 Inline
;或者對於 Tcl,使用 Critcl
),以便將您的操作系統的 C API 與您的插件(使用高級語言編寫)組合在一起。
Nagios 的另一個值得關注的特性是被動檢查。到此爲止,您所看到的 Nagios 監視功能可以管理短期狀態的可執行文件,啓動它們,然後接收結果。在被動檢查過程中,Nagios 並不產生插件以檢查狀態,而是不同的應用程序週期性地或者當服務狀態發生更改時,將狀態更新發送給 Nagios。這樣的應用程序可以接收來自其他源的通知,對其進行聚合,並將經過計算的彙總信息傳遞給 Nagios。如果經過一段時間還沒有接收到來自某個服務的通知,Nagios 還可以假定該服務已經停止。我們將在後續的文章中說明 Nagios 被動檢查的實現。
使得 Nagios 插件如此激動人心的原因是,它們非常容易進行編寫和共享。Nagios 插件非常適合於網絡和系統管理員所碰到的各種情況,並且在許多情況下,可以很簡單地重用其他人已經完成的工作。正如運行良好的 Wiki 或者 Web 本身一樣,可以很容易地提供一個有幫助的示例,不過所有可用的 Nagios 插件的整體價值是非常巨大的。