G1BS.0N

Tech Memo

Zabbixで他の機器からの通知メールを検知

| Comments

  1. .forwardでスクリプトに渡す
  2. RubyのMailライブラリでタイトルと本文を取得(mailalert.rb)
  3. 本文からホスト情報を取得し、該当ホストのトラッパーアイテムに内容を送信(mailalert.sh)

2と3のスクリプトは一つでやるべきなんでしょうけど、bashだとメールのパースが面倒、rubyだと改行が入るとzabbix_senderでうまく送れず・・・

~/.forward
1
2
"|/usr/bin/ruby /usr/lib/zabbix/alertscripts/mailalert.rb |/bin/sh
/usr/lib/zabbix/alertscripts/mailalert.sh"
mailalert.rb
1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/ruby

#受け取ったメールから、タイトルと本文を取得

require 'mail'

message = STDIN.read
mail = Mail.read_from_string(message)

puts "Subject: " + mail.subject
puts ""
puts mail.body.to_s
mailalert.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/sh

# タイトルと本文をzabbix_senderでトラッパーに送信

str=""

while read line; do
  str="$str\n$line"
done

host=`echo -e $str | awk '/Host/ {print $3}'` # メール本文からホスト情報
を取得

case $host in
  server1)     itemhost="server1" ;;    # どのホストに通知するかの定義
  server2)     itemhost="server2" ;;
  server3)     itemhost="server3" ;;
  *)               itemhost="zabbix-server" ;;      #未定義のものは
zabbix-server
esac

str=`echo -e $str`

/usr/bin/zabbix_sender -s "$itemhost" -z localhost -k mail_check -o "$str"

Zabbixの方はホストごとにmail_checkというZabbixトラッパーのアイテムを作成すれば、受信できます。
タイトルや本文の内容をもとにトリガーで通知できます。

ThinReportsでZabbixのレポートを作成

| Comments

Zabbixのスクリーン機能で、グラフの一覧表示なんかはできますが、 やっぱり提出用レポートとしては厳しいかと。

WordやExcelで毎回作るのもそれは手間だなーと思ってたら ThinReportsというものを知ったので、 これで自動でレポート作れるようにしてみました。

zabbix_report

表紙付きでいい感じにできました。

これはなかなかいいですね。

強いて言えば、出力がPDFなので、WordやExcelでできたら、細かいとこ修正できていいんですが・・・

CloudStackのドメインを変更する

| Comments

CloudStackで仮想マシンを立ち上げると、ドメイン名が「cs1cloud.internal」というドメインになります。

これを変えるには、WebUIのグローバル設定で「guest.domain.suffix」を変更すればいいはずなのですが、なんか変わりません。

ここにあるように、DBに直接変更しないと有効にならないみたいです。

UPDATE networks SET network_domain='cloud.mydomain.com' WHERE traffic_type='Guest';

あと、ここで指定したドメインは、仮想ルータのdnsmasqでは名前解決できないみたいなので、サブドメインにするとか、今使っているドメイン以外を指定したほうがいいみたいです。

Chef Server 11をインストール

| Comments

Chef Server を11.xにしようとしてハマったのでまとめておきます。

インストール手順は、このへん。

$ sudo yum install chef-server-11.0.6-1.el6.x86_64.rpm

それから

$ sudo chef-server-ctl reconfigure

失敗します。

Recipe: chef-server::bootstrap
  * execute[verify-system-status] action run
================================================================================
Error executing action `run` on resource 'execute[verify-system-status]'
================================================================================


Mixlib::ShellOut::ShellCommandFailed
------------------------------------
Expected process to exit with [0], but received '22'
---- Begin output of curl -sf http://localhost:8000/_status ----
STDOUT:
STDERR:
---- End output of curl -sf http://localhost:8000/_status ----
Ran curl -sf http://localhost:8000/_status returned 22


(中略)


