Startup script cannot find docker command in CoreOS

Posted: , Modified:   Google Cloud Platform CoreOS Ignition

Summary

Startup scripts running on a Google Compute Engine instance with CoreOS (coreos-stable-1298-7-0-v20170401) image seems not to be able to find docker command since the following log messages have been outputted:

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.

We should use Ignition and launch a startup service instead of sending a startup script in order to use docker command.

Ignition

Ignition is a tool to set up a cloud instance like cloud-init but the format of configuration files is JSON. In Google Compute Engine, we can send a configuration via metadata with key user-data.

We are now interested in running a startup script. To this purpose, we will setup a Systemd’s unit which runs a script. Ignition configuration has an element to setup Systemd and the format is like the following:

{
  "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 takes a list of service unit definitions. Each unit has three elements: name, which will be used as a file name to store the unit configuration to a file; enable; and contents, which is the content of the unit file.

Service unit for a startup script

Our startup script service needs docker; the service requires docker.service and running after docker.service runs. The following service configuration specifies the above requirements:

[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

Finally, the ignition configuration which setups the above service is like the following:

{
  "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"
    }]
  }
}

When we creates an instance on Google Compute Engine, we will send the above JSON text as metadata with key user-data.

References