In days of virtualization, resource optimization are DevOps developers topic of obsession.
With great Pros would come some Cons…
Some tasks that used to be straightforward for Sysadmins, could be something more elaborate to solve in dockerized environments.
In this post I will show you how to deal with Cron jobs which helps keep our resource optimization as efficient as possible.
Let’s say that we have a Magento project, that needs to run maintenance tasks like reindex database.
Most of you would say: just create a container based on Official Linux image (e.g. Ubuntu) and use the crond.
While this is perhaps the easiest option, it is not as effective in terms of resource optimization and development time. Docker does not allow us to run scripts from one container to another as a security measure which means you have to find ways to expose each and every script you want to be ran by cron.
In our example, the crontab can looks like:
*/30 * * * * docker exec mage-container sh -c "/usr/local/bin/php /code/crontab/scripts/test_cron.php >> /var/log/cron.log 2>&1
If you are using an orchestration system like Kubernetes, the previous solution is not valid anymore because it generate containers with dynamic names.
Most of you would say “Add a new container based on any cron image and run jobs there”. But, again, the security constraint of Docker does not allow us to run scripts placed in mage-container.
Don’t panic, there’s still a way to execute scripts in other container, we just need to expose them via TPC, then we can invoke them using tools like cURL.
version: '2.1'
services:
cron:
image: docker-alpine-cron:latest
container_name: my-cron
env_file: ./environment.env
volumes:
- crontab.data:/etc/cron.d/crontab
As a word of caution, be very careful with security holes or backdoors! You will have to take care of the networking settings to prevent request from sources that don’t come from your cron container.
Even though the cron container sounds promising, I choose to add an entrypoint script to my php container, where I installed only cron and syslog instead of full image. With this small tweak I’m able to run scheduled php scripts in the php container.
...
mage-php:
image: php-fpm
service: php
container_name: mage-php
env_file: ./environment.env
volumes:
- ../magento:/code
entrypoint: "/scripts/php/crons_local.sh"
...
crons_local.sh
#!/bin/sh
# hack to fix wrong size issue
rm -f /var/lib/apt/lists/deb.debian.org_debian_dists_jessie_main_binary-amd64_Packages.gz
apt-get update
apt-get install -y cron rsyslog
# init crontab jobs
cp /code/crontab/mywu.cron /var/spool/cron/crontabs/root
chmod -R 0600 /var/spool/cron/crontabs/root
# enable separated cron log file
sed -i '/cron/s/^#//g' /etc/rsyslog.conf
# starting services
/etc/init.d/rsyslog start
/etc/init.d/cron start
This is my method of running a resource efficient cron job. I hope you find it useful. As with many things in DevOps, it may not be perfect but it gets the job done. If you have a better approach that has been working for you let me know.
Lets talk!
Join our mailing list, we promise not to spam.