Adways Advent Calendar 2017 8日目の記事です。
http://blog.engineer.adways.net/entry/advent_calendar_2017
こんにちは、アドウェイズの天津です。商用インフラ全般を担当しています。
今回はオンプレ基盤で使用しているVMware vSphere でのvMotionをSlackに通知させた事例を書きます。
なぜSlack通知が必要だったか
弊社ではvSphereでESXi複数台でクラスタを組んでおり、DRSによる負荷平準化を設定しています。
DRSによるvMotionは自動で実施されるのですが、大きめの仮想マシンの場合、vMotion時に静止時間が長く、アプリケーションに影響が出ることがあります。
アプリケーションでエラーが発生し、原因切り分けを行う際に毎回vMotion履歴をvCenterにログインして確認としていましたが社外にいる場合もあるためリアルタイムSlack通知を実装しました。
構成
VMware vCenter Server からvMotionをSNMPトラップで流し、受信サーバで整形してSlackに通知する構成です。
Slack通知のために必要なこと
- SNMPトラップ受信サーバの設定
- vCenter ServerでのSNMPトラップ送信設定
- vCenter ServerでのvMotionイベントの通知設定
- SNMPトラップのSlack通知スクリプトの作成
それでは説明していきますね。vSphere 5.5での設定となります。
SNMPトラップ受信サーバの設定
まずはvCenterServerと通信できるネットワーク内にSNMPトラップを受信するサーバを建てましょう。
詳しい説明は割愛しますが、net-snmpのインストールと設定で動作すると思います。
vSphereのMIBファイル(こちらから ダウンロード できます)も忘れずに設置してください。
https://code.vmware.com/web/sdk/55/vsphere-management
vCenter ServerでのSNMPトラップ送信設定
vCenterの「管理」 - 「設定」 - 「全般」 - 「SNMPレシーバー」にIPアドレス、ポート番号、コミュニティストリングを設定します。
イベントが発生した場合、SNMPトラップ受信サーバに送信されるようになりますので、ログを確認してみて下さい。
vCenter ServerでのvMotionイベントの通知設定
ここが今回のポイントです。
vCenter ServerにてvMotionイベントを通知するようにアラーム定義を設定していきます。
アラーム定義は「状態変化」に対して通知が可能となっているため、状態変化を定義する必要があります。
今回は全仮想マシンの通知とするためvCenter Server のアラーム定義を設定します。
vMotionイベントにはDRSによるものと手動によるものがありますので2つとも設定します。
DRSの通知
「管理」-> 「アラーム定義」より新規作成します。(緑の+ボタンで作成)
- 1 全般
- アラーム名:任意
- 説明:任意
- 監視対象:仮想マシン
- 監視内容:「仮想マシンのパワーオンなど、このオブジェクトで起きる特定のイベント」を選択
- このアラームを有効にする:オン
- 2 トリガー
トリガーとなるイベントと条件を下記のとおり設定しましよう。
状態変化を定義するのはこの項目です。 「開始」を警告として設定し、「完了」を正常とするのがポイントです。
DRSを検知するためユーザ作業を除く条件もつけておきます。
- 3 アクション
アクションで「警告」から「正常」に状態変化したタイミングに対してsnmptrap通知を設定します。
手動vMotionの通知
DRSのものとトリガーのみ異なります。
確認
手動でvMotionを実行してみましょう。
うまく設定されていれば SNMPトラップ受信サーバの ログに下記のようなメッセージが書き込まれます。
(下記はrsyslogdによるログ書き込みのため、改行コードが8進数(#011、#012)に変換されています
Dec 4 18:46:47 snmptrapd-001 snmptrapd[53668]: 2017-12-04 18:46:47 192.168.200.8(via UDP: [192.168.0.1]:52727->[192.168.0.2]) TRAP, SNMP v1, community public#012#011VMWARE-PRODUCTS-MIB::vmwVC Enterprise Specific Trap (VMWARE-VC-EVENT-MIB::vpxdAlarmInfo) Uptime: 11 days, 23:38:59.22#012#011VMWARE-VC-EVENT-MIB::vmwVpxdTargetObjType.0 = INTEGER: vm(3)#011VMWARE-VC-EVENT-MIB::vmwVpxdOldStatus.0 = STRING: 赤#011VMWARE-VC-EVENT-MIB::vmwVpxdNewStatus.0 = STRING: 緑#011VMWARE-VC-EVENT-MIB::vmwVpxdObjValue.0 = STRING: vMotion_Notif - イベント: 仮想マシンが移行されました (7260303)#012サマリ: 仮想マシン amatsu-test-001 が ESXi-A、Storage-A から ESXi-B、Storage-A に移行されました#012日付: 2017/12/04 9:46:46#012ユーザー名: ADWAYS.NET\amatsu_satoshi#012仮想マシン: amatsu-test-001#012ホスト: ESXi-A#012リソース プール: Test-Cluster#012データストア: Storage-A#012データセンター: Test-Datacenter#012引数:#012 sourceDatacenter.name = Test-Datacenter#012 sourceDatastore.name = Storage-A#012 sourceHost.name = ESXi-B#012#011VMWARE-VC-EVENT-MIB::vmwVpxdTargetObj.0 = STRING: amatsu-test-001
改行変換処理したものが下記です。(#011をタブに、#012を改行に置き換えています)
Dec 4 18:46:47 snmptrapd-001 snmptrapd[53668]: 2017-12-04 18:46:47 192.168.200.8(via UDP: [192.168.0.1]:52727->[192.168.0.2]) TRAP, SNMP v1, community public VMWARE-PRODUCTS-MIB::vmwVC Enterprise Specific Trap (VMWARE-VC-EVENT-MIB::vpxdAlarmInfo) Uptime: 11 days, 23:38:59.22 VMWARE-VC-EVENT-MIB::vmwVpxdTargetObjType.0 = INTEGER: vm(3) VMWARE-VC-EVENT-MIB::vmwVpxdOldStatus.0 = STRING: 赤 VMWARE-VC-EVENT-MIB::vmwVpxdNewStatus.0 = STRING: 緑 VMWARE-VC-EVENT-MIB::vmwVpxdObjValue.0 = STRING: vMotion_Notif - イベント: 仮想マシンが移行されました (7260303) サマリ: 仮想マシン amatsu-test-001 が ESXi-A、Storage-A から ESXi-B、Storage-A に移行されました 日付: 2017/12/04 9:46:46 ユーザー名: ADWAYS.NET\amatsu_satoshi 仮想マシン: amatsu-test-001 ホスト: ESXi-A リソース プール: Test-Cluster データストア: Storage-A データセンター: Test-Datacenter 引数: sourceDatacenter.name = Test-Datacenter sourceDatastore.name = Storage-A sourceHost.name = ESXi-B VMWARE-VC-EVENT-MIB::vmwVpxdTargetObj.0 = STRING: amatsu-test-001
SNMPトラップのSlack通知スクリプトの作成
上記の通知内容を整形して通知します。今回はbashで書きました。「OID」と「サマリ」が含まれる行を処理しています。
弊社ではSlack通知に cubicdaiya さんのslackboard https://github.com/cubicdaiya/slackboard を使用して送信していますが、curlで直接Slackに送信してもいいと思います。
#!/bin/bash Temp_trap="/tmp/temp_trap.log" CHANNEL="amatsu-vminfo" SLACKBOARD="192.168.0.101:29800" echo -n > $Temp_trap while read LINE; do echo $LINE >> $Temp_trap done # OIDの取得 OID=`head -4 $Temp_trap | tail -1 | cut -f2 -d " "` ##### VMware vCenter Event MIB Trap ##### case $OID in *VMWARE-VC-EVENT-MIB* | *VMWARE-PRODUCTS-MIB* ) if grep "DRSvMotion_Notif" $Temp_trap > /dev/null ; then # DRS Message=`grep サマリ $Temp_trap | sed 's/、/ /g' |awk '{printf("vMotion(DRS): \`%s\` : %s -> %s (%s)", $4, $6, $12, $10)}'` elif grep "vMotion_Notif" $Temp_trap > /dev/null ; then # operation Message=`grep サマリ $Temp_trap | sed 's/、/ /g' |awk '{printf("vMotion(ope): \`%s\` : %s -> %s ( %s -> %s)", $3, $5, $8, $6, $9)}'` fi if [[ ! -z ${Message} ]]; then # send Slack echo -e "${Message}" | /usr/local/bin/slackboard-cli -s ${SLACKBOARD} -c ${CHANNEL} > /dev/null & fi ;; esac exit 0
通知スクリプトの設定
作成したスクリプトをSNMPトラップ受信時のハンドルとして登録します。
動作確認
手動でvMotionしてみましょう。 下記のようにSlackに通知が実行されるはずです。
これでいつでもどこにいてもvMotionがリアルタイムで把握できますね。
終わりに
今回、SNMPトラップをトリガーにしてSlackにvMotionを通知しましたが、任意のスクリプトを動かすことができるため、vMotionの前後に動かしたいスクリプトがあれば仕込むことができます。
vMotionに影響を受けるアプリケーションやミドルウェアがある場合、事前作業の自動化や回復処理の自動化ができそうですね。
最後までお読みいただきありがとうございました。