この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
データアナリティクス事業本部の鈴木です。
EC2インスタンスの開始時およびAMI取得時などの停止時に、一緒にインスタンス内で稼働しているプログラムを決まった手順で開始・停止したいことがありました。今回はsystemdを使って実現できるか検証しました。Linuxにお詳しい方だと当たり前かもしれませんが、参考までにご共有します。
準備
前提条件
以下のAMIを使ってEC2インスタンスを作成し、検証を行いました。
- AMI ID: ami-0ab0bbbd329f565e6
用意したファイル
ec2-user
のホームディレクトリに、起動時・停止時に実行するための2つのスクリプトを作成しました。これらは実行されると同じディレクトリにあるtest.log
に時間を追記します。
まずは起動時です。
start.sh
#!/bin/sh
echo `date` >> test.log
echo "start" >> test.log
次に停止時です。停止時用は、停止がコマンド実行を待ってくれているか確認するため、30秒の待機を含んでいます。
stop.sh
#!/bin/sh
echo `date` >> test.log
sleep 30
echo `date` >> test.log
echo "stop" >> test.log
ホームディレクトリ配置した後は、実行権限をつけておきました。
chmod +x ./start.sh
chmod +x ./stop.sh
次にサービスファイルを準備しました。EC2起動時にサービスが開始されExecStart
で設定したコマンドを実行し、終了時にExecStop
で設定したコマンドを実行します。
start.sh
を実行してからstop.sh
を実行するまでをサービスの起動状態とした方が自然と思ったので、Type
はoneshot
として、RemainAfterExit
をyes
としました。
sample.service
[Unit]
Description=Start&stop sample service.
After=syslog.target network-online.target
[Service]
User=ec2-user
Type=oneshot
RemainAfterExit=yes
KillMode=none
ExecStart=/bin/bash -c 'cd /home/ec2-user; ./start.sh'
ExecStop=/bin/bash -c 'cd /home/ec2-user; ./stop.sh'
[Install]
WantedBy=multi-user.target
ExecStart
とExecStop
では、あえてbash -c
でディレクトリ移動とスクリプト実行の複数のコマンドを実行しています。これは必須ではなく、以下のような特定のディレクトリに移動してからコマンドを実行する必要があるケースを想定しました。もちろん、単一のコマンドで済む場合は、普通にコマンドを書いて問題ありません。
サービスの有効化
systemctl
コマンドでサービスの有効化をしておきます。また、動作確認のためサービスの開始もしておきました。
# サービスの有効化
sudo systemctl enable sample
# サービスの開始
sudo systemctl start sample
test.log
を確認すると、開始用のスクリプトが動いていることを確認できました。
やってみる
停止を伴う3つのケースで、期待通りにスクリプトが実行されるか確認してみました。
停止・起動した場合
まずインスタンスを停止しました。
インスタンスが停止状態になったことを確認して、インスタンスを開始しました。
30秒待機してから停止していることが確認できました。
再起動した場合
インスタンスを再起動しました。
このときも30秒待機してから停止していることが確認できました。
静止点AMIを作成した場合
アクション
> イメージとテンプレート
> イメージを作成
からイメージを作成しました。
このとき、再起動しない
は無効にしておきました(有効化
にチェックは入れないままにしておきました)。
このときも30秒待機してから停止していることが確認できました。
最後に
今回はsystemdを使ってEC2の起動時・停止時にコマンドを実行できるか検証しました。特に停止時は不定期に停止を行っても決まったコマンドを実行してくれるので役立つケースが多そうです。参考になれば幸いです。