ZabbixでAWS/S3の保存量を取得する
はじめに
先日、S3の総保存量を計算するスクリプトについて、本ブログで紹介がありました
今回はそのスクリプトを利用し、ZabbixでS3の各バケット毎の保存量を監視する仕組みを作ってみました。
事前準備
AMIはAmazon Linux AMI 2014.03.1、Zabbixのバージョンは2.2.2です。
Zabbixのインストール方法に着いてはこちらを参照ください。(バージョンが2.0.9と古いです。登録するレポジトリを変更し、2.2系をインストールしてください。)
ZabbixサーバからS3のAPIを利用するので、「Amazon S3 Read Only Access」権限のあるIAM Roleを持ったインスタンスにしてください。IAM Roleについてはこちらを参照ください。
また、AWS SDK for Rubyも使うのでインストールしてください。下記の要領でできます。
$ sudo yum install rubygems rubygem20-aws-sdk.noarch
下記コマンドを実行して、エラーが出なかったら、roleの設定もSDKのインストールも正常にできています。
$ ruby -e "require 'rubygems';require 'aws-sdk';puts AWS::S3.new.buckets.count"
外部スクリプトの設置
S3の保存量を取得するため、Zabbixの外部チェックを利用します。 外部チェックは、Zabbixサーバがシェルスクリプトまたはバイナリを実行することによって実行するチェックです。
外部チェックで利用するスクリプトを設置します。
パラメータとして、バケット名と取得するデータの種別(バケット内のオブジェクトの総数、またはバケット内のオブジェクトサイズの合計)を渡します。 例えば、「shinsuke-test」という名前のバケット内のオブジェクトの総数を取得する場合は、下記のようなコマンドを実行します。
/usr/lib/zabbix/externalscripts/s3 --bucket_name shinsuke-test --mode count
設置するスクリプトの内容は以下になります。
/usr/lib/zabbix/externalscripts/s3
#!/usr/bin/ruby require 'rubygems' require 'aws-sdk' require 'optparse' params = ARGV.getopts( '', 'mode:', 'bucket_name:' ) s3 = AWS::S3.new bucket = s3.buckets[params['bucket_name']] exit unless s3.buckets.include? bucket case params['mode'] when 'count' puts bucket.objects.count when 'size' puts bucket.objects.inject(0){|total_size, object| total_size + object.content_length} end
Zabbixアイテムの設定
ホストを作成し、アイテム設定を行いましょう。
バケット「shinsuke-test01」内のオブジェクト総数を監視する場合は、以下のような設定を行います。
主な設定は下記の通りです。
名前 | Number of objects in $2 |
タイプ | 外部チェック |
キー | s3[--bucket_name, shinsuke-test01, --mode, count] |
データ型 | 数値(整数) |
アプリケーション | S3 |
バケット内のオブジェクトサイズの合計を取得する場合は、次のような設定になります。
名前 | Size of $2 |
タイプ | 外部チェック |
キー | s3[--bucket_name, shinsuke-test01, --mode, size] |
データ型 | 数値(整数) |
単位 | B |
アプリケーション | S3 |
最新データで監視結果を見てみましょう。
ちゃんと取れているようです。
ローレベルディスカバリによる自動アイテム登録
いま紹介したやり方だと、バケット毎にアイテムを作成する必要があります。それは面倒なので、Zabbixのローレベルディスカバリを利用し、自動でバケット毎のアイテムが作成されるようにしましょう。
ローレベルディスカバリについてはこちらの記事(【ZABBIX】やっぱりLLD(ローレベルディスカバリ)は最高だぜ!)が分かりやすいです。
「Template AWS S3」というテンプレートを作成し、ディスカバリルールを設定します。
主な設定項目は下記の通りです。
名前 | Bucket discovery |
タイプ | 外部チェック |
キー | discover_s3 |
キーに指定している「discover_s3」はS3のバケット一覧を返すスクリプトで、中身は以下の通りです。
/usr/lib/zabbix/externalscripts/discover_s3
#!/usr/bin/ruby require 'rubygems' require 'aws-sdk' require 'optparse' require 'json' discovery = {'data' => []} s3 = AWS::S3.new s3.buckets.each do |bucket| discovery['data'] << { '{#BUCKET_NAME}' => bucket.name, } end puts discovery.to_json
このスクリプトの実行結果は次のようになります。
[ec2-user@zabbix-server ~]$ /usr/lib/zabbix/externalscripts/discover_s3 | jq . { "data": [ { "{#BUCKET_NAME}": "shinsuke-test01" }, { "{#BUCKET_NAME}": "shinsuke-test02" } ] }
ローレベルディスカバリではこの結果を利用してアイテムのプロトタイプを作成することが出来ます。
オブジェクト総数を監視するプロトタイプは以下のようになります。
主な設定項目は下記の通りです。
名前 | Number of objects in {#BUCKET_NAME} |
タイプ | 外部チェック |
キー | s3[--bucket_name, {#BUCKET_NAME}, --mode, count] |
データ型 | 数値(整数) |
アプリケーション | S3 |
以前、直接指定していたバケット名の部分が「{#BUCKET_NAME}」に変わっただけで、他は同じです。
バケット内のオブジェクトサイズの合計も同様に設定します。
名前 | Size of {#BUCKET_NAME} |
タイプ | 外部チェック |
キー | s3[--bucket_name, {#BUCKET_NAME}, --mode, size] |
データ型 | 数値(整数) |
単位 | B |
アプリケーション | S3 |
これでテンプレートは出来たので、ホストを作成し、リンクさせましょう。
しばらくすると、アイテムが作成され、
監視結果も取れることが確認できました。
最後に
バケット内のオブジェクトサイズの合計からバケットの使用量を求めているため、オブジェクト数が増えると値取得に時間がかかります。
外部チェックのタイムアウトはデフォルトで3秒なので、最大値である30秒に変更しておきましょう。
$ sudo vim /etc/zabbix/zabbix_server.conf ### Option: Timeout # Specifies how long we wait for agent, SNMP device or external check (in seconds). # # Mandatory: no # Range: 1-30 # Default: # Timeout=3 Timeout=30
ただ、たとえ30秒に変更しても、オブジェクト数によってはタイムアウトにより値が取得できません。(c3.large上のZabbixの場合、2000オブジェクトを越えるとタイムアウトが発生しました。)
オブジェクト数が多い場合は、タイムアウトの無いZabbix Senderによる監視を検討した方が良いかもしれません。
今回作成した、S3用テンプレートです。手動で設定するのが手間な場合はこちらをご利用ください。