web-dev-qa-db-ja.com

ネットワークの開始後にスクリプトを実行させますか?

私はsystemdに比較的慣れておらず、そのアーキテクチャを学んでいます。

現在、カスタムシェルスクリプトを実行する方法を理解しようとしています。このスクリプトは実行する必要がありますネットワーク層が起動しました。

私はsystemctlとnetctlを使用してArchを実行しています。

テストするために、ip addr list > /tmp/ip.txtを実行するだけの簡単なスクリプトを作成しました。このスクリプト用に次のサービスファイルを作成しました。

(/etc/systemd/system/test.service)
[Unit]
Description=test service

[Service]
ExecStart=/root/test.script

[Install]
WantedBy=multi-user.target

次に、スクリプトを有効にしました。

systemctl enable test

再起動すると、スクリプトは実際に実行されますが、ネットワークが開始される前に実行されます。つまり、ip.txtの出力には、プライマリインターフェイスに割り当てられているIPv4アドレスは表示されません。ログインするまでに、IPv4アドレスが割り当てられ、ネットワークが稼働しています。

WantedByパラメーターをいじることでスクリプトの実行ポイントを変更できると思いますが、その方法はわかりません。

誰かが私を正しい方向に向けることができますか?

112
fdmillion

Systemdネットワーク構成の依存関係

Systemdのユニットの順序に影響を与えることは非常に簡単です。一方、完成したユニットが何を保証するかについて注意する必要があります。

サービスを構成する

現在のシステムでは、network.targetの後に注文しても、ネットワークサービスが開始されていることが保証されるだけであり、実際の構成があることは保証されません。あなたはnetwork-online.targetの後に注文し、それを実現するためにそれを引き込む必要があります。

[Unit]
Wants=network-online.target
After=network-online.target

古いシステムとの互換性のために、network.targetの後に注文する必要がある場合もあります。

[Unit]
Wants=network-online.target
After=network.target network-online.target

それはあなたのサービスのユニットファイルとsystemdのためです。

ソフトウェアの現在のバージョンでの実装

次に、network-online.targetが期待どおりに機能することを確認する必要があります(または、少なくともnetwork.targetを使用できることを確認してください)。

NetworkManagerの現在のバージョンはNetworkManager-wait-online.serviceを提供しており、これはnetwork-online.targetによって、つまりサービスによって取得されます。この特別なサービスにより、サービスは、開始するように構成されたすべての接続が自動的に成功、失敗、またはタイムアウトするまで待機します。

