systemd から起動される cloud-init を手動で再実行したいときの手順。
環境
- CentOS 8.2.2004
- (CentOS-8-GenericCloud-8.1.1911-20200113.3.x86_64.qcow2 をベースに dnf update したもの)
- cloud-init-19.4-1.el8.7.noarch
再実行の手順
$ sudo systemctl stop cloud\*
$ sudo cloud-init clean
$ sudo systemctl start cloud-init.target
これだけで良さそう。状態確認の手順やもう少し詳細な動きについては以下を参照。
背景
とあるプロビジョニングツールでプロビジョニングをしようとしていたところ、cloud-init のユーザスクリプトの途中でよくわからない処理失敗が出ていたので、解析のために手動で再実行したい、というのが発端。
手動でcloud-initを再実行する手順は参考情報に情報があり、シェルから cloud-init コマンドを直接実行する手順が紹介されていたが、自分の場合 systemd 経由で再実行させたかった。
その理由は、プロビジョニングツールが systemd の環境変数に追加設定を行っているようで、シェルから実行した場合と環境変数設定が異なっているため。具体的には PATH とか。
# env | grep PATH
PATH=/sbin:/bin:/usr/sbin:/usr/bin
# systemctl show-environment | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
もちろんこれだけならシェルのPATH環境変数を設定するだけで良いのだけど、他にもどこで差異の影響が出てくるかわからなかったので、「systemdさんから実行してもらいたいなあ」と思った次第。
再実行例と確認手順
再実行前の段階では cloud-init 関連のサービスの状態は以下となっていた。
すべて Type=oneshot で実行されているらしい。
$ systemctl list-units --all cloud\*
UNIT LOAD ACTIVE SUB DESCRIPTION
cloud-config.service loaded active exited Apply the settings specified in cloud-config
cloud-final.service loaded active exited Execute cloud user/final scripts
cloud-init-local.service loaded active exited Initial cloud-init job (pre-networking)
cloud-init.service loaded active exited Initial cloud-init job (metadata service crawler)
cloud-config.target loaded active active Cloud-config availability
cloud-init.target loaded inactive dead Cloud-init target
cloud-init関連のサービスをいったん全部停止する。
$ sudo systemctl stop cloud\*
$ systemctl list-units --all cloud\*
UNIT LOAD ACTIVE SUB DESCRIPTION
cloud-config.service loaded inactive dead Apply the settings specified in cloud-config
cloud-final.service loaded inactive dead Execute cloud user/final scripts
cloud-init-local.service loaded inactive dead Initial cloud-init job (pre-networking)
cloud-init.service loaded inactive dead Initial cloud-init job (metadata service crawler)
cloud-config.target loaded inactive dead Cloud-config availability
cloud-init.target loaded inactive dead Cloud-init target
次に cloud-init 実行状態を初期化する。
cloud-initの実行状態は /var/lib/cloud
配下に保存されおり、ここをクリアしないと再実行されないらしい。参考情報ではこのディレクトリ配下を全部消したり instance だけ消したりする方法も紹介されているが、 cloud-init clean
コマンドが一番お行儀が良さそうなのでこれを採用。
$ ls /var/lib/cloud
data handlers instance instances scripts seed sem
$ sudo cloud-init clean
$ ls /var/lib/cloud
seed
$
そして cloud-init サービスを再実行する。再実行中の実行ログは /var/log/cloud-init-output.log
で確認できる。
$ sudo systemctl start cloud-init.target
$ systemctl list-units --all cloud\*
UNIT LOAD ACTIVE SUB DESCRIPTION
cloud-config.service loaded active exited Apply the settings specified in cloud-config
cloud-final.service loaded active exited Execute cloud user/final scripts
cloud-init-local.service loaded active exited Initial cloud-init job (pre-networking)
cloud-init.service loaded active exited Initial cloud-init job (metadata service crawler)
cloud-config.target loaded active active Cloud-config availability
cloud-init.target loaded active active Cloud-init target
$ tail -f /var/log/cloud-init-output.log
(...)
Cloud-init v. 19.4 running 'modules:final' at Thu, 27 Aug 2020 02:35:46 +0000. Up 88132.66 seconds.
Cloud-init v. 19.4 finished at Thu, 27 Aug 2020 02:36:33 +0000. Datasource DataSourceConfigDrive [net,ver=2][source=/dev/sda2]. Up 88180.39 seconds
cloud-init 関連サービスの補足
cloud-init 関連サービスは以下の依存関係の順序で起動されている模様。それぞれの処理を個別に確認したい場合にはサービスを順番に一つ一つ起動していけば良さそう(今回はそこまではやっていない)。
cloud-init-local.service
cloud-init.service
cloud-config.target
cloud-config.service
cloud-final.service
cloud-init.target
$ (cd /usr/lib/systemd/system/; grep "^After=.*cloud" cloud-* )
cloud-config.service:After=network-online.target cloud-config.target
cloud-config.target:After=cloud-init-local.service cloud-init.service
cloud-final.service:After=network-online.target cloud-config.service rc-local.service
cloud-init.service:After=cloud-init-local.service
$ (cd /usr/lib/systemd/system/; grep "^WantedBy=.*cloud" cloud-* )
cloud-config.service:WantedBy=cloud-init.target
cloud-final.service:WantedBy=cloud-init.target
cloud-init-local.service:WantedBy=cloud-init.target
cloud-init.service:WantedBy=cloud-init.target
$