Glide Note

glidenote's blog

監視ソフトをNagiosからSensuに切り替えて2ヶ月経ったのでまとめた

新規サービス用の監視をNagiosからsensuに切り替えて2ヶ月経ったので、 導入時の調査で社内で公開してたissueと、投入して2ヶ月間運用した記録を公開しておこうと思う。

というか以前Sensuの事を書くと公言していたのに、すっかりサボっていて 昨日@ma0eさんのブログを見て下記のやり取りを思い出して急いで書いた…

導入環境はCentOS 6.4で、利用しているsensuのバージョンは0.12.1-1になり、基本的にはNagiosとの比較になります。 またPuppetを使っているので、導入にはsensu-puppetを使ってます。

箇条書きで読みにくいですが、sensu導入の際は参考にしてください。

Sensuの特徴

  • Nagiosの問題点から生まれた監視フレームワーク
  • Rubyで書かれている
  • 監視対象(クライアント)が自動登録される
  • 設定ファイルが簡潔、分かりやすい
  • 新規サーバにChef/Puppetを流した直後から監視が自動で開始される
  • 既存Nagios Checkの再利用が出来る(Nagios資産が活かせる)
  • EC2のようなサーバ構成が頻繁に変化する環境において非常に有用
  • Chef/Puppetとの相性が非常に良い
  • 必要な機能はプラグインで拡張。アラートの通知方法を追加したり、librato-metricsと連携して、メトリクス作成とかも出来る。
  • WEB UIの動作が軽快
  • スケールアウトが容易

より詳しい情報は公式スライド http://slides.sensuapp.org を参照

sensuと連携出来るサービスとしてスライドには下記の画像が載っている

導入前の検証、調査時のまとめ

  • sensu repoを追加すれば、yum一発で導入出来る
  • sensuにはサーバとクライアントがある
  • erlangRabbitMQredisとgemのsensu-pluginが必要。クライアント側はredis必要無い
  • sensuはsensu-serversensu-apisensu-dashboardsensu-clientの4つから構成されている
  • Nagiosのようにサーバからクライアントに状態を聞きに行くのではなく、クライアント自身が自分を監視している
  • クライアント側で監視がこけたらサーバ側にRabbitMQを使って、サーバ側に自身の異常を通知する
  • クライアントに設定ファイル、監視プラグインを渡してsunsu-client起動すれば監視が勝手に始まる。(極端な話/etc/sensuまるごとクライアントに渡せば良い)
  • サーバはクライアントをRabbitMQで定期的に通信していて、通信断やホストダウンはサーバ側が検知する
  • クライアントが増えた場合は、RabbitMQ経由でサーバに通知してきて勝手に監視対象に追加される
  • クライアントを削除する場合は、api経由で監視対象から外す。(管理画面があるのでそれで監視対象を管理出来る)
  • 設定ファイルはjson。手編集ではなく、chefやpuppetでの自動生成が推奨されている
  • sensu自体が、chef/puppetでの管理が推奨されている
  • Nagiosと比較して設定ファイルが分かりやすい(Chef/Puppetが生成してくれるので自分で書くことはないと思いますが)
  • apiがあるので、自前でツールを用意したりするのが楽そう。(後述するsensu-adminもapiを叩いているツール)
  • nrpe-pluginがそのまま使えるのでnagios時代の資産が使える。/usr/lib/nagios/plugins/check_load -w 20,500,500 -c 35,500,500とかをチェックコマンドとして設定すれば良い。
  • 監視プラグインの書き方はnagiosと一緒。sensu-pluginも公開されてる https://github.com/sensu/sensu-plugin
  • 通知プラグイン、アラートのトレンドをグラフ化してくれるプラグインなどもある。