現在のバージョンのsystemd-networkdは、すべてのデバイスが要求どおりに構成されるまでサービスをブロックします。現在のところ、起動時に適用される構成(より具体的には、 `systemd-networkd.serviceの起動時)のみをサポートしているため、より簡単です。

完全を期すために、Fedoraの/etc/init.d/networkサービスは、systemdの現在のバージョンによって解釈されるように、network.targetをブロックし、したがってnetwork-online.targetとサービスを間接的にブロックします。これは、スクリプトベースの実装の例です。

デーモンベースかスクリプトベースかに関係なく、実装が上記のネットワーク管理サービスの1つとして動作する場合、ネットワーク構成が正常に完了するか、正当な理由で失敗するか、妥当な時間後にタイムアウトになるまで、サービスの開始を遅らせます完了するフレーム。

netctlが同じように機能するかどうかを確認することをお勧めします。その情報は、この回答への貴重な追加となります。

古いバージョンのソフトウェアでの実装

これがうまく機能しないsystemdの十分に古いバージョンが表示されるとは思いません。ただし、少なくともnetwork-online.targetが存在し、network.targetの後に注文されていることを確認できます。

以前はNetworkManagerは、少なくとも1つの接続が適用されることが保証されていました。そして、それが機能するためにも、NetworkManager-wait-online.serviceを明示的に有効にする必要があります。これはFedoraで長い間修正されましたが、最近アップストリームに適用されました。

systemctl enable NetworkManager-wait-online.service

Network.targetおよびnetwork-online.targetの実装に関するメモ

ソフトウェアをNetworkManager.serviceまたはNetworkManager-wait-online.serviceやその他の特定のサービスに依存させる必要はありません。代わりに、すべてのネットワーク管理サービスはnetwork.targetの前、およびオプションでnetwork-online.targetの前に自分自身を注文する必要があります。

単純なスクリプトベースのネットワーク管理サービスは、終了する前にネットワーク構成を完了し、network.targetの前に、したがってnetwork-online.targetの前に間接的にそれ自体を注文する必要があります。

[Unit]
Before=network.target

[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes

デーモンベースのネットワーク管理サービスも、あまり便利ではありませんが、network.targetの前にそれ自体を注文する必要があります。

[Unit]
Before=network.target

[Service]
Type=simple
ExecStart=...

デーモンが完了するのを待つサービスは、特定のサービスの後、network-online.targetの前に自分自身を注文する必要があります。デーモンサービスでRequisiteを使用して、それぞれのネットワーク管理サービスが使用されていない場合にすぐに失敗するようにする必要があります。

[Unit]
Requisite=...
After=...
Before=network-online.target

[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes

パッケージは、network-online.targetwantsディレクトリにある待機中のサービスへのシンボリックリンクをインストールして、構成されたネットワークを待機するサービスによって取得されるようにする必要があります。

ln -s /usr/lib/systemd/system/... /usr/lib/systemd/system/network-online.target.wants/

関連資料

最終メモ

あなたが質問したときにあなたの質問に答えるのを助けただけでなく、アップストリームとLinuxディストリビューションの状況の改善にも貢献して、元の質問を書いたときよりも良い答えを出せるようになれば幸いです。 。

138
Pavel Šimerda

[Unit]セクションのAfterを使用して、サービスを開始する前に開始する必要があるサービスを定義できます。たとえば、NetworkManagerを使用している場合、NetworkManagerの起動後にサービスを開始できます。

[Unit]
Description=test service
After=NetworkManager.service
9
phoops

サービスがサーバーを提供していて、誰かがサーバーに接続するのを受動的に待機できる場合は、これを使用します。

[Unit]
After=network.target

サービスはワイルドカードインターフェイスにバインドする必要があります。ソケットのアクティブ化を使用する場合(推奨)、またはローカルのみである場合は、ネットワークターゲットを完全に無視できます。

サービスがクライアントとして機能する場合、またはピアツーピアの場合、これはより適切です。

[Unit]
After=network-online.target
Requires=network-online.target

systemd 21 の前に、network-online.targetはPavelが述べた回避策が必要です(ネットワークが起動するのを待つサービスを手動で有効にする必要があります)。 systemd 213以降、これはデフォルトで行われます。 systemd-networkd-wait-onlineは、非ループバックインターフェイスで少なくとも1つのアドレス(ルーティング可能またはリンクローカル)が構成されるのを待ちます。

Systemd-networkd、NetworkManager、または同等の設定は、独立したタスクです。 DHCP(IPv4の場合)とNDP(IPv6の場合)はそのまま使用できる傾向がありますが、「ネットワークが稼働している」という正確な定義がトリガーとなるように構成する必要がありますnetwork-online.target

ドキュメンテーション:

8
Tobu

WantedByパラメータをいじることで、スクリプトが実行されるポイントを変更できると思います

それはあなたが望むものとは逆の効果があります。 man systemd.unitから:

WantedBy =、RequiredBy =

[...]このユニットがsystemctl enableによってインストールされると、リストされた各ユニットの.wants /または.requires /ディレクトリにシンボリックリンクが作成されます。これには、タイプWants =またはRequires =の依存関係がリストされている単位から現在の単位に追加されるという効果があります。

これに基づいて、適切な単位オプションは「Wants」または「Requires」であることがわかります。それらの説明に基づいて、「必要」はおそらく正しいです。「後」を追加して、ネットワークサービスが実行されるだけでなく、このユニットの前に実行されるようにします。

ユニットオプションのAFAIKには、開始された前提条件が完了している必要がある、または特定のポイントに到達している必要があるという条件(ネットワークはおそらくデーモンサービスである)を含めることはできませんstart最初。これを念頭に置いて、スクリプトをType=forkingにして、正常な遅延(たとえば30秒)、または遅延を含む何らかの成功時の終了ループを投入して、最初にDHCPリース。

4
goldilocks

[Unit]セクションのAfterを使用して、独自のサービスの前に何を開始するかを指定します。 (これまでの答えのこれは正しいです。)

ネットワークが稼働した後でサービスを開始するには、NetworkTargetを使用します。NetworkTargetは、NetworkManager、Archのconf.d/netctlシステム、またはsystemdが認識している他のサービスを使用するかどうかに適用されます。

[Unit]
#.....
After=network.target

簡単に見ると、ネットワーク接続に依存するシステム上のすべてのotherサービスにこのディレクティブが含まれていることが確認できます。

また、systemdを使用するどのディストリビューションにも移植可能です。ユニットファイルはArch、Fedora、RHEL 7、Debianの将来のバージョンで同じになります...


startネットワーク接続のサービス(Archのスクリプトや独自のサービスなど)は、their ownユニットファイルでそのように指定する必要があります。

[Unit]
Wants=network.target
Before=network.target
3
Michael Hampton

この記事にポイントを追加したかったのです。現在(2015年夏)RHEL7/CentOS 7では、IPv6ネットワークが起動する前にnetwork-online.targetが誤って設定されているため、

Wants=network-online.target
After=network-online.target

また、IPv6アドレスに明示的にバインドするサービス定義では、IPv6が起動して実行される前に開始され、失敗する可能性があります。

1
Colo Host
[Unit]
After=systemd-networkd.service

私のために働く。

0
Zhenxiao Hao