ZabbixでAWS/CloudWatchの値を取得してみた

ZABBIX
93件のシェア(ちょっぴり話題の記事)

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

CloudWatchの値をZabbix側でも見られるようにしたので、その手順を共有します。

CloudWatchの値をZabbixで取りたい理由

Zabbixでは最初から非常に多くの項目を監視できるのですが、AWS等のクラウドを利用していると、必要だけど監視できない項目が出てきます。RDSやELB等のフルマネッジドサービスのリソース状況はもちろんのこと、EC2のCPU使用率といった一見Zabbixで監視できそうなリソースも、実は正確な値は取れていません

一方、CloudWatchはEC2内部の情報、例えばロードアベレージやプロセスの監視はできません。また、データの保持期間が14日間なので古い情報は見られません。

そこで、CloudWatchの情報をZabbixに貯めるようにすれば、、両方を一元的に管理できるし、情報の保持期間も好きなように設定できるようになります。

Zabbixの外部チェック機能

Zabbixには自作のスクリプトを利用して、監視を行う方法があります。外部チェックと呼ばれるものです。

CloudWatchにもAPIとそれを利用するSDKも用意されているので、CloudWatchから値を取得するスクリプトを作成し、Zabbixから値を参照できるようにしてみました。

事前準備

まず、Zabbixサーバを用意します。サーバの構築方法はこちらの記事を参考にしてください。

ただ、今回ZabbixサーバからCloudWatchのAPIを利用するので、「CloudWatch Read Only Access」権限のあるIAM roleをもったインスタンスにしてください。IAM roleについてはこちらをご覧ください。

また、AWS SDK for Rubyも使うのでインストールしてください。下記の要領でできます。

[root@zabbix-server]# yum install rubygems rubygem-aws-sdk.noarch

下記コマンドを実行して、エラーが出なかったら、roleの設定もSDKのインストールも正常にできています。

[ec2-user@zabbix-server]$ ruby -e "require 'rubygems';require 'aws-sdk';AWS::CloudWatch.new.client.describe_alarms"

外部チェック設定

スクリプトを利用した監視アイテムの設定方法

Zabbixのアイテム登録画面で「タイプ:外部チェック」を選択することで、独自のスクリプトを利用できるようになります。スクリプトファイル名やスクリプトに与える引数は「キー」欄で指定します。

スクリーンショット 2013-11-07 17.11.55

scriptname["params01","params02"]
という風に指定すると、

[zabbix@zabbix-server]$ /path/to/externalscripts/scriptname params01 params02 

がZabbixサーバ上でZabbixユーザによって実行され、返り値が監視結果としてZabbixに登録されます。

スクリプトの設置

スクリプトの設置場所は、Zabbixサーバの設定ファイルで指定してください。ExternalScriptsという設定項目です。

[root@zabbix-server01 ~]# grep ExternalScripts /etc/zabbix/zabbix_server.conf 
### Option: ExternalScripts
# ExternalScripts=${datadir}/zabbix/externalscripts
ExternalScripts=/usr/lib/zabbix/externalscripts

デフォルトで/usr/lib/zabbix/externalscriptsになっていたので、このディレクトリ以下にスクリプトを設置します。

例えば、以下のようなスクリプトでCloudWatchのデータが取得できます。
/usr/lib/zabbix/externalscripts/cloud_watch

#!/usr/bin/ruby

require 'rubygems'
require 'aws-sdk'
require 'optparse'

params = ARGV.getopts(
  "",
  "region:",
  "service:",
  "metric:",
  "dimension_name:",
  "dimension_value:",
  "statistics:"
)

AWS.config({
  :cloud_watch_endpoint => "monitoring.#{params['region']}.amazonaws.com",
})

metric = AWS::CloudWatch::Metric.new(
  "AWS/#{params['service']}",
   params['metric'],
   :dimensions => [{
     :name => params['dimension_name'],
     :value => params['dimension_value']
   }]
)

stats = metric.statistics(
  :start_time => Time.now - 300,
  :end_time => Time.now,
  :statistics => params['statistics']
)

last_stats = stats.sort_by{|stat| stat[:timestamp]}.last

exit if last_stats.nil?

puts last_stats[params['statistics'].downcase.to_sym]

このスクリプトは引数として

  • リージョン(例:ap-northeast-1)
  • AWSサービス(例:RDS)
  • メトリクス名(例:CPUUtilization)
  • ディメンジョン名(例:DBInstanceIdentifier)
  • ディメンジョン値(例:test-rds01)
  • 値の算出方法(例:Average)

を取り、次のように使います。

[root@zabbix-server01 ~]# chmod a+x /usr/lib/zabbix/externalscripts/cloud_watch
[root@zabbix-server01 ~]# sudo -u zabbix /usr/lib/zabbix/externalscripts/cloud_watch --region ap-northeast-1 --service RDS --metric CPUUtilization --dimension_name DBInstanceIdentifier --dimension_value test-rds01 --statistics Average
18.33

これで、test-rds01の直近のCPU使用率が取得できます。

使用可能なメトリクス、ディメンジョンの一覧はこちらをご覧ください。

Zabbix設定

では、このスクリプトを使った、Zabbixの設定をしましょう。

ホストの作成

