AWSのAuto-Scalingって、とってもクラウドらしくて聞こえもよく便利なんですが、
本気で導入しようとすると、結構細かい考慮が必要だったりします。
そのひとつが、監視対象をどうやってコントロールするか? です。
本記事では、zabbixを使って監視を行う構成を例に、その構成方法を解説したいと思います。
1.そもそもAuto-Scalingとは?
ざっくりですが、Auto-Scaingのおさらい。
Auto-Scalingは、大きく3つのコンポーネントから構成されています。
コンポーネント | 設定内容(超ざっくり) |
---|---|
Launch-configuration | 起動するAMI-IDやインスタンスタイプを指定 |
Auto-Scaling-group | 起動するAZ指定、max、min台数の指定 |
Auto-Scaling-policy | スケール時に何台ずつ拡張・縮退するかの指定 |
この3つのコンポーネントを定義しておき、CloudwatchでAuto-Scaling-groupの負荷状態を監視します。
Cloudwathは、定義した敷居値を超えると"アラーム"が発生するので、これをトリガーにAuto-Scaling-actionを発動し、
定義した内容の通りにインスタンスを増減させる仕組みです。
例えば、こんな具合です。
CPU使用率90超が2分間続いたらアラームを発生させ、インスタンスを1台ずつ増やす。
CPU使用率10%以下が10分間続いたらアラームを発生させ、1台ずつインスタンスを削除する。
ここで大切なのは、
Auto-Scalingで起動してくるインスタンスは、ど新規インスタンスである
ということと、
Auto-Scalingで削除されるインスタンスは、stopではなく、terminateされる
ということです。
つまり、予め準備しておいたインスタンスを起動・停止するわけではないので、
IPアドレスやホスト名は都度変わってしまうことになります(AWSの仕様)。
2.監視対象へ自動登録・削除するには?
ではどうするか?
スケールアウト時には自動で監視対象に登録する
処理と、
スケールイン時は、自動で監視対象から削除する
処理が必要になってきます。
zabbixはAPIが公開されているので、上記処理をスクリプトで書いておき、
インスタンス起動時(削除時)に自動的に実行するように仕込んでおけばOKです。
3.ホスト登録・削除スクリプト
zabbixには色々なAPIが存在していますが、ここでは純粋なzabbix-APIを利用して登録します。
zabbix-APIは、JSONを引数にしてメソッドやパラメーターを指定してhttpリクエストを投げる方式で処理を行っていきます。
イチからJSONをパースする処理を書くのは面倒なので、今回はpythonを使用してスクリプトを書いています。
...さて、やっと本題です。
zabbixのホストに登録するには以下の値が必要になります。
auth-id : 認証情報です
hostgroup-id : どのホストグループに登録するか?
template-id : どんな監視項目(Template)を割り当てるか?
なので、まずはこれらの値を取得してから登録処理を行います。
# coding=utf-8
import json
import urllib2
import socket
# based url and required header
url = "http://xxx.xxx.xxx.xxx/zabbix/api_jsonrpc.php"
header = {"Content-Type":"application/json"}
############### まずは認証し、認証idを取得します(以降の処理で必要) ###############
data = json.dumps(
{
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"user": "Admin", # initial-param
"password": "zabbix" # initial-param
},
"id": 0
})
# create request object
request = urllib2.Request(url,data)
for key in header:
request.add_header(key,header[key])
# auth and get authid
result = urllib2.urlopen(request)
response = json.loads(result.read())
result.close()
authid = response['result']
############### host登録に必要な値①:gropu-idを取得します ###############
data = json.dumps(
{
"jsonrpc": "2.0",
"method": "hostgroup.get",
"params": {
"output": "extend",
"filter": {
"name":[ "XXXXXXXXXXX" ]
}
},
"auth": authid,
"id": 1
})
# create request object
request = urllib2.Request(url,data)
for key in header:
request.add_header(key,header[key])
# get hostgroup-id
result = urllib2.urlopen(request)
response = json.loads(result.read())
result.close()
for gid in response['result']:
# set hostgrup-id
targetGroupid = gid['groupid']
############### host登録に必要な値②:template-idを取得します ###############
data = json.dumps(
{
"jsonrpc": "2.0",
"method": "template.get",
"params": {
"output": "extend",
"filter": {
"host":[ "XXXXXXXXXXX" ]
}
},
"auth": authid,
"id": 1
})
# create request object
request = urllib2.Request(url,data)
for key in header:
request.add_header(key,header[key])
# get template-id
result = urllib2.urlopen(request)
response = json.loads(result.read())
result.close()
for gid in response['result']:
# set template-id
targetTemplateId = gid['templateid']
############### 取得した値を基にhost登録 ###############
data = json.dumps(
{
"jsonrpc": "2.0",
"method": "host.create",
"params": {
"host": "XXXXXXXXXXX",
"interfaces": [{
"type": 1,
"main": 1,
"useip": 1,
"ip": "xxx.xxx.xxx.xxx",
"dns": "",
"port": "999"}],
"groups": [{
"groupid": targetGroupid
}],
"templates":[{
"templateid": targetTemplateId
}]
},
"auth": authid,
"id": 1
})
# create request object
request = urllib2.Request(url,data)
for key in header:
request.add_header(key,header[key])
# create host
result = urllib2.urlopen(request)
response = json.loads(result.read())
result.close()
for hid in response['result']['hostids']:
print "create host successful. host-id is " + hid
また、削除時には以下の値が必要になります。
登録時と同じように、まずはhost-idを取得し、取得したhost-idをキーに削除処理を行います。
host-id : 削除対象のホストキー
ソースコードは省略しますが、
登録時と同じように、認証 → host-id取得 → delete
という流れになります。
4.自動起動・削除の設定(Linux)
最後に、作ったスクリプトをサービスとして登録し、
インスタンスの起動時・シャットダウン時に自動実行するように設定してあげます。
これは普通にLinuxのService登録をしてあげるだけす。
etc/init.d
配下にserviceコマンド用のスクリプトを配置し、chkconfig --add xxxx
でサービス登録します。
サービス登録用のスクリプトはこんな感じです。
このスクリプトから、先ほどのホスト登録スクリプトや削除スクリプトを呼んでいます。
# !/bin/sh
# chkconfig: 2345 99 06
# description: regist or delete zabbix-managed-host-list.
servicename='manage-zabbix-host'
lock_file="/var/lock/subsys/${servicename}"
start() {
python /path/01_regist_host.py
touch ${lock_file}
echo "manage-zabbix-host-list start:[OK]"
return 0
}
stop() {
python /path/02_delete_host.py
rm -f ${lock_file}
echo "manage-zabbix-host-list stop:[OK]"
return 0
}
case "$1" in
start)
start
;;
stop)
stop
;;
*) break ;;
esac
5.おわりに
基本的な考え方は上記の通りです。
なお、例外処理は色々あると思うのでそこは適宜追加してください。
また、今回は一連の流れをどかーっと書きましたが、認証処理などは共通化できると思うので、
そこは適宜作り替えてもらえればと思います。
※こうやってるよ、というのがあれば教えてください!!!
後日、これの動作確認くらいの情報は追記したいと考えています。。。