LoginSignup
5
6

More than 5 years have passed since last update.

Koyomi を CentOS 7 にインストールし、Systemd で動かす

Posted at

筆者が開発している Koyomi という、分散ジョブスケジューラのインストール、使用方法について解説するチュートリアル・ドキュメントです。

今回は Vagrant を使ってまっさらな CentOS 7 の環境に Koyomi をインストールし、systemd1の service として起動します。
その上で、ジョブを登録して実行するところまでやってみます。

このチュートリアルを通して、Koyomi が cron のように動作することがわかると思います。

本稿執筆時点の Koyomi のバージョンは 0.5.1 です。

Vagrant による CentOS 7 環境構築

http://www.vagrantbox.es/ で配布されている Vagrantbox を使います。

以下のコマンドは MacOS X 上で実行しました。環境に応じて、適宜読み替えて下さい。

vagrant box add centos7 https://github.com/holms/vagrant-centos7-box/releases/download/7.1.1503.001/CentOS-7.1.1503-x86_64-netboot.box
mkdir ~/Vagrant/centos7
cd ~/Vagrant/centos7
vagrant init centos7
vagrant up

vagrant ssh で VM にログインできます。

CentOS 7 VM Setup

ここからは上で作成した Vagrant による CentOS 7 の環境で作業していきます。
vagrant ユーザで作業します。

plenv と Perl 5.22.0 インストール

VM に plenv2 と Perl 5.22.0 をインストールします。

git clone git://github.com/tokuhirom/plenv.git ~/.plenv

echo 'export PATH="$HOME/.plenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(plenv init -)"' >> ~/.bash_profile
exec $SHELL -l

git clone git://github.com/tokuhirom/Perl-Build.git ~/.plenv/plugins/perl-build/
plenv install 5.22.0

Koyomi インストール & セットアップ

インストールガイドでは、GitHub または CPAN からインストールする方法を紹介しています。

今回は GitHub 上の master ブランチの HEAD を用いますが、通常は最新の安定版を取得することを推奨します。

git clone git@github.com:key-amb/perl5-App-Koyomi.git ~/koyomi

cpanm, Carton を Perl 5.22.0 にインストールしておく

plenv を使って、~/koyomi 以下では Perl 5.22.0 を使うようにします。
また、下準備として cpanm3Carton4 を Perl 5.22.0 にインストールしておきます。

cd ~/koyomi
plenv local 5.22.0
plenv install-cpanm
cpanm -v Carton
plenv rehash

依存モジュールのインストール

Carton を使って local/ に Koyomi の依存モジュールをインストールします。
依存モジュールが多いので、初回は少々時間が掛かるかと思います。

cd ~/koyomi
carton install

Configure

今回はデフォルトの config/default.toml を使います。
設定ファイルを次のように編集します。

$ cd ~/koyomi
$ git diff config/default.toml
diff --git a/config/default.toml b/config/default.toml
index 1ef5b29..58c2ec0 100644
--- a/config/default.toml
+++ b/config/default.toml
@@ -4,7 +4,7 @@
 #debug_mode = true

 [log]
-#debug   = true
+debug   = true
 console = true
 file    = true
 # file_path = /path/to/log
@@ -27,13 +27,13 @@ lock_ttl_seconds = 25

 [datasource.module]
 job       = "Teng"
-semaphore = "Teng"
-#semaphore = "None"
+#semaphore = "Teng"
+semaphore = "None"

 [datasource.connector]
-dsn      = "dbi:mysql:database=koyomi;host=127.0.0.1;port=3306"
-#dsn      = "dbi:SQLite:tmp/koyomi.sqlite"
-user     = "root"
+#dsn      = "dbi:mysql:database=koyomi;host=127.0.0.1;port=3306"
+dsn      = "dbi:SQLite:tmp/koyomi.sqlite"
+user     = "" # "root"
 password = ""

 # Can override for each entity

設定ファイルの詳細については、ドキュメントを参照して下さい。

SQLite に DB 作成

