2016年1月2日土曜日

systemdでの起動処理時にネットワークに接続される前に何かをしたい

あけましておめでとうございます。

このエントリの続きでございます。

さて、先ほど作ったスクリプトをsystemdが採用されているCentOS7で/etc/rc.d/init.d/に放り込まないで起動時に処理させたいと思います。
そのスクリプトとは、ネットワークに接続する前に前処理をしたい、というスクリプトです。

CentOS7の場合(以下同様)、/etc/rc.d/init.d/networkが存在していて、そのファイルには
# chkconfig: 2345 10 90
と記述されています。

起動優先度に10が指定されているので9でも与えればいいのかなあ、と思いますが、折角ですからsystemdの起動スクリプト作法に従ってみたいと思います。

なお、これまで通りchkconfigでいけるのか!!とおもって10を指定するとこれまでは(スクリプトファイル名の関係で)NICが有効になる前に先に処理されていたのですが、CentOS7では/etc/rc.d/init.d/に置かれたスクリプトのはるか以前にNICがupされていました。/etc/rc.d/init.d/に置かれているスクリプトの処理順位はかなり低いのかもしれません。

で、これまで実行していたスクリプトをsystemd様のご指定の方法で起動の依存関係を設定してあげなければなりません。

とはいっても、systemd様が要求なさっていることは特に難しいことはありません。
単純にこれまで/etc/rc.d/init.d/配下で起動してたプロセスをsystemd様向けの定義体に書き直すだけのことです。

で、起動時一回だけネットワーク接続前にやりゃあいいわ、という単刀直入な要件の場合、まずは/etc/systemd/system/に以下の内容のようなファイルをおいてあげます。
ここではのちの説明のために、ファイル名をfoo.serviceとしておきます。
[Unit]
Description=このスクリプトのご説明。
Wants=default.target
Before=network.target
Before=network.service
Before=NetworkManager.service
Before=NetworkManager-dispatcher.service
Before=NetworkManager-wait-online.service
Before=network-online.target
[Service]
Type=oneshot
ExecStart=あなたが作ったスクリプト。ここには /etc/rc.d/init.d/xxxx start とした時と同じ処理を記述します。
RemainAfterExit=yes ←こいつはsystemctl status xxxx でかっこよく見せるかどうかです。
[Install]
WantedBy=default.target
Beforeがやたらと並んでいますが、CentOS7の場合ならではという事情もあると思います。
anacondaのしもべNetworkManagerが悪さ(?)をするからです。
サーバ機にいるのかこれ?という機能満載でCentOSは今日も絶好調なのでもしもyum updateしたときのために再有効化されてしまった時の用心のため指定しています。(サーバ機にtunedとかほんとにいるんかいなあ?redhatはデスクトップとサーバとどっちのほう向いているのかさっぱりわかりません)

ここは面倒なところで、各ディストリビューション毎にターゲット名やサービス名は変わってくると思います。
誤解を恐れずに言うならターゲットちゅうのはサービスの寄せ集め、サービスってのは個々のデーモンやら今回の起動時一回やればいいというような具体的な処理のことです。
従って、どういう処理をやるか、というのはサービスごとにまちまちに命名されますし、そのサービスを寄せ集めて命名したら、やっぱりまちまちの名前になりますから、ディストリビューションごとに方言ができてくる可能性は大です。したがって、ここはCentOS7の説明ですよ、としてご紹介するのが関の山です。

ちょいと脱線しましたが、要点をいうと、自分の処理が終わる前に起動しちゃダメヨ、という指定にBeforeを用いるだけです。
で、なにがダメなのか、という判断は各スクリプトによって変わるわけですが、今回はネットワークにつながる前にやりたいことがあるのよ、ということで、ネットワークがらみのtargetやserviceを軒並み指定します。実際にはここでBeforeに指定した各サービスやターゲットにもそれぞれ依存関係が定義されていますのでBeforeには1つ指定すればいいのですが、今後どう変わるかわかりませんので、保険として列挙しています。

Wants=は本来だったらNICのドライバのinsmodが終わったら的ななんかになると思いますが、はっきり言って今回はどうでもいいです。iptablesの操作先はNICドライバではないので。

さて、ファイルを書き終えたら、以前のコマンドでいうとchkconfig --add してあげなくてはいけません。
そのためのsystemdのコマンドは以下です。foo.serviceというのは先ほど便宜的に付けたファイル名です。実際にはfooだけでいいです。
systemctl enable foo.service
もし/etc/systemd/system/foo.serviceを編集しちゃったら、以下のコマンドでsystemdに変更したことを教えてあげてください:
systemctl reenable foo.service
これで次回起動時に実行されるようになります。

お疲れ様でした。

0 件のコメント:

コメントを投稿