2015/09/28

unicornとsidekiqをユーザレベルのsystemdで自動起動

lxcコンテナでRailsアプリである録画システムを動かすことに成功したので、永続化のためにコンテナの再起動時に自動起動するようにしたいわけです。

今までどおりなら、/etc/init.dに複雑な起動と停止のスクリプトを書くか、/etc/init.にupstart用のスクリプトファイルを置くのでしょうが、せっかく Ubuntu15.04 から systemd がデフォルトになったので、これを期にRailsアプリのデーモンをsystemdで扱えるようにしようと。

systemd/ユーザ
こちらを読むと、ユーザがログインした時に起動して、ログアウトで停止するようなサービスを定義できるらしい。更にそれをブート時に起動して、ユーザのログイン・ログアウトに依存しない永続化ができるらしい。これだぁ。

lxcコンテナでも、systemd --user デーモンがちゃんと稼働している。

今回デーモン起動したいサービスは、Railsのunicornとsidekiq。
これをsystemdのユーザサービスとして起動できるようにする。

systemdのサービスUnit定義ファイルを、ユーザのホームディレクトリの所定の場所に記述

SidekiqサービスUnitファイル .config/systemd/user/sidekiq.service

[Unit]
Description=Recman Sidekiq

[Service]
Type=forking
WorkingDirectory=%h/recman
ExecStart=/usr/local/bin/sidekiq -C ./config/sidekiq.yml -d

[Install]
WantedBy=default.target

UnicornサービスUnitファイル .config/systemd/user/unicorn.service

[Unit]
Description=Recman Unicorn

[Service]
Type=forking
WorkingDirectory=%h/recman
ExecStart=/usr/local/bin/unicorn_rails -D -c ./config/unicorn.rb -E development

[Install]
WantedBy=default.target

ExecStartは、デーモン起動したらすぐに終わるコマンドなので、Typeはforking。
Railsアプリのディレクトリに移ってから実行する必要があるので、WorkingDirectoryで指定する。
%hはユーザのホームディレクトリを示す変数。
インストール先は、default.target。systemd --userによって、defaut.targetユニットが予め存在するらしい。

とにかく、すごいシンプル!こんなでいいんだ。って感じ。

これらを登録して自動起動設定するまでの流れ
以降の操作はすべてユーザ権限で行える。systemctlに'--user'を付ける。

ユーザUnitファイルを読みこませる
$ systemctl --user daemon-reload

ちゃんと認識したか確認

$ systemctl --user list-unit-files

sidekiq.serviceとunicorn.serviceが、disableの状態でリストされる
ここまで行けば、手動での起動と停止ができるようになる

手動起動
$ systemctl --user start sidekiq
$ systemctl --user start unicorn

停止
$ systemctl --user stop sidekiq
$ systemctl --user stop unicorn

ExecStopを記述しなくても、停止させることが出来る。楽ちん。

自動起動するように有効化する

$ systemctl --user enable sidekiq
$ systemctl --user enable unicorn

再度確認してみた時の結果
ubuntu@recman:~$ systemctl --user list-unit-files
UNIT FILE            STATE   
sidekiq.service      enabled 
systemd-exit.service static  
unicorn.service      enabled 
basic.target         static  
bluetooth.target     static  
default.target       static  
exit.target          disabled
paths.target         static  
printer.target       static  
shutdown.target      static  
smartcard.target     static  
sockets.target       static  
sound.target         static  
timers.target        static

ubuntu@recman:~$ systemctl --user status unicorn
unicorn.service - Recman Unicorn
   Loaded: loaded (/home/ubuntu/.config/systemd/user/unicorn.service; enabled; vendor preset: enabled)
   Active: active (running) since 日 2015-09-27 17:59:14 JST; 15min ago
 Main PID: 1575 (ruby2.1)
   CGroup: /lxc/recman-1/user.slice/user-1000.slice/user@1000.service/unicorn.service

ubuntu@recman:~$ systemctl --user status sidekiq
sidekiq.service - Recman Sidekiq
   Loaded: loaded (/home/ubuntu/.config/systemd/user/sidekiq.service; enabled; vendor preset: enabled)
   Active: active (running) since 日 2015-09-27 17:59:12 JST; 15min ago
 Main PID: 1562 (ruby2.1)
   CGroup: /lxc/recman-1/user.slice/user-1000.slice/user@1000.service/sidekiq.service


永続化

ここまでだと、ログアウトと同時にユーザサービスは停止してしまうので、ブート起動して、ログイン/ログアウトに依存しない状態にする

$ sudo loginctl enable-linger

これでログアウトしても停止しなくなるし、lxcコンテナ起動時にサービスが開始される。
解除したい場合は、disable-lingerする。

$ sudo loginctl disable-linger

正直なところ、このloginctlとlingerがよく理解できていない。
enable-lingerするとセッションが壊れる危険性?があるということだが、どういうことなのか・・・

だけれど、とにかく、こうしたいっていう目的は達成である。

0 件のコメント:

コメントを投稿