導入、2ヶ月運用したまとめ

  • sensu-puppetを動かすまでかなり苦労した(どうやらChefだと導入が簡単らしい)
  • 日本語の情報がほとんどない。特にsensu-puppetは、英語のドキュメント自体ないのでmanifest読まないといけなくてかなりつらい
  • sensu-puppetが動くようになると、設定ファイルを作ってくれるので一気に全台に導入出来るようになる。監視項目追加なども非常に楽になる
  • 逆に言うとsensu-puppet(sensu-chef)を利用しない場合は、sensu採用する意味が薄い(と思う)
  • RabbitMQの管理にはpuppetlabs-rabbitmqを利用した
  • デフォルト管理画面のsensu-dashboardが簡素すぎる(設定項目が少ないので分かりやすいとも言えますが)
  • 標準管理画面(sensu-dashboard)に機能追加したsensu-adminというのがあり、これを導入するとダウンタイムなどを設定出来るようになる。
  • sensu-adminはRailsアプリなので、nginx+unicorn+upstartで上げてます。
  • sensuのプラグインだと足りないので、nrpe-pluginを結構使ってる。
  • ログもjsonで吐かれるので、jqを一緒に導入しておくのが良い
  • sensu-serverを再起動したタイミングで、sensu-apiが死ぬことがある。なのでsensu-apiの監視必須
  • sensu-serverを再起動する必要がある場合は、sensu-server,sensu-api両方再起動しておくのが吉
  • IRCの通知プラグインが簡素過ぎたので、色が付くようにPR出してmergeしてもらった colorize irc notification. by glidenote · Pull Request #329 · sensu/sensu-community-plugins
  • 各種プラグインがRubyで書かれていて、それぞれのファイルが短いので理解しやすい。改変や自作も楽に出来る。(Ruby情弱の私でも出来た)
  • 今Sensuで監視しているサーバは10台弱で、各サーバ8〜10個くらいの監視項目という小規模で利用していて、2ヶ月間トラブルもなく安定している
  • 数百台と監視したときNagiosと同等の安定した動作がするかは調査中。
  • 私がRabbitMQの扱いになれてないので、そこがトラブると調査が大変そうな予感…

実際に稼働しているsensu-serverの/etc/sensu配下のファイル一覧。.jsonが設定ファイルで、.rbがプラグイン。sensu-puppetが設定ファイルを生成してくれるので、管理が非常に楽。

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
/etc/sensu
├── conf.d
│   ├── api.json
│   ├── checks
│   │   ├── check_crond_process.json
│   │   ├── check_disk.json
│   │   ├── check_lb_health.json
│   │   ├── check_load.json
│   │   ├── check_mem.json
│   │   ├── check_ntp_time.json
│   │   ├── check_ReadOnly_FileSystem.json
│   │   ├── check_sensu_api.json
│   │   ├── check_serf_process.json
│   │   ├── check_ssh_port_22.json
│   │   └── check_ssl_expire.json
│   ├── client.json
│   ├── dashboard.json
│   ├── handlers
│   │   ├── default.json
│   │   ├── irc.json
│   │   ├── irc-server-op.json
│   │   └── mailer.json
│   ├── rabbitmq.json
│   └── redis.json
├── extensions
├── handlers
│   ├── irc.rb
│   ├── irc-server-op.rb
│   └── mailer.rb
├── mutators
├── plugins
│   ├── check-fs-writable.rb
│   ├── check-http.rb
│   ├── check-load.rb
│   ├── check_mem
│   ├── check-memcached-stats.rb
│   ├── check-procs.rb
│   └── check-redis-memory.rb
└── ssl
    ├── client_cert.pem
    └── client_key.pem

8 directories, 32 files

実際に使っている管理画面。sensu-dashboardからsensu-adminに切り替えてサービスに投入してます。

アラートが出ると下記のような感じ。アラートが出たものだけ表示される。

IRCには下記のような感じ(私のPRがmergeされて色が付くようになってます!)

メールでは

1
2
3
4
5
6
7
8
9
10
11
ALERT - web001.glidenote.jp/check_php-fpm:

PROCS CRITICAL: 0 processes with command name 'php-fpm'

            Host: web001.glidenote.jp
            Timestamp: Wed Nov 20 11:35:51 +0900 2013
            Address:  192.168.xxx.xxx
            Check Name:  check_php-fpm
            Command:  /usr/lib/nagios/plugins/check_procs -c 1: -C "php-fpm"
            Status:  2
            Occurrences:  2

みたいな感じで通知される。