[2013-03-14T14:53:27+09:00] ERROR: Running exception handlers
[2013-03-14T14:53:27+09:00] ERROR: Exception handlers complete
Chef Client failed. 110 resources updated
[2013-03-14T14:53:27+09:00] FATAL: Stacktrace dumped to /opt/chef-server/embedded/cookbooks/cache/chef-stacktrace.out
[2013-03-14T14:53:27+09:00] FATAL: Mixlib::ShellOut::ShellCommandFailed: execute[verify-system-status] (chef-server::bootstrap line 21) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '22'
---- Begin output of curl -sf http://localhost:8000/_status ----
STDOUT:
STDERR:
---- End output of curl -sf http://localhost:8000/_status ----
Ran curl -sf http://localhost:8000/_status returned 22

何度やっても同じです。 Ubuntu12.04でもCentOS6.3でも同じでした。

ここみると、DNSとかhostsとかが原因とありますが、どういじっても同じ結果・・・

原因はProxyでした。 curlがlocalhostもhttp_proxyが適用されてしまってたみたいです。

$ export no_proxy=localhost,127.0.0.1
  • /etc/profile.d/proxy.sh
1
export no_proxy=localhost,127.0.0.1

これで再挑戦

$ sudo chef-server-ctl reconfigure
(略)

Recipe: chef-server::erchef
  * service[erchef] action restart
    - restart service service[erchef]

Chef Client finished, 152 resources updated
chef-server Reconfigured!

成功しました!

でも・・・

$ sudo chef-server-ctl tail
==> /var/log/chef-server/nginx/error.log <==
2013/03/14 15:01:07 [emerg] 8903#0: bind() to 0.0.0.0:80 failed (98: Address already in use)

エラーが出てます。 chef11ではnginxを使うので、Apacheとボートがバッティングしてるようです。

chefのattributeを変更します。

  • /opt/chef-server/embedded/cookbooks/chef-server/attributes/default.rb
1
2
3
default['chef_server']['nginx']['ssl_port'] = 443
default['chef_server']['nginx']['enable_non_ssl'] = false
default['chef_server']['nginx']['non_ssl_port'] = 8880

とりあえずnon_ssl_portを80から変更してみました。 ssl_portも変更したりしてみましたが、うまく動きませんでした。 とりあえず、80番ポートは既存のApacheで、443はchef-serverのnginxで動かすことにしました。

再実行

$ sudo chef-server-ctl reconfigure
Recipe: chef-server::nginx
  * service[nginx] action restart
    - restart service service[nginx]

Chef Client finished, 5 resources updated
chef-server Reconfigured!

chef-server自信をclient登録します。

  • /etc/chef/client.rb
1
2
3
chef_server_url "https://chef-server IP"
http_proxy "http://Proxy IP:80"
https_proxy "http://Proxy IP:80"

validation.pemを配置

cp /etc/chef-server/chef-validator.pem /etc/chef/validation.pem

chef-clientを実行

# chef-client
Starting Chef Client, version 11.4.0
Creating a new client identity for helios.jkcloud.org using the validator key.
resolving cookbooks for run list: []
Synchronizing Cookbooks:
Compiling Cookbooks...
[2013-03-14T15:38:52+09:00] WARN: Node host.domain has an empty run list.
Converging 0 resources
Chef Client finished, 0 resources updated

Zabbix2.0でESXiのVMごとに監視してみる(自動登録編)

| Comments

前回のやつは、データは自動で取ってくるけど、Zabbixへのホスト登録は手動でやらないといけなかったので、いまいちでした。なので、ZabbixのAPIを使って、自動登録するように変更しました。また、1日データが取得できなかったら、Zabbixから削除するようにしました。

あと、登録したホストをマップに展開してホストスクリーンで各VMのステータスが確認できるようにしてみました。

Zabbix Map Zabbix HostScreen

コードはこんな感じです。

登録方法とかは前回と同じです。 ZabbixのURLを引数にしたので、vCenter登録時のマクロに

  - {$ZBX_URL} : http://xx.xx.xx.xx/zabbix

を追加してください。

CloudStackへのログインをLDAP認証する

| Comments

ClousStackのログインをLDAPにするには、APIからコマンドを実行しなければいけないようです。

APIのURL生成がかなりめんどくさいので、生成用のスクリプトを使わせてもらうことにします。
ここのスクリプトを使おうと思ったんですが、エンコード処理がうまくいかなかったので、 ここのを使わせてもらうことにしました。

まず、

