consulを使った冗長なcronツール"cronsul"を試す
About
最近cron辛いなーと思っていて、じゃあ使ったことのあるRundeckなのかと思うのですが、冗長性をどう担保しようかなーと悩んでいました。たまたまgithub眺めていたら面白そうなものを見つけたので試してみます!
解決したいこと
- 定時にジョブを実行させたい
- どのサーバで動くかは重要ではなくて、とにかく定期実行させたい(冗長性)
- disposalなサーバにしたいので、サーバ特有の設定をなるたけ排除したい
cronsulとは
GitHub - EvanKrall/cronsul: Runs periodic jobs somewhere on a cluster... sorta
cron + consul = cronsulということだと思うのですが、その名の通りcronをconsulで制御します。
仕組みとしてはいたって簡単です 1. consulクラスタ上で同じcronを定期実行させてジョブをkick 2. cronsulでまずconsul kvへ値を登録しようとする。登録が成功するとそのまま実行 3. 先に値が登録されていると、多重登録ができないためそこでjobがスキップされる
consul kvをキューに見立てて利用するイメージですね。
試す
consulの準備
適当なVMを2台用意します。
## app1 $ consul agent -server -bootstrap-expect=1 -data-dir=/tmp/tmp/consul -bind=<ipaddress> $ consul agent -data-dir=/tmp/consul -bind=192.168.34.43 ## app2 $ consul join 192.168.34.43 # serverを指定
cronsulの導入
git clone
するだけです。
$ cd ~ $ git clone https://github.com/EvanKrall/cronsul
サンプルジョブの作成・登録
とりあえず適当なスクリプトを用意します。各サーバに設置します。
$ cat ~/exec.sh #!/bin/bash echo `date` >> /tmp/exec.log $ crontab -l * * * * * /home/vagrant/cronsul/cronsul test /home/vagrant/exec.sh
上記のような形でtest
の部分はジョブの一意な名前です。毎分に実行させてみます。上記設定をすべてのサーバで実行します。
各サーバでtailfしてみると下記のようになりました
- app1
Sun Feb 7 14:10:01 JST 2016 Sun Feb 7 14:11:02 JST 2016 Sun Feb 7 14:12:01 JST 2016 Sun Feb 7 14:13:01 JST 2016 Sun Feb 7 14:14:01 JST 2016 Sun Feb 7 14:17:01 JST 2016 Sun Feb 7 14:18:01 JST 2016 Sun Feb 7 14:19:01 JST 2016
- app2
Sun Feb 7 14:15:01 JST 2016 Sun Feb 7 14:16:01 JST 2016 Sun Feb 7 14:20:01 JST 2016
使ってみて
仕組みは簡単でよさそう
難解なツールだと、情報量とか気になりますが短いスクリプトなので何か問題あったときでも対応はできそうです。試しに1分間隔で3台のクラスタで1時間動かした所、特に重複実行はでなかったです。ただ、実行されるサーバは偏りがちな気はしました。また、各サーバの負荷状況把握して実行する訳ではないので、重くないサーバで実行させるとかはできず、あくまでシンプルで冗長なcronというイメージでしょうか。
KVにログが溜まっていく
現状の仕組みだとログがどんどんたまるので、適宜掃除しないとダメそうかなーと。ちょうどPRが出ているので、解決するかもしれません。削除用のスクリプトが出ているので、利用すればなんとかなるかなーというところです。
各サーバで同じ設定をしないといけないので若干無駄な気もしますが、そこはchefとかで担保させることである程度吸収できるかなと。cronをそのまま使うよりはいいかなーと思ったので、ちょっと使ってみたいと思っているところです。