web-dev-qa-db-ja.com

systemd-journald設定の再読み込み

なぜこれが起こっているのかわかりません。テストサービスで、10秒ごとにstdoutに任意のテキストを記録しています。これが私のサービスファイル/etc/systemd/system/samplego.serviceです。

[Unit]
Description=Sample go app
After=network.target

[Service]
SyslogIdentifier=my-samplego
ExecStart=/opt/samplego/samplego
Restart=on-failure

[Install]
WantedBy=multi-user.target 

これはうまく機能し、journalctlを使用してこれらのログ行を表示できます。

ただし、/etc/systemd/journald.confの設定を変更すると、e。 g。 forwardtosyslog=yesを発行してからsystemctl restart systemd-journaldを発行すると、アプリのロギングが停止し、journalctl -fが発行されるまでsystemctl restart samplegoに更新が表示されません。 journald再起動後にすべてのサービスを再起動する必要がありますか?

6
W Khan

1990年代中頃のデーモンツールの主要な革新の1つは、信頼できるロギングのアイデアでした。デーモン監督者は、2つのデーモン、mainデーモン、およびlogデーモン。どちらかを呼び出す前にパイプを開き、パイプの書き込み側をmainデーモンプロセスの標準出力として渡し、パイプの読み取り側をlogデーモンプロセスの標準入力。それまた自体も、パイプの両端に開いたファイル記述子を保持していました。そのため、ログデーモンが終了したか、終了してから再起動した場合、パイプに書き込まれたログデータは保持され、ログデーモンの新たに再起動されたインスタンスによって読み取られ、ログに記録されます。これは、パイプが閉じられないためです。

Systemdの設計者は、この設計から学びませんでした。

systemdは、構成されている場合、生成されたサービスプロセスを調整して、標準出力をソケット経由でジャーナルプロセスに送信します。しかし、daemontoolsの場合のように、パイプを開いて各プロセスがパイプの適切な終端を継承するように調整するのではなく、systemdAF_LOCAL/run/systemd/journal/stdoutストリームソケットを使用します。メインプロセスはクライアントとして接続します。ログプロセスはサーバーとしてリッスンします。

つまり、データ接続には、継承されたパイプセマンティクスではなく、クライアント/サーバーソケットセマンティクスがあります。サーバーが停止すると、接続が切断されます。バッファされたログデータはすべて失われ、メインデーモンによって書き込まれたすべてのそれ以上のデータは閉じたソケットに移動して失われます。 (これは、systemdがデフォルトでtrueに設定されているIgnoreSIGPIPE設定を使用している理由の一部です。ログ出力を閉じたソケットに書き込むまた、カーネルがログを書き込んでいるデーモンを殺そうとします。)

したがって、systemd-journaldプロセスを強制終了すると、プロセス出口は、ログに記録しているすべてのデーモンプロセスへのソケット接続を閉じ、それ以降のすべての出力は失われます。これから回復し、メインプロセスの出力をログプロセスに再接続する方法はありません。すべてのメインプロセスを再起動して、systemdnewクライアント接続を(新しく作成された)ログに再度開くようにする必要があります。サーバ。

Systemdの人々は2016年にこの問題を回避するための準備を整えました。これには、プロセスが自分で選択した任意のオープンファイル記述子をプロセス#1にプッシュし、後でプルする機能を追加することが含まれます。 systemd-journaldは、ログに記録しているクライアントへのサーバー側の接続でこれを行うため、ログ記録デーモン自体を再起動してもクライアントは開いたままになります。

このメカニズムの問題は、セキュリティを確保するためにさらに多くの作業が必要であり、今年だけのイベントが実証しているように、セキュリティで保護するものを設計することに関してsystemdの人々は良い実績がないということです。 whowhatおよびいくつファイル記述子をプロセス#1にオープンし、どれだけが必要かアクセス制御および制限付き。そうでなければ、可能性のあるエクスプロイトがたくさんあります。 (daemontools設計では、サービスマネージャープロセス自体がファイル記述子を開くものであるため、子プロセスのために開いたままにしているファイル記述子を完全に制御します。だまされたり、悪用されたり、フラッディングされたりすることはありません。)

Laurent Bercotのs6では、s6-svscanは通常のdaemontoolsをメインサービスとログサービスの間のパイプで実行します。また、任意のファイル記述子を開いたままにするメカニズムも備えています。これは、systemdのように、プロセス#1のサービスマネージャー内でスーパーユーザー権限で実行されているコードでは行われません。これは、サービスマネージャとは別に実行される完全に特権のないプロセスによって行われます。

参考文献

14
JdeBP