web-dev-qa-db-ja.com

systemdとプロセスの生成

普段はここに投稿しないでくださいね。私はPythonスクリプトが起動時にフォークし、他の多くのプロセスを開始する責任があります。このスクリプトは、sysvinitを介して起動時に起動されていましたが、最近、Debian Jessieにアップグレードしました。 systemd経由で起動するようにそれを適合させました。

残念ながら、解決できない問題が発生しています。ユーザーシェルでスクリプトを直接起動すると、子プロセスが正しく起動され、スクリプトが終了すると、子プロセスは孤立し、実行を継続します。

Systemdを介して起動すると、親プロセスが終了すると、子もすべて終了します(まあ、画面は起動して死んで、Deadと表示されますか???)

理想的には、すべての子プロセスを強制終了せずに親スクリプトを再起動できるようにする必要があります。何か足りないものはありますか?

ありがとう!

[Unit]
Description=Server commander
After=network.target

[Service]
User=serveruser
Type=forking
PIDFile=/var/Server/Server.pid

ExecStart=/var/Server/Server.py
ExecStop=/bin/kill -s TERM $MAINPID

[Install]
WantedBy=multi-user.target

編集:Pythonスクリプトは基本的にその子プロセスの「コントローラー」であることを指摘することはおそらく関係があります。中央のサーバーからの要求に応じて、GNU画面でサーバーを起動および停止します。通常は常に実行されており、サービスを生成して終了しません。ただし、プロセスがpid 1に孤立している場合でも、子プロセスを強制終了せずにスクリプトを再ロードできるようにしたい場合があります。 Pythonスクリプトが親プロセスとしてプロセスを開始した場合でも、それが可能であれば問題はありません。

それがどのように機能するかについてのより良い説明:

  • Systemdは/Server.pyを生成します
  • Server.pyはSystemdのpidファイルをフォークして書き込みます
  • その後、Server.pyは、その指示に基づいて、GNU画面でサーバープロセスを生成します。
  • Server.pyは引き続き実行され、サーバーから要求された再起動を実行します

Systemdなしで起動すると、Server.pyを再起動でき、起動するgnu画面は影響を受けません。 System.dで起動すると、Server.pyがシャットダウンすると、それらのスクリーンプロセスがpid 1に孤立する代わりに、強制終了されます。

14
Bottswana

私は、KillModeをcontrol-group(デフォルト)の代わりにprocessに設定するだけでこれを修正することができました。皆さんありがとう

10
Bottswana

私はPythonスクリプトが起動時に分岐し、他の多くのプロセスを開始する責任があります。

これはあなたが間違ってそれをしていることを示しています。これについては後で詳しく説明します。

スクリプトが終了すると、子プロセスは孤立し、実行を続けます。

これは正しいデーモンの振る舞いではありません。 「メイン」プロセス—この場合、フォークした子、Type=forkingを指定したために終了した場合、systemdはサービスが非アクティブ化されたと見なし、(コントロールグループ内の)実行中の他のプロセスを終了します片付けるために。

Systemd rcスクリプトからsystemdへの変換は、systemdで行う正しい方法がまったく異なるため、簡単ではない場合があります。 systemdで(たとえば)OpenVPN、OpenStack、またはOSSEC HIDSを行う正しい方法は、rcスクリプトで行う方法とは異なります。分岐しているスクリプトがあり、その後、孫プロセスの負荷全体が生成され、それらの孫が実行し続けることを期待して終了するという事実は、レベルが2つ少ないにもかかわらず、ossec-controlと同じ種類の恐怖を犯していることを示しています。フォークの。 「有効」フラグをチェックし、システムの「有効」部分の子プロセスを実行する「マスター」スクリプトを作成している場合は、恐ろしいossec-controlと同じ間違いを犯しています。

Systemdでは、そのような自家製のメカニズムは必要ありません。それはすでにサービスマネージャです。 https://unix.stackexchange.com/a/200365/5132 によると、systemdでこの問題に対処する正しい方法は、 "sub"の奇妙で混乱した試みを生み出す1つのサービスを持つことではありません-services」。それは、それぞれの子プロセスを、それ自体で完全に本格的なsystemdサービスとして処理することです。次に、通常のsystemdコントロールを使用して、システムのさまざまな部分を有効化、無効化、起動、停止します。 OSSEC HIDSのケースでわかるように、単純なテンプレートサービスユニットはほぼすべてのサービスをカバーします(1つの例外は https://askubuntu.com/a/624871/43344 )サービスで、1つのことを許可しますsystemctl enable [email protected]などを使用して、オプションのagentlessdサービスを有効にします。System5 rcで必要だった恐ろしい「マスタースクリプト」メカニズムはまったく必要ありません。

OSSEC HIDSほど極端ではないかもしれませんが、そのような再考が必要なケースはたくさんあります。 eximやsendmailのようなMTSはその2つです。キューランナー、SMTP送信デーモン、SMTPリレーデーモンを生成する単一のrcスクリプトがあり、実行するものを正確に制御するために構成ファイルに一連のアドホックシェル変数が含まれている場合があります。しかし、systemdでこれを行う正しい方法は、3つの適切なサービスユニット(そのうちの2つがソケットを関連付けている)にすることですunits)アドホックなものは一切なく、サービスマネージャーの通常のメカニズムのみです。

5
JdeBP

親をスリープ状態にして、停止時にsystemdが殺すのを待つだけです。

0
Craig Hicks