Cron in a Pod

Vish
Airwalk Reply
Published in
2 min readMar 18, 2021
Photo by Aron Visuals on Unsplash

On a recent project, I came across a problem where I needed to run a cron job inside a pod.

The cron job had to connect to a database to do its thing and all the information required for the script was already available in the pod’s environment variables.

Now I know there is a Kubernetes CronJob resource that can be used, but this quick blog post is based on the use case of just a normal Linux cron job, inside a Kubernetes pod, that requires access to environment variables.

All the code is available here if required:

https://github.com/vishbhalla/cron-in-a-pod

Let’s run through a simple example. Below is noddy script that echoes the contents of an environment variable imaginatively called $MY_ENV_VARIABLE:

Below is a cron line that can be installed in Linux in order to run that script and output the results to a log file:

Now here is a Dockerfile that runs Ubuntu, copies the above files over, installs the cron job to run the script, and then tails the log file created by the cron job:

I’m working locally with minikube, so I can build via:

# eval $(minikube docker-env)
# docker build . -t echo_env

Lastly, here is a Kubernetes manifest that simply starts a pod with the above docker image, setting the value of our wonderfully named environment variable:

So we can now apply the manifest via:

# kubectl apply -f ./pod.yaml

And see the the output of the cron job every minute via:

# kubectl logs echo-env -f

As you can see:

* Starting periodic command scheduler cron
…done.
MY_ENV_VARIABLE is empty!

Why? Because Cron is designed to run in its own fresh shell, with limited environment variables. So we need to find a way of grabbing them from the pod’s environment, and making them available to the cron job.

One way to achieve this is to have the pod spit out all the environment variables into a file and make them available upon start up. Take a look at the ENTRYPOINT in the below Dockerfile:

I’ve excluded the environment variable LS_COLORS above simply because there are some special characters in it, and I didn’t need access it, so safer to just remove it.

Now we can edit the cron job to execute this file before running the script:

So after building our new docker image, and spinning up a new, updated pod, you should now see the variable being correctly reported in the logs:

* Starting periodic command scheduler cron
…done.
Hello from the environment

With this being a Ubuntu image, the better way to obtain the environment variables would be to stick them into /etc/environment via something like:

# env > /etc/environment

But I chose the approach I did as it should work with any Linux variant.

--

--