在 docker 中运行 cron python 作业 [英] Running cron python jobs within docker
问题描述
我想以分离模式在 docker 容器内运行 python cron 作业.我的设置如下:
I would like to run a python cron job inside of a docker container in detached mode. My set-up is below:
我的python脚本是test.py
My python script is test.py
#!/usr/bin/env python
import datetime
print "Cron job has run at %s" %datetime.datetime.now()
我的 cron 文件是 my-crontab
My cron file is my-crontab
* * * * * /test.py > /dev/console
我的 Dockerfile 是
and my Dockerfile is
FROM ubuntu:latest
RUN apt-get update && apt-get install -y software-properties-common python-software-properties && apt-get update
RUN apt-get install -y python cron
ADD my-crontab /
ADD test.py /
RUN chmod a+x test.py
RUN crontab /my-crontab
ENTRYPOINT cron -f
这种方法有哪些潜在问题?还有其他方法吗?它们的优缺点是什么?
What are the potential problems with this approach? Are there other approaches and what are their pros and cons?
推荐答案
我在尝试在 docker 容器中运行 cron 作业时遇到的几个问题是:
Several issues that I faced while trying to get a cron job running in a docker container were:
- docker 容器中的时间是 UTC 而不是本地时间;
- docker 环境没有传递给 cron;
- 正如 Thomas 所指出的,cron 日志记录还有很多不足之处,通过 docker 访问它需要一个基于 docker 的解决方案.
列表中存在特定于 cron 的问题和特定于 docker 的问题,但无论如何都必须解决这些问题才能使 cron 正常工作.
There are cron-specific issues and are docker-specific issues in the list, but in any case they have to be addressed to get cron working.
为此,我目前对问题中提出的问题的工作解决方案如下:
To that end, my current working solution to the problem posed in the question is as follows:
创建一个 docker 卷,所有在 cron 下运行的脚本都将写入该卷:
Create a docker volume to which all scripts running under cron will write:
# Dockerfile for test-logs
# BUILD-USING: docker build -t test-logs .
# RUN-USING: docker run -d -v /t-logs --name t-logs test-logs
# INSPECT-USING: docker run -t -i --volumes-from t-logs ubuntu:latest /bin/bash
FROM stackbrew/busybox:latest
# Create logs volume
VOLUME /var/log
CMD ["true"]
将在 cron 下运行的脚本是 test.py
:
The script that will run under cron is test.py
:
#!/usr/bin/env python
# python script which needs an environment variable and runs as a cron job
import datetime
import os
test_environ = os.environ["TEST_ENV"]
print "Cron job has run at %s with environment variable '%s'" %(datetime.datetime.now(), test_environ)
为了将环境变量传递给我想在 cron 下运行的脚本,按照 Thomas 的建议,在 /etc/cron.d
带有必须设置的占位符 XXXXXXX
.
In order to pass the environment variable to the script that I want to run under cron, follow Thomas' suggestion and put a crontab fragment for each script (or group of scripts) that has need of a docker environment variable in /etc/cron.d
with a placeholder XXXXXXX
which must be set.
# placed in /etc/cron.d
# TEST_ENV is an docker environment variable that the script test.py need
TEST_ENV=XXXXXXX
#
* * * * * root python /test.py >> /var/log/test.log
不是直接调用 cron,而是将 cron 包装在一个执行以下操作的 python 脚本中: 1. 从 docker 环境变量中读取环境变量并在 crontab 片段中设置环境变量.
Instead of calling cron directly, wrap cron in a python script that does does things: 1. reads the environment variable from the docker environment variable and sets the environment variable in a crontab fragment.
#!/usr/bin/env python
# run-cron.py
# sets environment variable crontab fragments and runs cron
import os
from subprocess import call
import fileinput
# read docker environment variables and set them in the appropriate crontab fragment
environment_variable = os.environ["TEST_ENV"]
for line in fileinput.input("/etc/cron.d/cron-python",inplace=1):
print line.replace("XXXXXXX", environment_variable)
args = ["cron","-f", "-L 15"]
call(args)
运行cron作业的容器的Dockerfile
如下:
The Dockerfile
that for the container in which the cron jobs run is as follows:
# BUILD-USING: docker build -t test-cron .
# RUN-USING docker run --detach=true --volumes-from t-logs --name t-cron test-cron
FROM debian:wheezy
#
# Set correct environment variables.
ENV HOME /root
ENV TEST_ENV test-value
RUN apt-get update && apt-get install -y software-properties-common python-software-properties && apt-get update
# Install Python Setuptools
RUN apt-get install -y python cron
RUN apt-get purge -y python-software-properties software-properties-common && apt-get clean -y && apt-get autoclean -y && apt-get autoremove -y && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
ADD cron-python /etc/cron.d/
ADD test.py /
ADD run-cron.py /
RUN chmod a+x test.py run-cron.py
# Set the time zone to the local time zone
RUN echo "America/New_York" > /etc/timezone && dpkg-reconfigure --frontend noninteractive tzdata
CMD ["/run-cron.py"]
最后,创建容器并运行它们:
Finally, create the containers and run them:
- 创建日志卷(test-logs)容器:
docker build -t test-logs .
- 运行日志卷:
docker run -d -v/t-logs --name t-logs test-logs
- 创建 cron 容器:
docker build -t test-cron .
- 运行 cron 容器:
docker run --detach=true --volumes-from t-logs --name t-cron test-cron
- 检查在 cron 下运行的脚本的日志文件:
docker run -t -i --volumes-from t-logs ubuntu:latest/bin/bash
.日志文件位于/var/log
中.
- Create the log volume (test-logs) container:
docker build -t test-logs .
- Run log volume:
docker run -d -v /t-logs --name t-logs test-logs
- Create the cron container:
docker build -t test-cron .
- Run the cron container:
docker run --detach=true --volumes-from t-logs --name t-cron test-cron
- To inspect the log files of the scripts running under cron:
docker run -t -i --volumes-from t-logs ubuntu:latest /bin/bash
. The log files are in/var/log
.
这篇关于在 docker 中运行 cron python 作业的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!