概要
Google Compute Engine で CoreOS イメージ(coreos-stable-1298-7-0-v20170401) を使ってインスタンスを作成すると,スタートアップスクリプトから docker コマンドが使えないような気がする.
Apr 21 12:20:59 xxx.internal rkt[1110]: + /usr/bin/google_metadata_script_runner --script-type startup
Apr 21 12:20:59 xxx.internal startup-script[1361]: INFO Starting startup scripts.
Apr 21 12:20:59 xxx.internal startup-script[1361]: INFO Found startup-script in metadata.
Apr 21 12:20:59 xxx.internal startup-script[1361]: INFO startup-script: /tmp/startup-qconLt/tmpI9QQlX: line 29: /usr/bin/docker: No such file or directory
Apr 21 12:20:59 xxx.internal startup-script[1361]: INFO startup-script: /tmp/startup-qconLt/tmpI9QQlX: line 33: /usr/bin/docker: No such file or directory
Apr 21 12:20:59 xxx.internal startup-script[1361]: INFO startup-script: Return code 1.
Apr 21 12:20:59 xxx.internal startup-script[1361]: INFO Finished running startup scripts.
仕方ないので, Ignition 経由で docker.service に依存するサービスとしてスタートアップスクリプトを送り込むことにした.(そもそもこっちが本来の使い方なのかもしれないが・・・)
Ignition
Ignition は cloud-init のように起動設定を簡略化してくれるツールで,cloud-init とは異なり設定を JSON フォーマットで渡す.Compute Engine の場合, この設定を user-data という名前のメタデータ経由で渡すことができる(参考: Ignition Config)
設定例はこの辺 にあるのだが,今回はスタートアップスクリプト用の Systemd サービス Unit が定義できれば良いので,
{
"ignition": { "version": "2.0.0" },
"systemd": {
"units": [{
"name": "example.service",
"enable": true,
"contents": "[Service]\nType=oneshot\nExecStart=/usr/bin/echo Hello World\n\n[Install]\nWantedBy=multi-user.target"
}]
}
}
この設定を編集して利用する.
units には,登録したい Systemd サービスの Unit を配列で指定する.各 Unit の設定は,name, enable, contents の三つの属性を持つオブジェクトとなっていて,各属性はそれぞれサービス名,enable にするか,そして unit ファイルの中身を表している.
スタートアップスクリプト用サービス Unit
Docker が起動した後に実行されるようにしておく.
[Unit]
Description=Startup Script
Requires=docker.service
After=docker.service
[Service]
ExecStartPre=-/usr/bin/docker stop myservice
ExecStartPre=-/usr/bin/docker rm myservice
ExecStart=/usr/bin/docker run --name myservice jkawamoto/myservice
ExecStop=/usr/bin/docker stop myservice
Restart=always
Type=simple
[Install]
WantedBy=multi-user.target
(参考: dockerコンテナをsystemdで管理させる)
この unit ファイルを登録するための Ignition config ファイルは次の通り.
{
"ignition": { "version": "2.0.0" },
"systemd": {
"units": [{
"name": "startup.service",
"enable": true,
"contents": "[Unit]\nDescription=Startup Script\nRequires=docker.service\nAfter=docker.service\n[Service]\nExecStartPre=-/usr/bin/docker stop myservice\nExecStartPre=-/usr/bin/docker rm myservice\nExecStart=/usr/bin/docker run --name myservice jkawamoto/myservice\nExecStop=/usr/bin/docker stop myservice\nRestart=always\nType=simple\n[Install]\nWantedBy=multi-user.target"
}]
}
}
あとは,このテキストデータを user-data という名前のメタデータとして渡せば良い.