今回は簡単のため、ジョブのデータストアとして SQLite を使います。
リポジトリに同梱している DDL を発行して、DB を作成します。

cat schema/sqlite/koyomi.ddl | sqlite3 tmp/koyomi.sqlite

sqlite3 コマンドが見つからない場合、yum install sqlite などとしてインストールして下さい。

以上で、koyomi を動かすための準備は完了です。

koyomi を動かす

ここでは Makefile に定義したタスクを使って手動で worker を実行します。

$ make worker
carton exec perl -Ilib script/koyomi
2015-06-20T22:20:53 [DEBUG] bless( {'datasource' => {'connector' => {'dsn' => 'dbi:SQLite:tmp/koyomi.sqlite','password' => '','user' => ''},'module' => {'job' => 'Teng','semaphore' => 'None'}},'debug' => {'worker' => {'sleep_seconds' => 5}},'job' => {'lock_ttl_seconds' => 25},'log' => {'console' => 'true','debug' => 'true','file' => 'true'},'schedule' => {'update_interval_seconds' => 120},'worker' => {'interval_minutes' => 1,'minimum_interval_seconds' => 30}}, 'App::Koyomi::Config' ) at lib/App/Koyomi/Config.pm line 30
2015-06-20T22:20:53 [DEBUG] update schedule at lib/App/Koyomi/Schedule.pm line 46
2015-06-20T22:20:53 [DEBUG] 2015-06-20T22:20:53 Sat at lib/App/Koyomi/Schedule.pm line 67

無事に起動しました。
デバッグログを有効にしているので、出力が多めになっています。

この時点では、まだ1つもジョブを登録していません。

一旦、Ctrl-C で worker プロセスを中断しておいて下さい。

Koyomi を Systemd の Service として動かす

koyomi は daemon として使われることを想定していますが、 koyomi 単体では自らを daemon 化する方法を提供していません。
daemontools など外部のツールを用いる必要があります。

今回は koyomi を systemd1 の service として動かしてみます。

Unit 定義ファイル作成

次のような Unit 定義ファイルを作成しました。

$ cat /etc/systemd/system/koyomi.service 
[Unit]
Description=koyomi daemon

[Service]
User=vagrant
Group=vagrant
ExecStart=/home/vagrant/koyomi/tmp/koyomi.sh

[Install]
WantedBy=multi-user.target

起動スクリプト作成

koyomi を起動するため、次のようなシェルスクリプトを作成しました。

$ cat /home/vagrant/koyomi/tmp/koyomi.sh
#!/bin/sh

set -e

HOME=/home/vagrant
KOYOMI=${HOME}/koyomi
CARTON=${HOME}/.plenv/versions/5.22.0/bin/carton

eval "$(${HOME}/.plenv/bin/plenv init -)"

cd $KOYOMI && \
  $CARTON exec perl -Ilib script/koyomi

以上で、koyomi を systemd で動かすための準備は完了です。

Service の起動

systemctl コマンドを使って service を有効化し、起動します。

sudo systemctl enable koyomi
sudo systemctl start koyomi

systemctl status で起動したことを確認できます。

$ sudo systemctl status koyomi 
koyomi.service - koyomi daemon
   Loaded: loaded (/etc/systemd/system/koyomi.service; enabled)
   Active: active (running) since 土 2015-06-20 23:23:51 JST; 2min 55s ago
 Main PID: 5129 (koyomi.sh)
   CGroup: /system.slice/koyomi.service
           ├─5129 /bin/sh /home/vagrant/koyomi/tmp/koyomi.sh
           └─5173 perl -I lib script/koyomi

 6月 20 23:23:51 localhost.localdomain systemd[1]: Started koyomi daemon.
 6月 20 23:23:52 localhost.localdomain koyomi.sh[5129]: 2015-06-20T23:23:52 [DEBUG] bless( {'datasource' => {'connector' => {'dsn' => 'dbi:SQLite:tm... {'conso
 6月 20 23:23:52 localhost.localdomain koyomi.sh[5129]: 2015-06-20T23:23:52 [DEBUG] update schedule at lib/App/Koyomi/Schedule.pm line 46
 6月 20 23:23:52 localhost.localdomain koyomi.sh[5129]: 2015-06-20T23:23:52 [DEBUG] 2015-06-20T23:23:52 Sat at lib/App/Koyomi/Schedule.pm line 67
 6月 20 23:24:22 localhost.localdomain koyomi.sh[5129]: 2015-06-20T23:24:22 [DEBUG] no need to update schedule at lib/App/Koyomi/Schedule.pm line 42
 6月 20 23:24:22 localhost.localdomain koyomi.sh[5129]: 2015-06-20T23:24:22 [DEBUG] 2015-06-20T23:24:22 Sat at lib/App/Koyomi/Schedule.pm line 67
 6月 20 23:25:00 localhost.localdomain koyomi.sh[5129]: 2015-06-20T23:25:00 [DEBUG] no need to update schedule at lib/App/Koyomi/Schedule.pm line 42
 6月 20 23:25:00 localhost.localdomain koyomi.sh[5129]: 2015-06-20T23:25:00 [DEBUG] 2015-06-20T23:25:00 Sat at lib/App/Koyomi/Schedule.pm line 67
 6月 20 23:26:00 localhost.localdomain koyomi.sh[5129]: 2015-06-20T23:26:00 [DEBUG] update schedule at lib/App/Koyomi/Schedule.pm line 46
 6月 20 23:26:00 localhost.localdomain koyomi.sh[5129]: 2015-06-20T23:26:00 [DEBUG] 2015-06-20T23:26:00 Sat at lib/App/Koyomi/Schedule.pm line 67
Hint: Some lines were ellipsized, use -l to show in full.

koyomi-cli を用いたジョブの登録

せっかくなので、1つジョブを登録することにします。

koyomi-cli add を実行するとエディタ(vi)が起動し、予めフォーマットされた YAML を編集する画面になります。
YAML を編集して保存することで、ジョブを登録します。

今回は echo $(date) alive >> /tmp/tick.log というコマンドを毎分実行するジョブを登録してみます。

$ cd ~/koyomi
$ carton exec perl -Ilib script/koyomi-cli add
:
# (エディタ起動)
---
command: 'echo $(date) alive >> /tmp/tick.log'
memo: ''
times:
- '*/*/* *:* (*)'
user: ''

# __EOF__
# Format and Description:
#   "command": String. Job as shell command to execute.
#   "memo":    String. You can add comment about the job on this field.
#   "times":   Array. Each entry follows this format:
#     - 'YYYY/mm/dd HH:MM (number of day in week)'
#     Examples:
#       - '2015/*/* 0:0 (7)' ... At 0:00 am every sunday in 2015
#       - '*/*/* *:30 (*)'   ... At 30 minutes after every o'clock
#   "user": String. OS user to execute the command. Leave it blank to execute by the user of worker
:
"/tmp/Ekdf40ta3e" 17L, 612C written
---
command: echo $(date) alive >> /tmp/tick.log
memo: ''
times:
- '*/*/* *:* (*)'
user: ''

Add this job. OK? (y/n) [n] y
2015-06-20T23:55:48 [INFO] [add] Finished. at lib/App/Koyomi/CLI.pm line 103

koyomi-cli list で登録されたジョブを確認できます。

$ koyomi-cli list
.-------------------------------------------------------------------------------.
| id | user | command                             | Y | m | d | H | M | weekday |
+----+------+-------------------------------------+---+---+---+---+---+---------+
|  1 |      | echo $(date) alive >> /tmp/tick.log | * | * | * | * | * | *       |
'----+------+-------------------------------------+---+---+---+---+---+---------'

デフォルトの設定ではジョブの登録・削除・変更は約2分後に daemon に反映されます。
数分後に journalctl コマンドでログを確認してみます。

$ sudo journalctl -n 100
6月 20 23:55:16 localhost.localdomain sudo[5410]: vagrant : TTY=pts/1 ; PWD=/home/vagrant/koyomi ; USER=root ; COMMAND=/bin/systemctl restart koyomi
6月 20 23:55:16 localhost.localdomain systemd[1]: Stopping koyomi daemon...
6月 20 23:55:16 localhost.localdomain systemd[1]: Starting koyomi daemon...
6月 20 23:55:16 localhost.localdomain systemd[1]: Started koyomi daemon.
6月 20 23:55:17 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:55:17 [DEBUG] bless( {'datasource' => {'connector' => {'dsn' => 'dbi:SQLite:tmp/koyomi.sql
6月 20 23:55:17 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:55:17 [DEBUG] update schedule at lib/App/Koyomi/Schedule.pm line 46
6月 20 23:55:17 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:55:17 [DEBUG] 2015-06-20T23:55:17 Sat at lib/App/Koyomi/Schedule.pm line 67
6月 20 23:56:00 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:56:00 [DEBUG] no need to update schedule at lib/App/Koyomi/Schedule.pm line 42
6月 20 23:56:00 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:56:00 [DEBUG] 2015-06-20T23:56:00 Sat at lib/App/Koyomi/Schedule.pm line 67
6月 20 23:57:00 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:57:00 [DEBUG] no need to update schedule at lib/App/Koyomi/Schedule.pm line 42
6月 20 23:57:00 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:57:00 [DEBUG] 2015-06-20T23:57:00 Sat at lib/App/Koyomi/Schedule.pm line 67
6月 20 23:58:00 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:58:00 [DEBUG] update schedule at lib/App/Koyomi/Schedule.pm line 46
6月 20 23:58:00 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:58:00 [DEBUG] (id,user,command) = (1,<NULL>,"echo $(date) alive >> /tmp/tick.log") at lib/
6月 20 23:58:00 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:58:00 [DEBUG] 2015-06-20T23:58:00 Sat at lib/App/Koyomi/Schedule.pm line 67
6月 20 23:58:00 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:58:00 [INFO] 5589 1 USER=vagrant COMMAND="echo $(date) alive >> /tmp/tick.log" at lib/App/
6月 20 23:58:00 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:58:00 [INFO] 5589 1 Succeeded. at lib/App/Koyomi/Job.pm line 69
6月 20 23:59:00 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:59:00 [DEBUG] no need to update schedule at lib/App/Koyomi/Schedule.pm line 42
6月 20 23:59:00 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:59:00 [DEBUG] 2015-06-20T23:59:00 Sat at lib/App/Koyomi/Schedule.pm line 67
6月 20 23:59:00 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:59:00 [INFO] 5595 1 USER=vagrant COMMAND="echo $(date) alive >> /tmp/tick.log" at lib/App/
6月 20 23:59:00 localhost.localdomain koyomi.sh[5414]: 2015-06-20T23:59:00 [INFO] 5595 1 Succeeded. at lib/App/Koyomi/Job.pm line 69

登録されたジョブが読み込まれ、実行されている様子がわかります。
/tmp/tick.log も見てみましょう。

$ cat /tmp/tick.log 
Sat Jun 20 23:58:00 JST 2015 alive
Sat Jun 20 23:59:00 JST 2015 alive
Sun Jun 21 00:00:00 JST 2015 alive
Sun Jun 21 00:01:00 JST 2015 alive
Sun Jun 21 00:02:00 JST 2015 alive
Sun Jun 21 00:03:00 JST 2015 alive
:

まとめ

CentOS 7 の環境に Koyomi をインストールし、systemd の service として動かしてみました。

Koyomi が動くこと、cron のように使えることがわかった(わかる)のではないかと思います。

ここでは SQLite の例を示しましたが、ジョブのデータストアとしてリモートサーバの MySQL を用いれば、ジョブの実行プロセスを冗長化することも出来ます。

Koyomi はまだ生まれたばかりのプロダクトなので、機能の不足などあるかと思います。
引き続き開発していくつもりですが、何かフィードバックがあれば是非お寄せ下さい。

Have fun!!

参考

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6