CentOS7でinterfaceの起動時に任意のスクリプトを実行する

CentOSは5,6しか使ったことなかったのですが、何も考えずにサーバにCentOS7をインストールしたら何もかもが変わっていてびっくりしました。
とりあえずネットワーク周りの設定でハマったのと、日本語で情報がなかったのでメモ。
(結局はNetwork Managerが面倒くさいだけな気はするのですが。。)

例えば、あるinterfaceを起動したときに、同時にそれに関連するネットワーク設定ができると便利ですよね。
Debian等でれば、/etc/network/interfacesにこんな感じで書けば、interface起動時に好きなコマンドを実行できたりします。

しかし、CentOS7はNetwork Managerがすべてを握っているため、果たしてどこに書いてやれば良いのか。


具体的にやりたかったのは起動時にこの環境が立ち上がることです。
(enp4s0の起動と同時に作りたい)

  1. netnsを作成
  2. vethのペアを作成
  3. vethの片方をnetnsに紐付け
  4. vethの有効化

OpenvSwitchの設定関しては、一度設定すればOpenvSwitch側のデータベースに入るのでrebootしても同じ設定で起きてきます。
また、OpenvSwitchの設定的にはinterfaceの名前をもとにポートを紐付けているようなので、
毎回起動時に同じ名前でinterfaceを作ってあげればifindex等は変わっても良さそうです。

まずは準備、とは言ってもOpenvSwitchの設定だけ先に入れておくだけです。
OpenvSwitchの設定はこんな感じで。

では、本題、interfaceの起動時に環境設定スクリプトを走らせる方法です。

まず初めに、スクリプトの起点となるinterfaceだけNetwork Managerの呪縛を解いてあげます。
(これも色々試してみたのですが、上手く行ったのはこの方法だけでした。)

/etc/sysconfig/network-script/ifcfg-enp4s0にこんな感じで記述。
(最終行のNM_CONTROLLED=noといのが大事です)

で、nmcliを叩くとあら不思議、enp4s0がunmanagedになってNetwork Managerの呪いから解き放たれました。

この時点で、ifup(/sbin/ifup)によりInterfaceの起動が制御されるようになりました。
ifupはシェルスクリプトで書かれており、中身を覗くとコードの最後のほうで/etc/sysconfig/network-scripts/ifup-ethを読んでいることがわかります。

さらに/etc/sysconfig/network-scripts/ifup-ethを読んでみると、今度は最終行で/etc/sysconfig/network-scripts/ifup-postが呼ばれています。

さらにさらに、/etc/sysconfig/network-scripts/ifup-postの中で/sbin/ifup-localが第一引数にデバイス名を渡して呼ばれています

デフォルトでは/sbin/ifup-localは存在していないので、実行されませんが作ってあげると実行してくれます。
こんな感じで書いてあげます。

権限付与。

これで、rebootしてみると、interfaceの起動時(ifupが呼ばれたとき)にこのスクリプトが実行されてくれます。

手順と動作の仕組みさえ分かってしまえば簡単でしたね。

ここまで来るのに結構苦労してるので、以下はそのへんの余談。
Network Managerからinterfaceを解き放つのは、上記の方法以外はうまく行きませんでした。

[方法1]
Network Managerの設定ファイルにinterfaceを無視するように書いてみる。
 → Interfaceの設定ファイル(ifcfg-hoge)自体が消失します。
   ifupもこのifcfgの設定ファイルを見ているため、ファイルがないとifupで「そんなデバイス知らねぇ」と怒られてしまいます。

[方法2]
続いて、nmcliからmanagedを外す。
コマンドは至ってシンプルでこれだけ。

 → しかし一瞬外れたように見えますが、rebootすると結局managedに戻ります。

[方法3]
そもそもNetwork Managerから外す必要があるのか、
 → Network Managerで管理させていると起動処理にifupが呼ばれていない。
   さきほどのjournalctlのログでもNetwork Managerで管理しているenp5s0は先程のifup-localを通ってないことがわかります。
  (Network Managerが直接システムコールか何かを叩いているのか中身はよくわかりませんが)

[結論]
Network Managerの管理から外してあげると、ifupのスクリプトによってinterfaceが起動される。
(Network Managerで管理させている場合でも、OS起動後に手動でifup叩けば一応設定は入るはするのですがrebootのたびに手動オペレーションはめんどくさい)
Network Managerの管理から外すために、ここに書いたような手順でやると、rebootでもとに戻ったり、ifupが参照する設定ファイルが消えたりで他のところで影響がでる。

nmcliの出力とnetworkのログを読んでいて気づいたのですが、実はlo interfaceは最初からunmanagedです。
つまり、loは特になにも設定しなくてもifupによって起動され、さきほどの/sbin/ifup-localも呼ばれます。
これを利用して、lo interfaceの起動時に他のinterfaceの設定をやってしまう方法もありそうです。
が、ログを見る限り順番的にlo interfaceが最初に上がって、それ以外のinterfaceはそのあとNetwork Managerによって起動されそうな雰囲気。
今回はinterfaceそのものの設定を変更するスクリプトは書いてないので問題ないですが、interface設定をしたとしても上書きされて意味なしです。
(nmcli dev enp4s0 managed noを叩けばNetwork Managerが設定する頃にはunmanagedなので、無視してくれるかもしれませんが、あまりいい方法ではないと思ったので試してないです)

以上余談でした。

色々ハマったあげく、今はこの方法でうまく行ってます。
Network Managerのクセが強すぎて、たったこれだけのことでかなり苦戦しました。

何か他にいい方法を知ってる方がいれば教えてください。。

コメントを残す

Your email address will not be published / Required fields are marked *