Comment utiliser Cron avec vos conteneurs Docker –
L’exécution de tâches en arrière-plan selon une planification est une exigence standard des services backend. La configuration était simple – vous définiriez vos tâches dans votre serveur crontab
et appelle ça un jour. Voyons comment vous pouvez utiliser cron
lors de l’utilisation de Docker pour le déploiement.
La conteneurisation de vos services augmente la productivité des développeurs. Simultanément, cela peut vous laisser vous demander comment l’administrateur système traditionnel concerne la correspondance avec les concepts Docker. Vous avez plusieurs options lors de l’utilisation cron
avec des conteneurs Docker et nous les explorerons ci-dessous par ordre de pertinence. Avant de continuer, assurez-vous d’avoir créé une image Docker de votre application.
Sommaire
Utilisation du Crontab de l’hôte
Dans sa forme la plus élémentaire, vous pouvez toujours utiliser le cron
installation de l’hôte qui exécute votre moteur Docker. Assure-toi cron
est installé, puis modifiez le système crontab
comme d’habitude.
Vous pouvez utiliser docker exec
pour exécuter une commande dans un conteneur existant:
*/5 * * * * docker exec example_app_container /example-scheduled-task.sh
Cela ne fonctionnera que si vous pouvez être sûr du nom du conteneur à l’avance. Il est normalement préférable de créer un nouveau conteneur qui existe uniquement pour exécuter la tâche:
*/5 * * * * docker run --rm example_app_image:latest /example-scheduled-task.sh
Toutes les cinq minutes, votre système cron
l’installation créera un nouveau conteneur Docker en utilisant l’image de votre application. Docker exécutera le /example-scheduled-task.sh
script dans le conteneur. Le conteneur sera détruit (--rm
) une fois le script terminé.
Utilisation de Cron dans vos conteneurs
Utilisation de l’hôte crontab
rompt la conteneurisation de Docker car les tâches planifiées nécessitent une configuration manuelle sur votre système. Vous devrez vous assurer cron
est installé sur chaque hôte sur lequel vous déployez. Bien que cela puisse être utile dans le développement, vous devriez chercher à intégrer cron
dans vos services Dockerised lorsque cela est possible.
Les images de base Docker les plus populaires n’incluent pas cron
démon par défaut. Vous pouvez l’installer dans votre Dockerfile
puis enregistrez votre application crontab
.
Commencez par créer un nouveau crontab
fichier dans votre base de code:
*/5 * * * * /usr/bin/sh /example-scheduled-task.sh
Ensuite, modifiez votre Dockerfile
à installer cron
et enregistrez votre crontab
– voici comment faire cela avec une image basée sur Debian:
RUN apt-get update && apt-get install -y cron COPY example-crontab /etc/cron.d/example-crontab RUN chmod 0644 /etc/cron.d/example-crontab && crontab /etc/cron.d/example-crontab
Nous installons cron
et copiez notre base de code crontab
dans le /etc/cron.d
annuaire. Ensuite, nous devons modifier les autorisations sur notre crontab
pour s’assurer qu’il est accessible à cron
. Enfin, utilisez le crontab
commande pour faire connaître le fichier au cron
démon.
Pour terminer cette configuration, vous devrez modifier la commande ou le point d’entrée de votre image pour démarrer le cron
démon lorsque les conteneurs commencent à s’exécuter. Vous ne pouvez pas y parvenir avec un RUN
étape dans votre Dockerfile
car ce sont des étapes transitoires qui ne persistent pas au-delà de la phase de construction de l’image. Le service serait démarré dans le conteneur éphémère utilisé pour créer la couche, et non dans les conteneurs finaux exécutant l’image terminée.
Si la seule tâche de votre conteneur est d’exécuter cron
– dont nous discuterons plus en détail ci-dessous – vous pouvez ajouter ENTRYPOINT ["cron", "-f"]
à ton Dockerfile
pour le lancer comme processus de premier plan. Si vous devez conserver un autre processus au premier plan, tel qu’un serveur Web, vous devez créer un script de point d’entrée dédié (par exemple ENTRYPOINT ["bash", "init.sh"]
) et ajouter service cron start
en tant que commande dans ce fichier.
Séparer Cron des services de votre application
La mise en œuvre de la configuration décrite dans la section précédente fournit une solution plus robuste que de compter sur l’hôte crontab
. Ajout du cron
démon aux conteneurs qui servent votre application garantit que toute personne consommant votre image Docker aura automatiquement des tâches planifiées.
Cela entraîne néanmoins un mélange de préoccupations. Vos conteneurs se retrouvent avec deux responsabilités: premièrement, fournir les fonctionnalités de l’application, et deuxièmement, conserver cron
actif et exécutez les tâches planifiées. Idéalement, chaque conteneur devrait fournir une unité spécifique de fonctionnalité.
Dans la mesure du possible, vous devez exécuter votre cron
tâches dans un conteneur distinct de votre application. Si vous créez un backend Web, cela signifierait un conteneur pour fournir votre serveur Web et un autre qui s’exécute cron
au premier plan.
Sans cette séparation, vous ne pourrez pas utiliser un orchestrateur tel que Docker Swarm ou Kubernetes pour exécuter plusieurs réplicas de votre application. Chaque conteneur exécuterait son propre cron
démon, provoquant l’exécution de tâches planifiées plusieurs fois. Cela peut être atténué en utilisant des fichiers de verrouillage liés à un volume Docker partagé. Néanmoins, il est plus facile de résoudre le problème racine et d’introduire un conteneur dédié pour le cron
démon.
En règle générale, vous souhaiterez que les deux conteneurs soient basés sur l’image Docker de votre application. Ils auront chacun besoin de connexions aux volumes et réseaux Docker de votre service. Cela garantira le cron
container a un environnement identique au conteneur d’application, la seule différence étant le processus de premier plan.
Ce n’est pas une règle absolue – dans certains projets, vos tâches planifiées peuvent être des scripts triviaux qui fonctionnent indépendamment de votre base de code. Dans ce cas, le cron
le conteneur peut utiliser une image de base minimale et supprimer les connexions à des ressources périphériques inutiles.
Une façon d’obtenir la configuration avec un cron
conteneur serait à utiliser docker-compose
. Vous définiriez le cron
conteneur comme service supplémentaire. Vous pouvez utiliser l’image de base de votre application, en remplaçant la commande entrypoint pour démarrer le cron
démon. En utilisant docker-compose
simplifie également la connexion du conteneur à tous les volumes et réseaux partagés dont il a besoin.
version: "3" services: app: image: demo-image:latest volumes: - data:/app-data cron: image: demo-image:latest entrypoint: /bin/bash command: ["cron", "-f"] volumes: - data:/app-data volumes: data:
En utilisant l’exemple ci-dessus, un conteneur sert notre application en utilisant le point d’entrée par défaut dans l’image. Assurez-vous que cela ne pas Commencer le cron
démon! Le deuxième conteneur remplace le point d’entrée de l’image pour s’exécuter cron
. Tant que l’image a encore cron
installé et votre crontab
configuré, vous pouvez utiliser docker-compose up
pour faire apparaître votre demande.
Utilisation de tâches Cron Kubernetes
Enfin, examinons un exemple simple d’exécution de tâches planifiées dans Kubernetes. Kubernetes est livré avec son propre CronJob
ressource que vous pouvez utiliser dans vos manifestes.
Vous n’avez pas besoin d’installer cron
dans votre image ou configurez des conteneurs spécialisés si vous utilisez Kubernetes. Soit conscient que CronJob
est une ressource bêta qui pourrait changer dans les futures versions de Kubernetes.
apiVersion: batch/v1beta1 kind: CronJob metadata: name: my-cron namespace: my-namespace spec: schedule: "*/5 * * * *" concurrencyPolicy: Forbid jobTemplate: spec: template: spec: containers: - name: my-container image: my-image:latest command: ["/bin/bash", "/my-cron-script.sh"] restartPolicy: OnFailure
Appliquez le manifeste ci-dessus à votre cluster pour créer un nouveau cron
travail qui s’exécutera /my-cron-script.sh
dans votre conteneur toutes les cinq minutes. La fréquence est donnée comme un cron
définition à la schedule
clé dans la ressource spec
.
Vous pouvez personnaliser le ConcurrencyPolicy
pour contrôler si Kubernetes autorise le chevauchement de vos tâches. Il est par défaut Allow
mais peut être changé en Forbid
(empêcher le démarrage de nouveaux travaux alors qu’il en existe déjà un) ou Replace
(mettre fin à un travail existant dès qu’un nouveau commence).
L’utilisation de la ressource intégrée de Kubernetes est la méthode recommandée pour gérer les tâches planifiées au sein de vos clusters. Vous pouvez facilement accéder aux journaux de tâches et ne pas avoir à vous soucier de la préparation de vos conteneurs pour une utilisation avec cron
. Il vous suffit de produire une image Docker contenant tout ce dont vos tâches ont besoin pour s’exécuter. Kubernetes gérera la création et la destruction d’instances de conteneur selon la planification que vous spécifiez.