まず、監視対象のRDSインスタンスのホスト設定を行います。
「設定」➡「ホスト」➡「ホストの作成」から、ホスト作成画面を開きます。
「ホスト名」のRDSのDB Instane Identifierの値を入れてください。

AWSのコンソールで確認すると

スクリーンショット 2013-11-07 14.30.24

DB Instane Identifierはtest-rds01なので

スクリーンショット 2013-11-07 14.37.00

Zabbix側のホスト名もtest-rds01にします。グループにはそのホストが所属するグループを指定してください。他の項目は設定しないでも大丈夫です。

アイテムの作成

次にアイテムの設定を行います。「設定」➡「ホスト」➡test-rds01の行にある「アイテム」リンク➡「アイテムの作成」から、アイテム作成画面を開きます。

  • 名前:CPU使用率
  • タイプ:外部チェック
  • キー:cloud_watch["--metric","CPUUtilization","--dimension_name","DBInstanceIdentifier","--dimension_value","{HOST.NAME}","--statistics","Average","--service","RDS","--region","ap-northeast-1"]
  • データ型:数値(浮動小数)
  • 単位:%
  • 更新間隔(秒):60

と入力してください。

キーの入力値に「{HOST.NAME}」という部分がありますが、これはZabbixのマクロでスクリプト実行時にホスト名に置き換えられます。今回の例だと、「test-rds01」に置き換えられます。
また、CloudWatchの監視間隔が60秒なので、Zabbixの更新間隔も60秒にしています。

スクリーンショット 2013-11-07 15.05.07

監視結果

アイテム一覧が面に右側にある「ステータス」が「有効」で「エラー」が無ければ、正常に値が取れています。

スクリーンショット 2013-11-07 15.10.10

もし、エラーが出た場合はZabbixサーバ上のログ、/var/log/zabbix/zabbix_server.logの内容を確認し、対応してください。

他のメトリクスも「"--metric","CPUUtilization"」の部分を変更したアイテムを作成することで取得できます。RDSで取得可能はメトリクスはこちらを参照ください。

正常であれば、「監視データ」➡「最新データ」で以下のようにRDSの各メトリクスが見られます。

スクリーンショット 2013-11-07 16.14.41

Zabbixテンプレート

RDSの設定をテンプレート化したものを共有します。手動で設定するのが手間な場合はこちらをご利用ください。
(テンプレートとはアイテムやその他の設定をまとめて保存し、多くのホストで使い回せるようにする仕組みです。)

Zabbixテンプレート

利用するには、上記リンクからzbx_RDS_template.xmlをダウンロードし、Zabbixの「設定」➡「テンプレート」➡「インポート」画面からテンプレートをインポートしてください。グラフ、スクリーンの設定もしてあるので、それぞれの横のチェックボックスにチェックを入れてください。

スクリーンショット 2013-11-07 16.54.21

インポートが成功すると、テンプレート一覧に「Template AWS RDS」が現れるので、テンプレート名のリンクから設定画面に移動し、「ホスト/テンプレート」に監視したいRDSのホストを追加してください。

スクリーンショット 2013-11-07 16.58.18

これで、追加したホストに監視設定が適用されます。

スクリーンの設定により、「監視データ」➡「最新データ」で表示されるホスト名を左クリックしたときに現れる「ホストスクリーン」をクリックするとグラフ一覧が見られます。

スクリーンショット 2013-11-07 17.03.09 スクリーンショット 2013-11-07 17.05.36

いかがだったでしょうか。今回はRDSを例に挙げましたが、同様のやり方でCloudWatchで監視できるものは何でもZabbixに登録できるので、RDSを利用してない方もぜひ試してみてください。

AWS Cloud Roadshow 2017 福岡

  • 高志 佐井

    2015/1/21現在の最新のEC2で動作確認したのですが、2点はまりましたので内容記載します。

    ①パスについて
     zabbixをデフォルトインストールした場合、zabbixユーザーの.bash_profileが無いため
     Rubyの実行エラーになりました。
     /etc/passwd
     でホームディレクトリを設定し、.bash_profileを作成しパスを設定することで解決しました。

    ②/usr/lib/zabbix/externalscripts/cloud_watchのスクリプトについて
     現在文法が変わっているようです。
     33行目の :statistics の渡し方を配列で渡す必要がありました。
     :statistics => params[‘statistics’]

     :statistics => [ params[‘statistics’] ]

     と書き換えて解決しました。

  • もるすぁ

    > ②/usr/lib/zabbix/externalscripts/cloud_watchのスクリプトについて現在文法が変わっているようです。
    > 33行目の :statistics の渡し方を配列で渡す必要がありました。

    まさしく同じところで嵌りました…。
    既にaws-sdk自体v2になっているので、もう本記事自体更新されることはないかもしれませんが、
    嵌っている方いらっしゃったら、本記事一番下の高志様のコメント参照されるとよいです。
    ※自分は下まで読まずに嵌ったので、できれば注釈いれて頂きたいところですがw

    また、2016/11/20時点ですと、上述の通り、aws-sdk自体v2になっているので、本記事のサンプルコードを流用される方は、
    “`
    gem install aws-sdk -v ‘~>1’
    “`
    でaws-sdk-v1をインストールし、require ‘aws-sdk-v1’で明示的にv1を指定してあげてください。