天天看點

nagios插件編寫及使用nrpe執行root指令

MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0

前言:Nagios是相當不錯的監控工具,被稱作是“監控之神”,但同樣也有“難搞死”頭銜。發揮 Nagios一切魅力的都是他的插件,正因為豐富多樣的插件讓nagios有血有肉。監控的内容不斷在變化,插件也不斷變化,預設的一些插件可能越來越不 能滿足需求,這個時候就要自己來寫些插件了。

以下就是用我的第一個Nagios插件來說明編寫方法和我遇到一些問題調試方法。如果你有耐心可以通篇看完,應該對第一次寫的人來說會有很大幫助(如果你看不懂,可能是我寫得不清楚 那就沒辦法了 表達能力有限)

需求:

監控普通磁盤的健康狀況(普通磁盤以外還有RAID、陣列的監控是不同方法來做的,這裡先不讨論,先從最簡單的入手),定期進行檢測,并進行報警,報警内容磁盤是否正常,不正常是什麼狀态。

分析編寫過程:

我寫腳本的前提都是先從手動成功完成,再到自動化(我想其它人的思路應該都一樣的)

1、找到監控磁盤的方法

通過一番查找 smartctl 這個指令是比較不錯的  centos slackware一般的預設都有這個

smartctl -H /dev/sda  隻檢測狀态

smartctl -i /dev/sda   隻檢測硬碟資訊

smartctl -a /dev/sda 檢測所有資訊

2、擷取檢測資訊

# smartctl -H /dev/sda

smartctl version 5.38 [x86_64-redhat-linux-gnu] Copyright (C) 2002-8 Bruce Allen

Home page is http://smartmontools.sourceforge.net/

SMART Health Status: OK

關鍵的最後一行說明磁盤的情況       截取  DISK_HEALTH=`smartctl -H /dev/sda | tail -1 | cut -d: -f2-  `

3、 進行關鍵判斷

據我所知道的 smartctl 5.38  是出以上的結果 為OK

而 smartctl 5.39 是出以下結果

=== START OF READ SMART DATA SECTION ===

SMART overall-health self-assessment test result: PASSED

關鍵詞是PASSED

是以要分析判斷多種情況

4、腳本編寫步驟

1)了解nagios插件編寫規範

Nagios的插件可以用腳本(shell、Perl)C編譯後的可執行程式,但必須滿足以下兩件事:

A、既出時有一個傳回值

B、至少向标準輸出裝置(STDOUT)輸出一行檔案。(但也不能太大,預設是4K,如果想大些,修改源程式吧,方法搜。。。)

傳回值定義:

Plugin Return Code

Service State

DISK State

OK

OK 或者PASSED

1

WARNING

插件警告  DISK報警隻分OK或者CRITICAL

2

CRITICAL

DISK檢測非OK 或者PASSED

3

UNKNOWN

未知狀态

2)插件編寫SHELL速成法

在這裡我選用我最熟悉的SHELL進行腳本編寫 ,

我的速成法就是,直接去nagios exchange 去下比較成熟的比較簡單的shell腳本,這樣會從一開始借鑒别人好的方法,養成好的習慣,而且隻要你有一點SHELL程式設計經驗也可以很快寫得像一個老手。(不過不要把自己搞暈了就行)

3)以下是我的check_disk_health.sh

#!/bin/bash

# ========================================================================================

# disk health  plugin for Nagios

#

# Written by    : Ajian

# Release       : 1.2.0

# Creation date : 2009-07-28

# Revision date : 2009-07-30

# Description   : Nagios plugin (script) to check disk health .

#               This script has been designed and written on Linux System.

# USAGE         : ./check_disk_health.sh [-d (disk)]

# Exemple: ./check_cpu_stats.sh

#          ./check_cpu_stats.sh -d /dev/sda

# HISTORY :

#     Release   |     Date      |    Authors            |       Description

# --------------+---------------+----------------------+-----------------------------------

#  1.0.0        | 2009-07-28     | Ajian                | Create the script

#  1.2.0        | 2009-07-30    |  Ajian                | modify the script and run well ,fix a bug.

# -----------------------------------------------------------------------------------------

# NOTICE:

#-----------------------------------------------------------------------------------------

#     You should have the root Permissions ,You can use sudo to realize .

# -----------------------------------------------------------------------------------------                                   

# Nagios return codes

#定義 nagios傳回的狀态變量

STATE_OK=0

STATE_WARNING=1

STATE_CRITICAL=2

STATE_UNKNOWN=3      

# Paths to commands used in this script.  These may have to be modified to match your system setup.

# 定義關鍵的核心指令smartctl 路徑 如果你的系統不是這個位址,請更改。 以下注釋的是調試的資訊,是自動擷取指令路徑的方法。

SMARTCTL="/usr/sbin/smartctl"

#SMARTCTL=`which smartctl`

#if [ $? -ne 0 ]; then

