Amazon Linux 2 が起動してネットワークが有効になった後で自作スクリプトを実行する方法を調べてみた
はじめに
こんばんは、菅野です。
Amazon Linux を使っていた頃は、起動時にスクリプトを実行する場合に以下のどちらかを使っていたと思います。
- rc.local に記述する
- initd を利用する
今回のブログでは「Amazon Linux 2 として正しいお作法」を調べてみました。
条件としては「ネットワークが有効になった後」に実行されること、となります。
正しいお作法としては systemd を使う
Amazon Linux 2 では「systemd」を使いましょう。
実行したいスクリプトの他に一つのファイルを用意するだけで簡単に目的は達成できます。
用意するファイル
自作スクリプト
- ファイル名:/home/ec2-user/exec_ping.sh
- Owner:ec2-user
- パーミッション:755
- 説明:yahoo へ ping を撃ち、その結果を result.txt へ記録します
- 一つ目の引数でどこから起動されたかを、二つ目で start か stop を受け取るようにしています
#!/bin/bash rc=0 case "$2" in start) /usr/bin/echo >> /home/ec2-user/result.txt /usr/bin/echo $1 >> /home/ec2-user/result.txt /usr/bin/ping -c 1 www.yahoo.co.jp | grep "bytes from" >> /home/ec2-user/result.txt [ $? -ne 0 ] && rc=1 ;; stop) ;; esac exit $rc
systemd のユニットファイル
- ファイル名:/etc/systemd/system/test.service
- Owner:root
- パーミッション:644
- 説明:ネットワーク起動後に /home/ec2-user/exec_ping.sh を実行します
- Unit セクションに「After=network-online.target」を記述することでネットワーク起動後に実行されます
- Install セクションに「WantedBy=network-online.target」を記述することで依存関係を定義します
- その他オプションはこちらのページを参照してください
[Unit] Description=exec by systemd After=network-online.target [Service] Restart=no Type=simple RemainAfterExit=yes ExecStart=/home/ec2-user/exec_ping.sh systemd start ExecStop=/home/ec2-user/exec_ping.sh systemd stop [Install] WantedBy=network-online.target
自動起動の設定
ファイルを用意しただけではインスタンス起動時に「exec_ping.sh」は実行されません。
以下のコマンドを実行して自動起動されるように登録しましょう。
$ systemctl daemon-reload $ systemctl enable test
以下のコマンドで登録されたのかを確認します。
$ systemctl list-unit-files | grep test
うまく動いたか再起動後に確認
結果は「/home/eco-user/result.txt」に追記されてますので確認します。
systemd 64 bytes from 182.22.28.252 (182.22.28.252): icmp_seq=1 ttl=43 time=3.83 ms
systemd が実行した ping の結果が返ってきました。
結果
先ほど記載した systemd のユニットファイルを用意すれば、Amazon Linux 2 でネットワークが有効になった後に任意のスクリプトを実行することが可能です。
ここからは余談
今までの内容で、このページにたどり着いた皆さんの目的は達成されたかと思います。
ここから先は目的を達成された方には無関係な内容となりますが、見ても損しませんので引き続きどうぞ。
今までの方法は使える?
試してみましょう。 ということでいくつかのファイルを用意します。
rc.local 検証用ファイル
- ファイル名:/etc/rc.d/rc.local(既存ファイル)
- Owner:変更しない
- パーミッション:755(sudo chmod +x /etc/rc.d/rc.local を実行して変更)
- 説明:ファイルは存在しますので、以下の1行を追記します
/home/ec2-user/exec_ping.sh rclocal start
initd 検証用ファイル
- ファイル名:/etc/rc.d/init.d/init01(他に末尾10〜90、99も用意)
- Owner:root
- パーミッション:755
- 説明:ファイル内に「chkconfig」と書かれている部分の2番目の数字を変更して異なる実行優先度を指定する
- 書き換えるのは「chkconfig」の行とスクリプトを実行する行の1番目の引数(init10では「initd_10」とする)
#! /bin/bash # # test01 exec ping at 1 # # chkconfig: 2345 1 90 # description: exec /home/ec2-user/exec_ping.sh # # Source function library. . /etc/init.d/functions /home/ec2-user/exec_ping.sh initd_01 $1
再起動して結果を確認
再起動後に「/home/ec2-user/result.txt」を確認してみると以下のようになっていました。
initd_01 initd_10 rclocal 64 bytes from 183.79.219.252 (183.79.219.252): icmp_seq=1 ttl=42 time=8.15 ms systemd 64 bytes from 183.79.219.252 (183.79.219.252): icmp_seq=1 ttl=42 time=8.20 ms initd_20 64 bytes from 183.79.219.252 (183.79.219.252): icmp_seq=1 ttl=42 time=8.10 ms initd_30 64 bytes from 183.79.219.252 (183.79.219.252): icmp_seq=1 ttl=42 time=8.22 ms initd_40 64 bytes from 183.79.219.252 (183.79.219.252): icmp_seq=1 ttl=42 time=8.19 ms initd_50 64 bytes from 183.79.219.252 (183.79.219.252): icmp_seq=1 ttl=42 time=8.07 ms initd_60 64 bytes from 183.79.219.252 (183.79.219.252): icmp_seq=1 ttl=42 time=8.11 ms initd_70 64 bytes from 183.79.219.252 (183.79.219.252): icmp_seq=1 ttl=42 time=8.10 ms initd_80 64 bytes from 183.79.219.252 (183.79.219.252): icmp_seq=1 ttl=42 time=8.20 ms initd_90 64 bytes from 183.79.219.252 (183.79.219.252): icmp_seq=1 ttl=42 time=8.21 ms initd_99 64 bytes from 183.79.219.252 (183.79.219.252): icmp_seq=1 ttl=42 time=8.12 ms
余談の結果
- 今までの方法は、現時点の Amazon Linux 2 でも引き続き使える
- ネットワークは優先度10で実行されている
- /etc/rc.d/init.d/network で優先度が10となっていたので、この設定が利用されている様子
- init01と init10 は ping の応答が返ってきていない
- ネットワークが有効になっていないタイミングで実行された
- 同じ優先度なのに「network」より先に実行されたのはアルファベット順のため
- rc.local はネットワーク起動後に実行される
- systemd でネットワーク起動後を指定して実行するよりも rc.local の方が先に実行される
最後に
いかがでしたでしょうか。
起動時に実行する自作スクリプトは、ネットワークの準備ができた後で自動実行されることが望ましいことがほとんどかと思われます。
今回記述した systemd のユニットファイルが皆さんのお役に立てれば幸いです。
参考ページ
以下のページを参考にさせていただきました。
ありがとうございました。