L'exécution de cron python emplois au sein de docker
Je voudrais lancer un python tâche cron à l'intérieur d'un conteneur docker en mode détaché. Mon set-up est ci-dessous:
Mon script python est test.py
#!/usr/bin/env python
import datetime
print "Cron job has run at %s" %datetime.datetime.now()
Mon cron fichier est mon crontab
* * * * * /test.py > /dev/console
et mon Dockerfile est
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
Quels sont les problèmes potentiels de cette approche? Il existe d'autres approches et quels sont leurs avantages et leurs inconvénients?
- Idée intéressante. N'aurait pas pensé à cela, même si j'ai souvent exécuter cron dans des récipients à l'aide de supervisord.
- Je serais très intéressé de savoir comment vous le faire à l'aide supervisord. Merci!
- docs.docker.com/articles/using_supervisord
- J'ai un conteneur docker qui utilise les variables d'environnement lors de l'exécution d'une tâche de script python. Voici un lien pour ce que j'ai une réponse dans un autre post DONC, stackoverflow.com/a/41938139/5090330
Vous devez vous connecter pour publier un commentaire.
Plusieurs problèmes que j'ai rencontrés tout en essayant d'obtenir une tâche cron s'exécute dans un conteneur docker ont été:
Il y a cron-questions spécifiques et sont docker problèmes spécifiques dans la liste, mais en tout cas ils doivent être adressées à obtenir cron de travail.
À cette fin, mon travail actuel solution au problème posé dans la question est comme suit:
Créer un menu fixe le volume à laquelle tous les scripts en cours d'exécution en vertu de cron écrira:
Le script qui sera exécuté en vertu de cron est
test.py
:Afin de passer la variable d'environnement pour le script que je veux lancer sous cron, suivre la suggestion de Thomas et de mettre un crontab fragment pour chaque script (ou un groupe de scripts) qui a besoin d'un menu fixe variable d'environnement dans
/etc/cron.d
avec un espace réservéXXXXXXX
qui doit être réglé.Au lieu de l'appeler cron directement, enveloppez cron dans un script python qui ne fait les choses: 1. lit la variable d'environnement depuis le menu fixe variable d'environnement et définit la variable d'environnement dans une crontab fragment.
La
Dockerfile
que pour le conteneur dans lequel les tâches cron run est comme suit:Enfin, créer les conteneurs et les exécuter:
docker build -t test-logs .
docker run -d -v /t-logs --name t-logs test-logs
docker build -t test-cron .
docker run --detach=true --volumes-from t-logs --name t-cron test-cron
docker run -t -i --volumes-from t-logs ubuntu:latest /bin/bash
. Les fichiers journaux sont dans/var/log
.TEST_ENV=test-value cron -f -L 15
pas de travail pour la commande?RUN chmod 644 /etc/cron.d/cron-python
parce que "les fichiers dans /etc/cron.d doit être détenue par la racine, et ne doit pas être un groupe - ou d'autres-à l'écriture." [tiré de "l'homme cron']. Avant cela, moncron-python
fichier de groupe en écriture.Voici un complément sur rosksw réponse.
Il n'est pas nécessaire de faire une chaîne de caractères de remplacement dans le fichier crontab afin de passer des variables d'environnement pour les tâches cron.
Il est plus simple de stocker les variables d'environnement dans un fichier lors de l'exécution de la contrainer, puis les charger à partir de ce fichier à chaque exécution de cron. J'ai trouvé l'astuce ici.
Dans le dockerfile:
Dans le fichier crontab:
export $(cat /root/env-params | xargs)
à la charge de l'env par la suite. Puis il a travailléAjoutant crontab fragments dans
/etc/cron.d/
au lieu d'utiliser la racine ducrontab
serait peut-être préférable.Ce serait:
Observer que le format de ces fichiers est un peu différent d'une entrée crontab. Voici un échantillon de la distribution Debian package php:
Dans l'ensemble, à partir de l'expérience, l'exécution de cron dans un récipient fonctionne très bien (en plus de cron journalisation laissant beaucoup à désirer).
Voici une solution alternative.
dans
Dockerfile
dans
entrypoint.sh
-f
! Si vous ne le faites pas, vous obtenez un certain comportement bizarre, comme de ne pas être en mesure de shell dans la boîte. (docker exec
peut ne pas fonctionner)Nous utilisons ci-dessous la solution. Il supporte à la fois
docker logs
la fonctionnalité et la capacité à accrocher le cron processus dans le conteneur sur le PID 1 (si vous utiliseztail -f
solutions de contournement fournies ci-dessus - si cron se bloque, docker ne suivra pas le redémarrage de la politique):cron.sh:
Dockerfile:
crontab:
Et s'il vous plaît n'oubliez pas d'ajouter la chair de poule nouvelle ligne dans votre crontab
Seul Conteneur Méthode
Vous pouvez exécuter
crond
dans le même conteneur qui est faire quelque chose d'intimement liés à l'aide d'une image de base qui gère le PID 0, comme phusion/baseimage.Conteneur Spécialisé Méthode
Peut être plus propre serait d'avoir un autre Récipient associées qui passe juste
crond
. Par exemple:Dockerfile
crontab
Puis exécutez:
Remarque: Dans ce cas, il va exécuter le travail que
www-data
. Ne suffit pas de monter lecrontab
fichier en tant que volume, car il doit être détenue par desroot
avec seulement l'accès en écriture pourroot
, d'autrecrond
sera exécuté rien. Aussi, vous aurez à exécutercrond
commeroot
.Ne pas mélanger crond et votre image de base. Préférez utiliser une solution native pour votre langue (horaire ou crython comme dit par Anton), ou découpler il. Par découplage c'que je veux dire, de garder les choses séparées, de sorte que vous n'avez pas à maintenir une image tout à la fusion entre python et crond.
Vous pouvez utiliser Tasker, un groupe de coureur qui a cron (un planificateur de soutien, pour le résoudre, si vous voulez garder les choses découplés.
Ici un
docker-compose.yml
fichier, qui va exécuter certaines tâches pour vousIl suffit d'exécuter
docker-compose up
, et de le voir travailler. Voici la Tasker repo avec la documentation complète:http://github.com/opsxcq/tasker
Une autre possibilité est d'utiliser Crython. Crython vous permet de régulièrement planifier une fonction python à partir de l'intérieur d'un seul script python /processus. Il parvient même pas à comprendre cron syntaxe:
À l'aide de crython évite les divers maux de tête de la course crond à l'intérieur d'un conteneur docker - votre travail est maintenant un processus unique qui se réveille lorsqu'il en a besoin, qui s'intègre mieux dans le docker modèle d'exécution. Mais il a l'inconvénient de mettre le calendrier à l'intérieur de votre programme, ce qui n'est pas toujours souhaitable. Encore, il peut s'avérer pratique dans certains cas d'utilisation.
pip
est horriblement cassé (feux de n'importe quel travail à chaque seconde). Et leexpr
syntaxe de vous tromper, car il n'est pas compatible avec cron.schedule
paquet. github.com/dbader/schedulenohup
avec docker processus. Qui met le processus en arrière-plan et docker est probablement quitter quand le principal processus de premier plan se ferme.