私が導入したときはVersion 0.9だったのが今はVersion 0.12になっており、ドキュメントの更新も結構活発なので、 導入に関しては公式ドキュメントを読むのが良いと思います。

Puppetでの構築

実際に構築時に流しているコマンド、下記を流せば、Sensuでの監視が勝手に始まる。 Serf-muninも使っているので、下記を流し終われば即サービスに投入も出来る。

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
cat << 'EOF' >/etc/yum.repos.d/epel.repo
[epel]
name=epel repo
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
EOF

yum -y install puppet

cat << 'EOF' > /etc/puppet/puppet.conf
[main]
ssldir = $vardir/ssl
rundir = /var/run/puppet
logdir = /var/log/puppet

[master]
environment = development
certname    = manage001.pb.glidenote.lan
manifestdir = $vardir/data/manifests
templatedir = $vardir/data/templates
modulepath  = $vardir/data/modules

[agent]
pluginsync = true
EOF

echo "172.18.xxx.xxx    manage001.pb.glidenote.lan" >> /etc/hosts

yum -y install rubygems
rpm -Uvh http://mirrors.kernel.org/fedora-epel/6/x86_64/rubygem-json-1.4.6-1.el6.x86_64.rpm

puppet agent --test --server manage001.pb.glidenote.lan --noop
puppet agent --test --server manage001.pb.glidenote.lan

SensuとともにSerf-muninを導入したこともあって、インスタンス起動して、 Puppet流したら即サービス投入可能という、手間のかからない環境が出来上がった。

数百台、数千台の監視になるとどうなるか分からないけど、今の規模では非常に安定しているし、 Sensuの管理の簡単さを知るともうNagiosには戻りたくない。

参考

Webサーバのメンテナンス、トラブル調査に役に立つコマンド3選

メンテナンス、サーバのミドルウェア設定、障害対応のときに私がよく使っているコマンド。 先週Webサーバを16台ほどリプレイスした際にも、使って挙動、確認作業をしてました。

コレ系のコマンドは各人の秘伝のタレみたいになってて、他の人が教えてくれることが少ない気がして、 新卒氏のインフラOJT用に専用の資料作ろうかと思ったけど、新卒氏以外でも知ってれば 「よく分からんけど、動かないからインフラ担当者に聞く」みたいなことが 減って自分で解決出来るのではないかと思うので書いておく。

手元のmac、linuxから該当サーバに対して実行するコマンドで ちゃんと該当サーバが外部に向けてサービスが提供出来ているのか、 要は外から確認するためのコマンドです。

調査系のコマンドは

  • オプション、使い方が覚えやすい
  • 手軽に使える
  • 結果が見やすい、理解しやすい

というのが重要だと思う。

サーバの中で調査するなら

のコマンドを見た方が良いです。

nc(netcat)

ポートが開いているか、デーモンが起動してリクエスト応答しているか確認。

1
nc -vz github.com 80
1
2
nc -vz github.com 443
Connection to github.com 443 port [tcp/https] succeeded!

今よく触ってるSerfは7946ポートを使うので、他のサーバから下記で接続確認。

1
nc -vz manage001.hogemoge.lan 7946

アラートが来たら、とりあえずnc叩けば 接続過多で駄目なのか、そもそもミドルウェアが落ちてるのかとか サーバ入る前にだいたい検討付くので初動を間違えずに済む。

普段やること無いですが、一応下記みたいな感じでポートスキャンも出来る。

1
nc -vz hogemoge.com 1-1023

最近はtelnetをサーバに入れてないことが多いけど、ncが入ってれば telnetと同様な感じでも利用出来るので、ヘッダをリクエストしたり

1
2
3
4
nc www.google.com 80 << EOF
HEAD / HTTP/1.0

EOF

