docker - pas de crontab pour root

10

Mon Dockerfile semble se construire correctement (il me le dit). Lorsque j'exécute le conteneur, j'obtiens le message d'erreur ci-dessous. J'ai essayé d'exécuter les commandes ( CMD) avec et sans le répertoire du service.

crontab.shécrit essentiellement une planification cron dans un fichier texte ( cron.jobs), puis importe le fichier texte dans crontab.

Dockerfile:

FROM node:0.10
MAINTAINER Tom

VOLUME /var/log/

RUN mkdir /pulse
ADD . /pulse
WORKDIR /pulse

RUN apt-get update && apt-get install -y cron

ADD *.sh /pulse/
RUN chmod 750 /pulse/crontab.sh && chmod 750 /pulse/

RUN chmod 644 /etc/crontab

CMD cron -f
CMD touch /var/log/cron.log && sh /pulse/crontab.sh && tail -f /var/log/cron.log
CMD cron /pulse/cron.jobs
CMD crontab -l

edited to add crontab.sh

crontab.sh (certains crons ont été supprimés):

#!/bin/bash

cat <<- 'EOF' > cron.jobs

0 * * * * node /pulse/scripts/awsPulseTest.js > /tmp/awsPulseTest.log 2>&1

EOF

crontab cron.jobs

Erreur:

no crontab for root

Notes annexes:

  • Pulse est le nom du service.
  • La version du nœud est ancienne en raison du service, elle sera mise à niveau.
  • Le service est essentiellement destiné aux tâches cron dans le nœud
TomFirth
la source
Une combinaison de serverfault.com/a/851500/395574 et serverfault.com/a/851479/395574 a aidé à résoudre ce problème.
TomFirth

Réponses:

11

C'est un problème avec le dockerfile (plutôt qu'avec les commandes du fichier). Un seul CMDest exécuté (le dernier) - voir https://docs.docker.com/engine/reference/builder/#cmd

Il ne peut y avoir qu'une seule instruction CMD dans un Dockerfile. Si vous répertoriez plusieurs CMD, seul le dernier CMD prendra effet.

Paul Haldane
la source
Ah, et il y a cela en plus de tout le reste :) À OP: Cela n'invalide pas mon explication et vous devrez essentiellement remplacer votre CMDpar RUN.
Sven
2
Je pense que d'appeler cela un problème est un peu décalé. Ce comportement est voulu par la conception même du produit. Les conteneurs ne sont pas des mini-OS. Ils sont centrés sur l'application.
JimmyJames
D'accord. Mon intention était de clarifier que le problème du PO résidait dans leur configuration docker plutôt que dans les détails de cron.
Paul Haldane
Ce n'est pas un problème de docker . C'est par conception.
Andrew Savinykh
5

Comme les autres réponses l'ont déjà expliqué, une seule CMDsera exécutée par Dockerfile et la commande que vous souhaitez exécuter est incorrecte.

Mais il y a un problème plus urgent avec votre configuration IMO - Les conteneurs Docker ne sont généralement pas conçus pour fonctionner de cette façon. Ce que vous devez faire à la place, c'est exécuter les services cron à partir de l'hôte (ou de votre orchestrateur) en tant que processus ponctuels (en utilisant probablement quelque chose comme docker runou docker-compose run, ou, si pour une raison quelconque vous ne voulez pas démarrer un conteneur séparé pour cela, je devinez que vous pourriez utiliser docker exec).

Ce n'est que mon avis sur la façon dont les conteneurs doivent être utilisés, alors vous devez évidemment le prendre avec un grain de sel.

Artur Ciesielski
la source
2
Je n'ai qu'une familiarité passagère avec cron, mais je pense que pour rendre cela sensible, le CMD devrait fonctionner en crond. Sinon, le conteneur se fermera une fois la commande crontab terminée.
JimmyJames
@JimmyJames Ce que vous dites est correct, mais comme je l'ai expliqué ci-dessus, la meilleure solution consiste à exécuter ces commandes à partir d'un cron externe en tant que docker runs uniques. Plus de conteneurs-y. :)
Artur Ciesielski
Tu pourrais avoir raison. La question est intéressante car il n'est pas clair s'il est logique d'exécuter crond en tant que commande de votre conteneur. Cela peut être réalisable, mais cela semble gênant dans un conteneur.
JimmyJames
3

Si vous ajoutez ceci à /etc/crontab, cela n'apparaîtra pas dans la crontab personnelle de root, car il ne contient que la crontab spécifique à l'utilisateur éditée avec crontab -e, pas celle du système dans /etc.


Plus de détails:

Je suppose que /pulse/crontab.sh(que vous ne montrez pas, pourquoi?) Ajoute la ligne crontab pertinente au fichier crontab à l'échelle du système /etc/crontab. Vous exécutez la commande plus tard crontab -l, mais cela montre seulement une erreur car il liste rootde personnel crontab seulement (qui se trouve être vide), pas celui de l' ensemble du système dans /etc/crontab. Tout cela est parfaitement normal et attendu. Pour afficher la ligne ajoutée par votre script, vous devez remplacer CMD crontab -lpar CMD cat /etc/crontab.

Tout cela n'a rien à voir avec les commandes dockerfile comme ADD, RUNou CMD, c'est juste des trucs Linux basiques.

Sven
la source
Je pense que je comprends cela. Mes paramètres de génération sont sur l'utilisateur mais mes paramètres d'exécution tentent de s'exécuter à partir de la crontab de la racine? cela fait sens, je vais essayer de contourner cela. Je suppose que vous ne vouliez pas dire: ADD . /etc/crontabcar cela ne fonctionne pas.
TomFirth
@ TomFirth: Cela n'a pas beaucoup de sens. Veuillez lire ma modification pour plus de détails.
Sven