my $site = "http://*.*.*.*/client/api?";

の”*”を自分のサイトのIPアドレスに変更しておきます。

使い方はこんな感じです。

generate-url.pl -f 3 -u (コマンド) -a (APIキー) -s (Secretキー)

コマンドの作り方は、Administrator Guideに書いてあります。

組み合わせるとこんな感じになります。

generate-url.pl -a (APIキー) -s (Secretキー) -f 3 -u "command=ldapConfig&port=389&queryfilter=%28%26%28uid%3D%25u%29%29&searchbase=dc%3Dexample%2Cdc%3Dcom&hostname=(LDAPサーバのIPアドレス)&response=json"

成功すると、こんな応答が返ってきます。

{
   "ldapconfigresponse" : {
      "ldapconfig" : {
         "queryfilter" : "(&(uid=%u))",
         "hostname" : "LDAPサーバのIPアドレス",
         "port" : "false",
         "searchbase" : "dc=example,dc=com"
      }
   }
}

あと、MD5 hashに関するバグがあるようで、 Cloudstack 3.x LDAP Authentication - Disabling MD5 hashの設定変更が必要になります。

/usr/share/cloud/management/webapps/client/scripts/sharedFunctions.js を

var md5HashedLogin = false;

に変更し、 CloudStackの再起動が必要になります。

service cloud-management restart

あらかじめローカルにユーザを作っておかないといけないようですし、LDAPサーバ障害時を考慮して、adminとか特定のユーザのみローカル認証にするとかもできないようです。

また、なんかトラブルの後、ログインできなくなることが多々あります。 その場合は、cloud-setup-managementコマンドを実行し、インストールし直すともとのローカル認証でログインできるようになります。(これが問題ないかどうかは分かりません・・・)

Ubuntu 12.04 では /etc/resolv.confが書き換えられる

| Comments

Ubuntu12.04ではresolvconfという仕組みを使うらしい

/etc/resolvconf/resolv.conf.d/配下のファイルと、/etc/network/interfacesのdns-nameservers と dns-search から動的に/etc/resolv.confが生成されるようです。

/etc/resolvconf/resolv.conf.d/base に書くのが一般的みたいですが、 それだと/etc/network/interfaces 「dns-nameservers」 が上に来て優先されるみたいです。

chefで一括管理することを考えると、/etc/network/interfacesにはどう書かれるか分からないので、/etc/resolvconf/resolv.conf.d/headに書く方がいいかもしれないです。

resolv.confに反映させるには、resolvconfサービスの再起動が必要です。

service resolvconf restart

Zabbix2.0でESXiのVMごとに監視してみる

| Comments

vSphere APIを使えば、ESXiだけじゃなくて、VMごとのCPU、メモリなんかのステータスも取得てきます。 取得した値をZabbixに食わせて、Zabbixで監視してみます。 VMwareのサイトにPerlのSDKがありますが、書き方が分かりにくかったので、 今回はRubyのRbVmomiを使ってみます。

RbVmomi

まずはインストール

1
gem install rbvmomi

使い方

1
require 'rbvmomi'

これでステータスが取れます。簡単です。
取得する値は、 VMware vSphere API Reference Documentation とか https://(vCenter)/mob を参照します。

Zabbixへの取込み方は、 ESXi 4.0 Hardware and Software Monitoring VMWare を参考にして、

  1. 取得した値をローカルにテキストで保存する
  2. それをZabbix AgentのUserParameterで取得する

というやり方にしてみます。
上記のサイトでは1つのファイルにしていますが、VMごとに取得したいので、 ついでに、ESXi、データストアのステータスも取得したいと思います。
VM、ESXi、データストアそれぞれをZabbixに監視ホストとして登録しようと思うので、それぞれ別ファイルにしてみます。

RbVmomiスクリプト

で、スクリプトはこんな感じになりました。

/tmp/vsphere にファイルを保存するのdで、zabbixの実行ユーザに書き込み権を与えておきます。

chown zabbix:zabbix /var/vsphere

引数にvCenter(or ESXi)のIPアドレス、ユーザ名、パスワードを指定して実行します。

su -u zabbix rbvmomi-zabbix.rb 192.168.1.1 root password