たとえばmunin-nodeが動作しているか確認する場合は、下記みたいに出来る。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@manage001 ~]# nc manage001.hogemoge.jp 4949
# munin node at manage001.hogemoge.jp
list
cpu df df_abs df_inode entropy forks fw_conntrack fw_forwarded_local fw_packets if_err_eth0 if_err_eth1 if_eth0 if_eth1 interrupts irqstats load memory munin_stats netstat ntp_kernel_err ntp_kernel_pll_freq ntp_kernel_pll_off ntp_offset ntp_states open_files open_inodes postfix_mailqueue postfix_mailvolume proc_pri processes swap threads uptime users vmstat
fetch memory
slab.value 189231104
swap_cache.value 0
page_tables.value 6995968
vmalloc_used.value 119119872
apps.value 936333312
free.value 676610048
buffers.value 247578624
cached.value 1336840192
swap.value 0
committed.value 885620736
mapped.value 31141888
active.value 1401610240
inactive.value 658358272
.
quit

通常は接続元IPを制限してると思うので、許可されているIPと許可されていないIPの二つから確認して、 設定がちゃんと出来てるとかの確認もしてます。

host

サーバの/etc/resolv.confで設定して参照しているDNSサーバ、Google Public DNSとかとの結果を比較をして、 おかしなDNS情報を持ってないか確認したりするのに使ってます。

DNSサーバを指定しない場合は、/etc/resolv.confに設定してあるDNSサーバを利用。

1
host -a github.com

Google Public DNSを参照

1
host -a github.com 8.8.8.8

dnsmasqとか使ってると古い情報をキャッシュしてたりするので、hostコマンドを使うとすぐ分かる。

エンジニアのための時間管理術 から引用で

  • 奇妙な問題は DNS の設定ミスが原因していることが多い

DNS は多くのサブシステムにとって致命的な影響を与え、しばしば、問題を 別の問題であるかのように見せかけ、その問題を覆い隠してしまう傾向がある。 これに該当するのは、DNS サーバーにアクセスできないクライアント、無効 な DNS データが設定されたホスト、または無効な DNS データが設定された ホストにアクセスしようとするクライアントである。

私の経験上でも、意味不明なトラブルはDNS周りが起因していることが多いので、早めにhostdigでDNS周りの調査をします。

http (httpie)

最近はnginxのプロキシ、リプロシキ、ngx_luaの設定ばっか触ってるので、httpieで挙動確認、設定確認をしてます。

CentOS6では下記のように導入。

1
2
yum -y install python-pip
pip install httpie

Macの場合はhomebrew利用してここを参考に下記みたいな感じで導入。

1
2
3
brew install python
export PATH=/usr/local/share/python:$PATH
pip install httpie

curlでも同じ事が出来るんですが、curlは人間に優しくないというか 私がオプションを全く覚えることが出来ないので、こちらを多用してます。 httpieだけでは足りないので、もちろんcurlも重宝してます。

下記の例はヘッダを見てるだけだけど、色が付くだけで見やすくなる。

ヘッダの確認

1
http -h httpbin.org

basic認証の確認

1
http -a hoge https://httpbin.org/basic-auth

リダイレクトの確認

1
http --follow google.co.jp

GETのテスト。defaultがGETなので、GETの場合はmethod指定しなくても良い。

1
http GET httpbin.org/get

PUTのテスト

1
http PUT httpbin.org/put name=hoge key=value

と例を挙げたらキリがないんですが、ApacheやNginxの動作、設定確認なので、 普段はだいたい上記みたいな感じで使ってます。

ちなみにhttp://httpbin.org/を利用するとhttpieの使い方が覚えるのに便利で、 https://httpbin.org/もあるので、ssl系のテストも出来る。

httpieのzsh補完関数は先日pull req出して、zsh-completionsにmergeされているので、httpieご利用の方はご活用ください。

add httpie completion by glidenote · Pull Request #184 · zsh-users/zsh-completions

他にも調査用のコマンドはありますが、nc,host,httpieを使いこなせれば、 サーバ入る前にある程度の事が判断ついて、いろいろと捗ると思う。

serf-muninを導入してmunin-nodeの監視追加、削除を自動化した

前回の続きSerfを触ってる。前回のエントリを見て、@zembutsuさんが作ってくれたserf-muninが素晴らしかったので、弊社仕様に若干修正して導入した。

Serf-muninが自動生成、削除するファイルは/etc/munin/conf.d/配下で、 既存のmunin環境(/etc/munin/munin.confとか)を壊すことがないと思うので、すぐに試すことが出来ると思う。