#        echo " smartctl is found in $SMARTCTL ; Go on ... "

#        echo "smartctl the command cannot find"

#        exit $STATE_UNKNOWN

#fi

# Plugin parameters value if not define

# 定義預設的檢測硬碟

CHECK_DISK="/dev/sda"                  

# Plugin variable description

# 插件描述資訊

PROGNAME=$(basename $0)

RELEASE="Revision 1.2.0"

AUTHOR="(c) 2009 Ajian ([email protected])"

# Functions plugin usage

# 插件的使用方法函數

print_release() {

    echo "$RELEASE $AUTHOR"

}                          

print_usage() {

        echo ""

        echo "$PROGNAME $RELEASE - Disk health check script for Nagios"

        echo "Usage: check_disk_health.sh -d /dev/sdb"

        echo "  -d  the disk (/dev/sda) "

        echo "          not the Hard disk partition(sda2 is wrong)"

        echo "  -v  check the version"

        echo "  -h  Show this page"

    echo "Usage: $PROGNAME"

    echo "Usage: $PROGNAME --help"

    echo ""

    exit 0

}                                                                                                          

print_help() {

        print_usage

        echo "This plugin will check disk health  "

        exit 0

}                                                  

# Parse parameters

# 傳遞參數

while [ $# -gt 0 ]; do

    case "$1" in

        -h | --help)

            print_help

            exit $STATE_OK

            ;;

        -v | --version)

                print_release

                exit $STATE_OK

                ;;

        -d | --disk)

                shift

                CHECK_DISK=$1

                #判斷磁盤是否存在

                if [ ! -b $CHECK_DISK ];then

                        echo "$CHECK_DISK is no exsit,Please change it "

                        exit $STATE_CRITICAL

                fi

        *)  echo "Unknown argument: $1"

            print_usage

            exit $STATE_UNKNOWN

        esac

shift

done

#根據不同的操作進行不同的操作,這裡暫時隻支援Linux

case `uname` in

        Linux )

             #最核心的部分 前面都是些腳本的基本功能 一個架構 因為第一個腳本牽扯到了很多東西,雖然功能很簡單,

             #但折騰了我不少,在後面的分析中會具體說到 總之注意sudo用法 腳本一開始就有說哦

                DISK_HEALTH=`$SMARTCTL  -H $CHECK_DISK | tail -1 | cut -d: -f2- `

                #DISK_HEALTH="OK"

        #       DISK_INFO=`/usr/bin/sudo $SMARTCTL -i $CHECK_DISK | grep "Device:"`

                if [ "$DISK_HEALTH" = " OK" ]|| [  "$DISK_HEALTH" = " PASSED" ];then

                        echo "OK - $CHECK_DISK status is $DISK_HEALTH "

                        #echo "OK - $CHECK_DISK status is $DISK_HEALTH | $DISK_INFO"

                        exit $STATE_OK

                else

                        echo "CRITICAL - $CHECK_DISK status is $DISK_HEALTH "

                        #echo "CRITICAL - $CHECK_DISK status is $DISK_HEALTH | $DISK_INFO"

        fi

        *)              echo "UNKNOWN: `uname` not yet supported by this plugin. Coming soon !"

                        exit $STATE_UNKNOWN

4)運作腳本

(注意:在最開始自己寫的腳本是沒有sudo的,以上腳本是已經調試過後的,還需要配置一些其它的東西,慢慢看吧)

給與腳本執行權限,手動執行

# ./check_disk_health.sh

OK – /dev/sda status is  OK

結果正确了,其實這個時候,高興得太早了。 我先不說問題、繼續正常的一般流程。

5、配置Nagios 調用插件

1)在遠端NRPE 被監控伺服器上修改nrpe.conf

# vim /usr/local/nagios/etc/nrpe.cfg

添加 command[check_sda_health]=/usr/local/nagios/libexec/check_disk_health.sh -d /dev/sda

(注意這裡了,先提醒下,這裡是錯誤的,一般是正确的,是這個腳本的特殊性造成的)

2)在Nagios 監控伺服器上添加一些配置

定義服務

define service{

use                             Disk-Health

host_name                       DB-56

servicegroups                   Disk-Health

service_description            check sda disk health

contact_groups                  admins

check_command               check_nrpe!check_sda_health

}

如果像上面定義一個服務 那麼就要注意相關的定義了 ,

定義Disk-Health 模版  把硬碟檢測定義一個模版會比較好控制,因為硬碟的檢測不像其它服務一樣需要準确的及時性反正檢測得太多可能會造成壓力,一般一天檢測幾次就夠了。

定義DB-56 主機需要定義

定義組 admins

以上這些隻要安裝過nagios 一般都知道的了 隻是強調下模版的單獨定義

3)通過WEB控制檢測 檢視結果

結果是失敗 報警CRITCTL 但是狀态裡面的資訊都是空的  CRITCTL – /dev/sda status is

