ZabbixでAWS/S3の保存量を取得する

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

はじめに

先日、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」内のオブジェクト総数を監視する場合は、以下のような設定を行います。

スクリーンショット 2014-05-16 11.14.40

主な設定は下記の通りです。

名前 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

最新データで監視結果を見てみましょう。

スクリーンショット 2014-05-16 11.31.48

ちゃんと取れているようです。

ローレベルディスカバリによる自動アイテム登録

いま紹介したやり方だと、バケット毎にアイテムを作成する必要があります。それは面倒なので、Zabbixのローレベルディスカバリを利用し、自動でバケット毎のアイテムが作成されるようにしましょう。

ローレベルディスカバリについてはこちらの記事(【ZABBIX】やっぱりLLD(ローレベルディスカバリ)は最高だぜ!)が分かりやすいです。

「Template AWS S3」というテンプレートを作成し、ディスカバリルールを設定します。

スクリーンショット 2014-05-16 11.49.07

主な設定項目は下記の通りです。

名前 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"
    }
  ]
}

ローレベルディスカバリではこの結果を利用してアイテムのプロトタイプを作成することが出来ます。

オブジェクト総数を監視するプロトタイプは以下のようになります。

スクリーンショット 2014-05-16 12.07.39

主な設定項目は下記の通りです。

名前 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

これでテンプレートは出来たので、ホストを作成し、リンクさせましょう。

スクリーンショット 2014-05-16 12.17.28

しばらくすると、アイテムが作成され、

スクリーンショット 2014-05-16 12.18.36

監視結果も取れることが確認できました。

スクリーンショット 2014-05-16 12.19.51

最後に

バケット内のオブジェクトサイズの合計からバケットの使用量を求めているため、オブジェクト数が増えると値取得に時間がかかります。

外部チェックのタイムアウトはデフォルトで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用テンプレートです。手動で設定するのが手間な場合はこちらをご利用ください。

Zabbixテンプレート