導入環境は

  • CentOS 6.4
  • Serf 0.2.0
  • munin-2.0.17

で、Serfの起動コマンドや生成されるmuninのconfの関係上、Serf 0.2.0とmunin 2.0以上は必須条件になります。

serf-muninの仕組みの説明

1. web server1がmuninサーバと同じクラスタにserf joinしてくる

2. Web server1がクラスタにjoinしてきたので、member-joinイベントが発生

  1. muninサーバでmember-joinイベントで指定しているスクリプトが実行される
  2. muninサーバの/etc/munin/conf.d/web001.foobar.confという設定ファイルが追加され、ポーリング対象のサーバが追加される。
  3. Web Serve1がmuninのグラフに追加される

3. DB server1がクラスタにjoinしてきたので、member-joinイベントが発生

  1. muninサーバでmember-joinイベントで指定しているスクリプトが実行される
  2. muninサーバの/etc/munin/conf.d/db001.foobar.confという設定ファイルが追加され、ポーリング対象のサーバが追加される。
  3. DB Serve1がmuninのグラフに追加される

4. Web server1が突然の死。member-leaveイベントが発生

  1. muninサーバでmember-leaveイベントで指定しているスクリプトが実行される
  2. muninサーバの/etc/munin/conf.d/web001.foobar.confという設定ファイルが削除され、ポーリング対象のサーバから削除される。
  3. Web Server1がmuninのグラフから削除される

もしWeb Server1が復活したら、勝手にクラスタに参加してくるので、再度ポーリング先に自動追加される。

実際の設定

muninサーバ側の設定

SERF_ROLEはmuninのconf内でgroupに利用するために設定してます。 muninサーバにはmanageというroleを設定してます。

作業の流れは

  1. Serfをダウンロードして、/usr/local/bin/serfに設置
  2. 自動生成されるconf用ディレクトリ/etc/munin/conf.dを作成
  3. serf join/leaveイベント発生時に実行されるスクリプトserf-munin.shを作成し、設置
  4. Serfの起動スクリプトを作成
  5. Serfの起動
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
export SERF_ROLE=manage
sudo yum install -y unzip

cd /tmp/
until wget -O serf.zip https://dl.bintray.com/mitchellh/serf/0.2.0_linux_amd64.zip; do
  sleep 1
done
unzip serf.zip
sudo mv serf /usr/local/bin/serf
rm serf.zip

sudo mkdir -p /etc/munin/conf.d/

# create serf-munin.sh
cat <<'EOF' >/tmp/serf-munin.sh
#!/bin/sh

while read line
do
  echo ${line}
    HOSTNAME=`echo ${line} | cut -d ' ' -f 1`
    ADDRESS=`echo ${line} | cut -d ' ' -f 2`
    GROUP=`echo ${line} | cut -d ' ' -f 3`

    case ${SERF_EVENT} in
    "member-join")
      cat << __EOF__ > "/etc/munin/conf.d/${HOSTNAME}.conf"
[${GROUP};${HOSTNAME}]
    address ${ADDRESS}
    use_node_name yes
__EOF__
;;
    "member-leave" | "member-failed")
      rm -f /etc/munin/conf.d/${HOSTNAME}.conf;;
    \?)
      echo "other";;
    esac
    break
done 

exit 0
EOF

sudo mv /tmp/serf-munin.sh /usr/local/bin/serf-munin.sh
sudo chmod 755 /usr/local/bin/serf-munin.sh

# Configure the agent
cat <<EOF >/tmp/agent.conf
description "Serf agent"

start on runlevel [2345]
stop on runlevel [!2345]

exec /usr/local/bin/serf agent \\
  -event-handler="/usr/local/bin/serf-munin.sh" \\
  -role=${SERF_ROLE} >>/var/log/serf.log 2>&1
EOF
sudo mv /tmp/agent.conf /etc/init/serf.conf

# Start the agent!
sudo start serf

この状態で既に/etc/munin/conf.d/${HOSTNAME}.confというファイルが出来上がって、

1
2
3
[manage;manage001.foobar.com]
    address 127.0.0.1
    use_node_name yes

