Docker offers several advantages: it packages dependencies up cleanly, it enables repeatable deployments, and it shares physical host resources more flexibly than virtual machines. One thing it cannot do, however, is run a task on a schedule.
There are a range of solutions to this problem. Sometimes, the simplest solution is to use the host’s scheduling services to run a container at the right time. You can do this using the system
cron command, or, if you’re living on the edge, Kubernetes has an alpha-status scheduling facility.
You can also solve the problem by adding some extra software to your Docker image, such as one of the implementations of
cron. This has a significant drawback:
cron has its own dependencies. Most implementations rely on sending an e-mail to notify administrators of job status, whereas the Docker approach is to log to standard out and let the Docker daemon send this on to some other facility.
Most implementations also rely on a system logging service such as
syslog. Often, the problem is solved through either a simple in-application schedule facility, or running some lightweight cron-like wrapper process.
There’s another wrinkle to consider here. The first process to run inside a Docker container has process ID 1, and carries the responsibilities of process ID 1. Ordinarily, this is handled by
init, but there is no
init process inside a Docker container. The chief responsibility of interest is that of adopting orphaned child processes, and ensuring their exit status is collected so the operating system can reclaim their resources fully. An orphaned child process occurs when its parent terminates without having collected the child’s exit status, and shows up in Unix process lists as a zombie process.
To solve both problems at once, at APNIC we are using a statically linked binary tool to launch sub-processes according to a schedule, inside a Docker container. This tool is called Crocker: Cron in Docker. It is available on GitHub, and takes a single cron-like expression (including abbreviations such as
@daily) followed by the command to execute. Crocker will adopt any orphaned child processes and correctly collect their exit status, and will also respond to container shutdown signals and propagate those properly to all child processes.
Crocker is currently preview quality — it has not been well tested in a production setting. It’s a tool we expect to make some use of at APNIC, and have made available to the Internet community at large, where it may help solve similar problems.
We welcome feedback on Crocker and any suggestions for improvement over at Crocker’s Github page.
The views expressed by the authors of this blog are their own and do not necessarily reflect the views of APNIC. Please note a Code of Conduct applies to this blog.