成功すれば、/tmp/vspere以下にESXi、データストア、VMごとのファイルができます。

Zabbix設定

次はZabbix側です。

まず、APIからのデータ取得は結構時間がかかるので、サーバ側、エージェント側両方のタイムアウトを30秒にして、再起動しておきます。

  • /etc/zabbix/zabbix_server.conf
1
Timeout=30
  • /etc/zabbix/zabbix_agentd.conf
1
TImeout=30

テンプレートをインポートします。

Zabbix UserParameterの設定

下記のファイルを/etc/zabbix/zabbix_agentd.d/以下に保存します。

vCenterの登録

Zabbixにホストとして、vCenterを登録します。

ホスト
- ホスト名:適当
- エージェントのIPアドレス:127.0.0.1
- ポート:10050

テンプレート
- インポートしたvCenter用テンプレート

マクロ
- {$HOST} : IPアドレス
- {$USERNAME} : ユーザ名
- {$PASSWORD} : パスワード

これで、スクリプトが設定した間隔で実行されます。

ESXi、データストア、VMの登録

ホスト
- ホスト:各登録名
- IPアドレス:127.0.0.1
- ポート:10050

テンプレート
- インポートしたESXi、データストア、VM用テンプレート

名前に「:」が含まれていると、登録できないので、「-」に変換して登録してください。

Bind + OpenLDAP

| Comments

BindのバックエンドDBをOpenLDAPにしてみる

OSはCentOS6.3

  • bind-sdbをインストールする
1
# sudo yum install bind-sdb
  • DNSzoneスキーマを組み込む

/etc/openldap/slapd.conf に追加

1
include /etc/openldap/schema/dnszone.schema
  • 構成はこんな感じ
1
2
3
4
5
6
root - Hosts --- example.com ------------- @(SOA NS)
              |                         |- server1(A)
              |                         |- www(CNAME)
              |
              |- 1.168.192.in-addr.arpa -- @(SOA NS)
                                        |- 1(PTR)

LDIF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
dn: ou=Hosts,dc=example,dc=com
objectclass: organizationalUnit
objectclass: top
ou: Hosts

# 正引き
dn: ou=example.com,ou=Hosts,dc=example,dc=com
objectclass: organizationalUnit
objectclass: top
ou: example.com

dn: relativeDomainName=@,ou=example.com,ou=Hosts,dc=example,dc=com
dnsclass: IN
dnsttl: 86400
nsrecord: ns.example.com.
objectclass: dNSZone
objectclass: top
relativedomainname: @
soarecord: ns.example.com. root.example.com. 2012110303 28800 14400 3600000 
 86400
zonename: example.com

dn: relativeDomainName=server1,ou=example.com,ou=Hosts,dc=example,dc=com
arecord: 192.168.1.1
dnsclass: IN
dnsttl: 3600
objectclass: dNSZone
objectclass: top
relativedomainname: server1
zonename: example.com

dn: relativeDomainName=www,ou=example.com,ou=Hosts,dc=example,dc=com
cnamerecord: server1
dnsclass: IN
dnsttl: 3600
objectclass: dNSZone
objectclass: top
relativedomainname: www
zonename: example.com

#逆引き
dn: ou=1.168.192.in-addr.arpa,ou=Hosts,dc=example,dc=com
objectclass: organizationalUnit
objectclass: top
ou: 1.168.192.in-addr.arpa

dn: relativeDomainName=@,ou=1.168.192.in-addr.arpa,ou=Hosts,dc=example,dc=com
arecord: 255.255.255.0
dnsclass: IN
dnsttl: 86400
nsrecord: ns.example.com.
objectclass: dNSZone
objectclass: top
ptrrecord: example.com.
relativedomainname: @
soarecord: ns.example.com. root.example.com. 2012110302 28800 14400 3600000 
 86400
zonename: 1.168.192.in-addr.arpa

dn: relativeDomainName=1,ou=1.168.192.in-addr.arpa,ou=Hosts,dc=example,dc=com
dnsclass: IN
dnsttl: 3600
objectclass: dNSZone
objectclass: top
ptrrecord: server1.example.com.
relativedomainname: 1
zonename: 1.168.192.in-addr.arpa