というような内容になっている。

munin-node側の設定

MUNIN_SERVERにmuninサーバのIPもしくはfqdnを設定。MUNIN_SERVERで指定したサーバに serf joinしに行きます。 SERF_ROLEはmuninのconf内でgroupに利用するために設定してます。 例ではwebというroleを設定しており、実環境でもwebdbbackupなどとroleを設定してます。

作業の流れは

  1. Serfをダウンロードして、/usr/local/bin/serfに設置
  2. Serfの起動スクリプトを作成
  3. Serfの起動
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
export MUNIN_SERVER=192.168.100.100
export SERF_ROLE=web

sudo yum install -y unzip

# Download and install Serf
cd /tmp
until wget -O serf.zip https://dl.bintray.com/mitchellh/serf/0.2.0_linux_amd64.zip; do
  sleep 1
done
unzip serf.zip
sudo mv serf /usr/local/bin/serf
rm serf.zip

# Configure the agent
cat <<EOF >/tmp/agent.conf
description "Serf agent"

start on runlevel [2345]
stop on runlevel [!2345]

exec /usr/local/bin/serf agent \\
  -join=${MUNIN_SERVER} \\
  -role=${SERF_ROLE} >>/var/log/serf.log 2>&1
EOF
sudo mv /tmp/agent.conf /etc/init/serf.conf

# Start the agent!
sudo start serf

この状態で既に/etc/munin/conf.d/${HOSTNAME}.confというファイルが出来上がって、

1
2
3
[web;web001.foobar.com]
    address 172.18.100.109
    use_node_name yes

というような内容になっていて、

1
sudo stop serf

でSerfと止めると、confが削除されるのが分かる。

Serf 0.2.0になって、serf agent join="IP"みたいなことが出来るようになっていて起動スクリプトもシンプルになった。 やってることは非常に単純でSerfの設置、スクリプト設置だけなのでpuppet化も非常に楽。

Serf 0.2.0の変更点は@zembutsuさんのブログが非常に参考になります。素晴らしいエントリ!!

担当しているサービス用にインストール用のwrapperスクリプトを公開しているので、参考にどうぞ。

Serf 0.2.0から暗号化も可能になったので、これでサーバ起動して、Puppet流せば、 新規サーバのmuninグラフが勝手に出来上がる仕組みが出来上がった。

参考

Serf+HAProxyで作るAutomatic Load Balancer

Serf使ってますか!サーフ!

諸事情というか大人の事情で急遽自前でロードバランサを用意しないといけなくて、それをissueに書いてたら、 あんちぽさんがSerf+HAProxy使ったらいいのでは、 とIRCで助言をくれて、同日のmizzyさんのブログでもSerfに言及していたので、 ちょっとSerfの概要を知るためと、Serf+HAProxyが実際ロードバランサとしてどんな感じに使えるのか検証してみた。

Serfは新しいプロダクトだし、公式でSerf+HAProxyをDemoと言って紹介してるけど、ドキュメントが少なくて、 どうすれば動くのか、どういう仕組みなのか理解に苦労したので先に概要をちょっとまとめてみる。

Serf + HAProxyの概要

  • Serfは全てのサーバで動かす必要がある。
  • クラスタという概念があって、各サーバ(ノード)で動いているSerfがクラスタにjoin/leaveすることが出来る。
  • クラスタに参加している、ノード同士が相互通信をしていて、クラスタへのjoin/leaveするノードを検知している
  • ノードがクラスタにjoin/leaveするとイベントが発生して、事前に設定したスクリプトを走らせることが出来る。 今回の例だとロードバランサ側で/etc/haproxy/haproxy.cfgの修正スクリプトが走って、バランシング先のWEBサーバを自動で追加、除外してくれる。

2013年10月31日 19:00 修正
HAProxyの再起動と書いてましたが、正しくは/etc/init.d/haproxy reloadなので、設定再読込でした。

1.ロードバランサのクラスタにweb server1がjoin

