2016.11.27この記事は約20分で読めます。Linux/Unixのプロセスを管理するpython製のOSSであるSupervisorを使っているソフトウェアに触れる機会があったのですが、あまり知識がなかったのでSupervisorについて調べてまとめてみました。ver4.0.0.dev0で確認しています。正確な記述を心掛けていますが、謝り等も含まれる可能性があるので、気づいた場合はご指摘または公式ホームページを参照ください。参考リンクSupervisorについてLinux/Unixのプロセスを管理するソフトウェアでPythonで開発されている。クライアント/サーバー型である。3.2以上で動作させられるよう計画されているとされており、Python2の環境での利用が推奨されている。(2016/11/10現在、githubのOverviewより)Windows環境はサポートされていない。プロセスがクラッシュした時、リスタートしてくれる。プロセスを自身のサブプロセスとして実行するので、Pidfileのようなプロセスの実態との不一致がない。サブプロセスをdaemon化しない。all”のようにグループに対してコマンドを実行してくれる。ShellやWebUIからプロセスの状態をコントロールでき、またXML-RPCインターフェースを持っている。supervisorを使っているソフトウェアとして、私が触れたことがある例では、HadoopディストリビューションCDHの管理ソフトウェアであるClouderaManager[2]http://www.cloudera.com/products/cloudera-manager.htmlがあります。Supervisorを構成するコンポーネントSupervisorを構成しているコンポーネントは以下。supervisord子プロセスをコントロールするサーバープロセス。設定ファイルは、/etc/supervisord.confでINI形式[3]https://en.wikipedia.org/wiki/INI_fileで記述する。supervisorctlクライアントプログラム。UnixドメインソケットやTCPソケット経由でsupervisordと対話する。設定は、[supervisorctl]セクションに記述する。Serversupervisorctlの機能をブラウザ経由で実行できるWebインターフェース。設定は、[inet_http_server]セクションに記述する。インストールpythonがインストールされていない場合は、まずpythonをインストールする必要がある。あとはsetuptoolsまたはpipでインストールできる。supervisorディストリビューションのパッケージの場合、例えばCentOSではyumでいける。以下はepel経由でインストールしている。supervisor以下のecho_supervisord_confコマンドで設定ファイルのsampleを確認でき、このテンプレートをベースに設定を記述していくことができる。以下でsupervisordのプロセスを起動する。FILE設定ファイルを指定。–nodaemonデーモン化しない、foregroundで動作させる。デフォルトでは、daemonで動作する。–helpヘルプを表示する。–user=USERプロセスownerをUSERにする。–umask=OCTALsupervisordが使うデフォルトマスク。例:022デフォルトは、022。–directory=PATHsupervisordがdaemonとして実行されるときにcdするPATH。–logfile=FILEログファイル。デフォルトで、$CWD/supervisord.log。–logfile_maxbytes=BYTESログファイルを指定されたBYTES(byte)でローテートする。デフォルトで、50MB。–logfile_backups=NUMログファイルがバックアップされる世代数。–loglevel=LEVELログレベル。例:trace、debug、info、warn、error、criticalデフォルトで、info。–pidfile=FILEpidを書くファイル。デフォルトで、$CWD/supervisord.pid。–identifier=STRING現在のsupervisorインスタンスを識別できる任意の文字列。デフォルトは、supervisor。–childlogdir=PATHAUTO指定の子プロセスのログディレクトリ。–nocleanup起動時にAUTO指定の子プロセスのログを削除しない。–minfds=NUMsupervisordの利用可能なファイル記述子の上限(RLIMIT_NOFILE)を設定する。デフォルトは、1024。–strip_ansi子プロセスのログからANSIエスケープシーケンス文字を除去する。–versionバージョンを表示する。–profile_options=LISTプロファイルのためのオプションリストをカンマ区切りで指定する。supervisordはプロファイラの下で動作する。例:cumulative、calls、callers–minprocs=NUMsupervisordのプロセス生成数の上限(RLIMIT_NPROC)を設定する。各種Linux/Unixディストリビューションのinitスクリプトを公開してくれているので、環境に合わせてダウンロードして設置する。GitHub.github.comsupervisorctlの実行supervisorctlはコマンドラインツールで、supervisordに接続してプロセスの各種コントロール要求を送る。–configuration設定ファイルを指定する。デフォルトは、/etc/supervisord.conf。–helpヘルプを表示する。–interactive対話モードで起動する。引数なしでコマンドを実行するとpromptが起動する。URL接続するサーバープロセス(supervisord)のURL。デフォルトで、http://localhost:9001/。–usernameユーザー認証のユーザー名。–passwordユーザー認証のパスワード。shutdownサンプルプログラムをsupervisordで実行してみるまずは、簡単なサンプルプログラムを用意しsupervisor管理下で実行してみる。supervisord.conf設定はとりあえず最小限で以下のとおり。/path/to/hello.shprocess_name=%(program_name)sstdout_logfile=hello.logcommandのhello.shは以下。1done以上を準備し、supervisordをforegroundで起動してみる。上記実行後、127.0.0.1:9001でHTTPサーバーが起動しており、以下にアクセスするとWebUIを確認できる。アクセス時に認証を要求されるが、confで設定したuserとpasswordを指定すればよい。-fをクリックすると以下のような出力を確認できる。プロセス単体及びプロセスをまとめて起動・停止を行なうことができる。続いてsupervisorctlでアクセスしてみる。helpコマンドでコマンドリストが表示される。<command>でコマンド詳細を確認できる。infoここでは、先ほどのsampleプログラムを停止してみる。stopでプロセス名を指定しないとusageが表示される。続いてプロセス名を正しく指定して、stopコマンドを実行すると停止できる。stoppedWebUIでrunningとなっていたプロセスのステータスもstoppedになっていることを確認できる。プロセスが異常終了した場合もしプロセスが何らかの理由でダウンした場合、デフォルトの設定では再度プロセスを開始する。killコマンドでSIGTERMを送ってみる。(startsecs)続いてSIGSEGVを送ってみる。(startsecs)予期せぬ異常終了時にもプロセスがリスタートされていることを確認できた。本来はプロセスが異常終了しないように根本原因を特定し問題を解決する必要があるだろう。仮にプロセスが開始できなかった場合、リトライ回数の上限まで起動を試みた後fatal状態になる。1doneログには以下のように出力された。quickly数回リトライした後FATAL状態に移行し、プロセス開始が停止されたことを確認できる。以上サンプルプログラムをsupervisor経由で実行し、supervisorでプロセス管理するイメージを掴むことができた。運用ではsupervisord自体の監視が必要になるだろう。supervisordのシグナルハンドリングsupervisordがハンドリングするシグナルには以下のようなものがある。TERM、INT、QUITsupervisordとそのすべての子プロセスをshutdownする。以下はSIGTERMを送った例。pid)シグナルを受信したsupervisordは以下のようなログを出力する。SIGTERM)HUPすべての子プロセスを停止し設定をリロード、続いてプロセスを開始する。pid)シグナルを受信したsupervisordは以下のようなログを出力する。(startsecs)USR2メインとすべての子プロセスのログを再オープンする。pid)シグナルを受信したsupervisordは以下のようなログを出力する。logreopensupervisord.confsupervisord関連の設定はこのconfに記述していくことになる。読み込みの優先順位や主なセクションについてまとめる。詳細は、本家の公式ドキュメントまたはソースのoptions.pyを参照のこと。設定ファイルは、以下の順で探索される。<supervisor_bindir>/etc/supervisord.conf<supervisor_bindir>/supervisord.confsupervisord.confetc/supervisord.conf/etc/supervisord.conf/etc/supervisor/supervisord.conf’[unix_http_server]セクションUnixドメインソケットでlistenするHTTPサーバーの設定。None[inet_http_server]セクションTCPソケットでlistenするHTTPサーバーの設定。listenするhost:port。None[supervisord]セクションsupervisordプロセスに関する設定。supervisorctl_historystatus、help、restartとコマンド実行して見た結果、以下の履歴が保存される。sample[program:x]セクションsupervisord管理下で動作させるプログラムの設定。xにはプログラムを識別する任意の文字列を指定する。2の場合%(process_num)02dは、02、03となる。起動、停止における優先度。autorestartオプションのunexpectedで使われる終了コード。このリストにない終了コードでプロセスが終了した場合、自動再起動がかかる。プロセスグループに対してstopsignalを送信する。この値がfalseの場合。サブプロセスが実行されている場合はリペアレンティングされる。プロセスグループに対してSIGKILLを送信する。デフォルトでは、stopasgroupと同じ値となる。trueの場合、プロセスの標準エラー出力は標準出力にリダイレクトされる。trueの場合、プロセスがstdoutに書き込む時にPROCESS_LOG_STDOUTイベントが送られる。trueの場合、プロセスがstderrに書き込む時にPROCESS_LOG_STDOUTイベントが送られる。プロセスと対話するサーバーURLプロセス中では、環境変数でSUPERVISOR_SERVER_URLとして参照できる。999その他にも設定項目がありますが疲れたのでここで。stopasgroupオプションの動作について確認stopasgroupオプションはデフォルトでfalseだが、trueにした状態でプロセスからサブプロセスを実行して親プロセスにシグナルを送出してみる。"parent"続いて、supervisord.confを以下のようにする。truesupervisordを起動する。supervisordプロセスツリーを確認する。/tmp/hello-child.shサププロセスとして実行されていることを確認できる。続いて、supervisorctlからstopコマンドでSIGTERMを送る。sample2pstreeでgrepしても確認できないので、親・子プロセスとも停止している。falseにして実行して同様な操作をしてみたところ以下のようにリペアレンティングされていることを確認できる。stopでなく端末からシグナルを送ってみる。/tmp/hello-child.sh続いてSIGTERMを送る。53171親プロセスは変わっていることを確認できる。見つかりませんでした。コメントをキャンセルメールアドレスが公開されることはありません。»タイトルとURLをコピーしました。