6、調試

從Nagios的遠端監控來看是失敗的,并且沒有擷取到任務有用的資訊。

分析可以看到,說明nrpe調用  這個變量擷取到的是為空的資訊

DISK_HEALTH=`$SMARTCTL -H $CHECK_DISK | tail -1 | cut -d: -f2- `

即是空的 隻有一個原因,肯定是沒有執行 如果執行了 肯定會有字段 不管這個字段是否相符。

但是手動執行是沒有問題。

經過對smartctl的檢視 原來這個指令是隻允許root進行調用的。

現在需要解決的問題是:非root 使用者 如何遠端調用含有需要有root權限指令的腳本進行監控。

(不要小看這一句話,每一個詞都是一個需要攻克的地方)

以下是調試步驟:

1)非root使用者

NRPE插件是用nagios這個使用者來執行的 是以要得到真實的情況需要

A: su nagios   再執行腳本 (這個方法比較好)

B: sudo -u nagios ./check_disk_health.sh

結果:

sudo -u nagios ./check_disk_health.sh

CRITICAL – /dev/sda status is

跟遠端的結果是一樣的了 沒有資訊

2)需要有root權限

需要root權限隻有一個辦法就是用sudo

将DISK_HEALTH=`$SMARTCTL -H $CHECK_DISK | tail -1 | cut -d: -f2- `

改為DISK_HEALTH=`/usr/bin/sudo $SMARTCTL -H $CHECK_DISK | tail -1 | cut -d: -f2- `

(最後發現這時加sudo 并不是關鍵 關鍵是很行腳本時用sudo )

結果:sudo -u nagios ./check_disk_health.sh

Password:

需要輸入密碼  sudo不用輸入密碼的方法

修改sudo配置檔案

執行 visudo

添加

nagios ALL=(ALL) NOPASSWD:/usr/local/nagios/libexec/check_disk_health.sh

建議:最好進行sudo的一些控制,很多網方法就是nagios ALL=NOPASSWD:ALL

結果:

su nagios

/usr/bin/sudo check_disk_health.sh

OK – /dev/sda status is OK

那麼在nrpe.conf配置檔案中需要添加sudo

command[check_sda_health]=/usr/bin/sudo /usr/local/nagios/libexec/check_disk_health.sh

最開始那個是錯誤的 注意啊 這個是需要添加/usr/bin/sudo 就是說隻要腳本中涉及到提升到root權限的指令那麼就要用這個

3)遠端調用

遠端調用方法:./check_nrpe -H 192.168.0.56 -c check_sda_health

同上如果想模拟真實環境請切換到相應的執行使用者 su nagios 再執行以上操作

結果:   

這個錯誤的原因一定要明白,之是以報這個錯意思是說NRPE沒有擷取到任何資訊,也說是寫腳本之前說的其中第二條規範

問題:在沒有任何資訊的情況下怎麼來擷取NRPE執行的日志呢

就是要确定問題在哪,經過一大番的查找眼睛偶爾看到一個有趣的小方法

修複nrpe.conf配置檔案 在要檢查的指令後面添加>>/tmp/output 2>&1 将錯誤導出到檔案中進行檢視

command[check_sda_health]=/usr/bin/sudo /usr/local/nagios/libexec/check_disk_health.sh -d /dev/sda >>/tmp/output 2>&1

重記nrpe服務

遠端調用 結果當然還是NRPE: Unable to read output

檢視/tmp/output

sudo: sorry, you must have a tty to run sudo

有錯誤就簡單了  原來這個是預設不允許sudo 在後端進行

visudo

注釋Defaults requiretty 就OK了

結果通過WEB檢視也正确了。

(注意:注釋後 檢測仍然會是Unable 不過看/tmp/output就會有正确的結果,是以有正确的結果後,一定要去掉 >>/tmp/outpt 2>&1 資訊都導到檔案中了 nagios還是得不到任何消息。)

一個腳本執行成功後,就是大批量應用,用生産環境驗證,出現問題繼續調試。

以上為所有的分析調試方法。如果你看到最後一步了,說明你很有耐心,你也一定會成功的,至于寫得好與壞、對與錯請盡管說,這不會影響你的成功。呵呵

今天在搞nagios 的event handler時調試了半天沒有結果,把我郁悶的,最後發現是在visudo裡沒有注釋Defaults requiretty  

注釋後使用 check_nrpe -H 127.0.0.1 -c restart_nginx 指令可以正常工作

restartnginx.sh 内容如下

#*******************************

#Author sky

#20120206

/usr/bin/sudo /usr/local/nginx/sbin/nginx -s stop

/usr/bin/sudo /usr/local/nginx/sbin/nginx

printf "DONE!"

#*********************************

原先還有“NRPE: Unable to read output”錯誤,在腳本加一行’ printf "DONE!" ‘就可以了

特此備忘一下

明天再繼續搞