2.Web server1がクラスタにjoinしてきたので、member-joinイベントが発生

  1. ロードバランサでmember-joinイベントで指定しているスクリプトが実行される
  2. ロードバランサの/etc/haproxy/haproxy.cfgの書き換え、HAProxyの設定再読込がかかり、Web Server1がバランシング先に追加される。
  3. Web Serve1にアクセスが流れるようになる

3.Web server2がクラスタにjoinしてきたので、member-joinイベントが発生

  1. ロードバランサでmember-joinイベントで指定しているスクリプトが実行される
  2. ロードバランサの/etc/haproxy/haproxy.cfgの書き換え、HAProxyの設定再読込がかかり、Web Server2がバランシング先に追加される。
  3. Web Serve1とWeb Server2にアクセスが流れるようになる

4.Web server1が突然の死。member-leaveイベントが発生

  1. ロードバランサでmember-leaveイベントで指定しているスクリプトが実行される
  2. ロードバランサの/etc/haproxy/haproxy.cfgの書き換え、HAProxyの設定再読込がかかり、Web Server1がバランシング先から除外
  3. Web Server2だけアクセスが流れるようになる

もしWeb Server1が復活したら、勝手にクラスタに参加してくるので、再度バランシング先に自動追加される。

Serf+HAProxyのまとめ

  • Webサーバの増減に伴って設定ファイル書き換え、commit、push、deployして、HAProxyのreloadとかする必要ない。
  • Webサーバの増減をロードバランサが自動で検知してバランシング先に追加、除外を自動でしてくれる。
  • Puppet(Chef)でSerf+HAProxyの設定をしておけば、インスタンス起動してPuppet(Chef)流せば勝手にサービスに投入される

公式だとapt-getでCentOSで動かなかったり、apache勝手に入れてきたり、クラスタに参加出来なかったり 動くようになるまでなかなかつらかったので、CentOSでとりあえず動くものをGitHubに公開しておきましたので参考にどうぞ。 ローカルLAN用のeth1が無いと使えなかったり、私も触って1日なので、よく分かってない部分が多くて改良の余地が大いにありますが。 facterを組み合わせれば、自分自身の情報を他のノードに伝える事が簡単にできると思う。

http://LP_IP:9999/にアクセスするとHAProxyの状態が確認出来て、自動でバランシング先が変化するのが確認出来る。

あんちぽさんも/etc/hostsを自動で書き換えるものを作っていたので、勉強になります。

想定される使いどころとして、すぐ思い浮かぶのがnagiosとかmuninとかサーバ増えるたびに設定ファイル修正が必要なので、Serf使いどころだと思う。 サーバの増減とかに伴って、ファイル修正が必要な部分はSerf使えば解決するはず。

Serfはドキュメントも読み切れてないので引き続きいろいろと検証を続けてる。

Nagiosから脱却すべく最近使い始めたSensuも、サーバの増減を自動で検知して勝手に監視が始まるので、 従来のサーバ増やした(減らした) => 設定ファイル修正commit、push、deploy みたいな作業は今後無くなっていくんだろうな-。

Nagiosに代わるであろう監視ソフトSensuについても、頑張って検証しているので機会があればブログに書こうと思う。

参考

うっかりnohup無しで長時間かかるコマンドを実行したときに後から終了しないようにする

すぐ終わるかと思って、nohuptmuxも無しで 実行したら全然終わらなくて帰れなくなって久々にググってやったのでメモ。

定時前に数分で終わると思ったrpm作成で下記みたいなことを実行して、

1
rpmbuild -ba hoge.spec

いつまで経っても終わらないから帰れない… 途中で終了してしまうと困るので、ログアウトしても終了しないように。

作業の流れ

  1. Ctrl+Zでコマンドの中断
  2. bgでバックグラウンドに回す
  3. jobsでジョブの確認
  4. disownでログアウトしても実行されるようにする

実際のコマンドだと

1
2
3
4
5
rpmbuild -ba hoge.spec
# Ctrl+Zで中断
bg 1
jobs 1
disown %1

で帰れる。

nohupdisownの違いは

  • nohup:コマンドをハングアップシグナル無視で実行させる。
  • disown:nohupをつけ忘れた時、途中からバックグラウンドでの実行へ切り替える

参考