さくらのクラウドのサーバの起動/停止をスケジューリングする
概要
以前同じ内容でこちらの記事を書いたのですが、このときは実行環境に AWS を使っていましたし、saklient というライブラリも公開が終了したようなので、作り直すことにしました。
以下の希望がある場合は、本処理が参考になる可能性があります。
- 検証用途などのサーバを業務時間外等に停止しておくことで課金額を抑えたい
手法
usacloudという CLIクライアントを利用して、対象となるサーバを特定し、起動または停止するスクリプトを作成します。
この処理を、cron で好きな時間帯に実行することで、自動化します。
今回は自前のサーバなどを用意しなくてもすむように、GitHub Actions を使用して、指定した時間帯で usacloud のコンテナを作成し、スクリプトを実行するようにしています。
注意事項
- スクリプトはあくまでもサンプルなので、必要に応じて修正ください。
- 全ゾーンを対象に、
myautostartstop
タグが付いたサーバを対象としています。 - 内閣府様の「国民の祝日」についてというサイトから、CSVをダウンロードして配置しておくことで、祝日を除外できるようにしてあります。ファイルに同じフォーマットで年月日を追加すれば、個別の休業日も除外可能です。
- usacloud の起動/停止コマンドでは、タグを指定して以下のように全ゾーンに対して一括実行することが可能です。ただし、すでに起動しているサーバに対して起動依頼をかけるとエラーレスポンスがあります(停止の場合は無いようです)。それが少し微妙だったので(実害があるわけでは無さそうですが)、スクリプトでは現在のステータスを確認して実行対象を限定するようにしています。停止時には
-f
(強制シャットダウン)をつけていますが、これも気になる場合は外してください。
usacloud server shutdown --zone all -y -f --no-wait myautostartstop
usacloud server boot --zone all -y --no-wait myautostartstop
基本的な流れ
-
GitHub のリポジトリを
プライベート
で作成してください。- パブリックで作成して公開してしまうと、ログが見えることになるので危険です。
-
該当リポジトリ内の Settings で、Secrets内の Actions に以下 Actions secrets を設定してください。
NameSAKURACLOUD_ACCESS_TOKEN SAKURACLOUD_ACCESS_TOKEN_SECRET
-
以下ファイルを配置してください。
startstop.sh#!/bin/bash HOLIDAYS=`cut -d ',' -f 1 ./syukujitsu.csv | sed -e '1d'` #HOLIDAYS=`curl -sS https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv | awk -F',' 'NR>1 {print $1}'` TODAY=`TZ='Asia/Tokyo' date "+%Y/%-m/%-d"` TARGET_TAG="myautostartstop" TASK=$1 SERVERSTATUS="up" POWERCOMMAND="boot" if [ "$TASK" = "start" ]; then SERVERSTATUS="down" POWERCOMMAND="boot" elif [ "$TASK" = "stop" ]; then SERVERSTATUS="up" POWERCOMMAND="shutdown -f" else echo "Usage: startstop.sh start|stop" exit 0 fi echo ${HOLIDAYS} | grep ${TODAY} > /dev/null if [ ${?} -eq 0 ] ; then echo "today is holiday" exit 0 fi for Zone in tk1a tk1b is1a is1b do echo "---- List Target Servers of $Zone ----" ServerIds=`usacloud server ls --tags $TARGET_TAG --zone $Zone --query="map(select( .InstanceStatus==\"$SERVERSTATUS\" )) | reverse | .[].ID" --query-driver=jq | xargs` for ServerId in $ServerIds do echo "---- $ServerId ----" usacloud server $POWERCOMMAND --zone $Zone -y --no-wait $ServerId done done echo "---- Servers ----" usacloud server ls --tags $TARGET_TAG --zone all
.github/workflows/start.ymlname: StartServer on: # push: # branches: # - main schedule: - cron: '15 1 * * 1-5' jobs: node-docker: runs-on: ubuntu-latest container: #起動するコンテナイメージを指定 image: ghcr.io/sacloud/usacloud #指定のdockerイメージを使用 env: SAKURACLOUD_ACCESS_TOKEN: ${{ secrets.SAKURACLOUD_ACCESS_TOKEN }} SAKURACLOUD_ACCESS_TOKEN_SECRET: ${{ secrets.SAKURACLOUD_ACCESS_TOKEN_SECRET }} SAKURACLOUD_ZONE: "is1a" steps: #dockerコンテナ内でステップを実行 - name: Log usacloud version run: | usacloud -v #バージョンの確認 cat /etc/os-release #Linuxバージョンの確認 apk add --update --no-cache tzdata - uses: actions/checkout@v2 #次ステップでファイル読み込むのでクローンが必要 - name: Run a script run: sh ./startstop.sh start
.github/workflows/stop.ymlname: StopServer on: # push: # branches: # - main schedule: - cron: '15 9 * * 1-5' jobs: node-docker: runs-on: ubuntu-latest container: #起動するコンテナイメージを指定 image: ghcr.io/sacloud/usacloud #指定のdockerイメージを使用 env: SAKURACLOUD_ACCESS_TOKEN: ${{ secrets.SAKURACLOUD_ACCESS_TOKEN }} SAKURACLOUD_ACCESS_TOKEN_SECRET: ${{ secrets.SAKURACLOUD_ACCESS_TOKEN_SECRET }} SAKURACLOUD_ZONE: "is1a" steps: #dockerコンテナ内でステップを実行 - name: Log usacloud version run: | usacloud -v #バージョンの確認 cat /etc/os-release #Linuxバージョンの確認 apk add --update --no-cache tzdata - uses: actions/checkout@v2 #次ステップでファイル読み込むのでクローンが必要 - name: Run a script run: sh ./startstop.sh stop
-
start.yml
およびstop.yml
にあるとおり、日本時間の月~金の 10:15頃に起動し、18:15頃に停止するようになっていますので、必要に応じて実行時間を変更してください。schedule: - cron: '15 1 * * 1-5' schedule: - cron: '15 9 * * 1-5'
- 必ずしも時間通りに実行されるかはわかりませんので、気になる場合は実行タイミングを複数作るか、負荷の少なそうな時間帯を探すか、おとなしく自前の実行環境を用意した方がいいかもしれません。
- 実行時間については公式の情報も参照ください。
ノート: scheduleイベントは、GitHub Actionsのワークフローの実行による高負荷の間、遅延させられることがあります。 高負荷の時間帯には、毎時の開始時点が含まれます。 遅延の可能性を減らすために、Ⅰ時間の中の別の時間帯に実行されるようワークフローをスケジューリングしてください。
サンプルログ
起動時のログを確認すると、以下のように見えます。
このときは 2つのサーバが対象になっていて、問題無く起動されています。
なお停止時は、InstanceStatus が cleaning など、途中の状態になっていることもありました。
--no-wait
をつけてコマンドを実行しているためです。
Run sh ./startstop.sh start
---- List Target Servers of tk1a ----
---- List Target Servers of tk1b ----
---- ***********0 ----
---- ***********9 ----
---- List Target Servers of is1a ----
---- List Target Servers of is1b ----
---- Servers ----
+------+--------------+-----------------------------------+-------------------------+-----+--------+-----+-------------------+----------------+----------------+----------------+
| Zone | ID | Name | Tags | CPU | Memory | GPU | IPAddress | Upstream(Mbps) | InstanceStatus | InstanceHost |
+------+--------------+-----------------------------------+-------------------------+-----+--------+-----+-------------------+----------------+----------------+----------------+
| tk1b | ***********9 | ****************************-a... | [@auto-reboot @group... | 1 | 2 | 0 | ***.**.***.***/24 | shared/100 | up | sac-tk1b-sv*** |
| tk1b | ***********0 | ****************************-a... | [@auto-reboot @group... | 1 | 2 | 0 | ***.**.***.***/24 | shared/100 | up | sac-tk1b-sv*** |
+------+--------------+-----------------------------------+-------------------------+-----+--------+-----+-------------------+----------------+----------------+----------------+
最後に
管理サーバを用意して cron で実行する方が確実なのですが、そこにお金をかけたくない・・・という場合には、こういった方法もお手軽でおもしろいかなと思います。
とはいえ、予定通りに実行されない結果、クラウドの課金が増えたら本末転倒なので、一長一短かもしれませんが。
サーバの作成も Terraform で実行している場合は、そのコードとまとめて管理することもできて、ちょうどよいかもしれません。
参考になれば幸いです。
どうぞよいさくらのクラウドライフを!
Author And Source
この問題について(さくらのクラウドのサーバの起動/停止をスケジューリングする), 我々は、より多くの情報をここで見つけました https://qiita.com/shztki/items/bfbd9c217ab224c35a18著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .