読者です 読者をやめる 読者になる 読者になる

tjinjin's blog

いつかすごいエンジニアになることを目指して、日々学んだことを書いていきます。

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をそのまま使うよりはいいかなーと思ったので、ちょっと使ってみたいと思っているところです。