Sie können Ihre Crontab in ein Image kopieren, damit der von diesem Image gestartete Container den Job ausführt.
Siehe " Führen Sie einen Cron-Job mit Docker aus " von Julien Boulay in seinem Ekito/docker-cron
:
Erstellen wir eine neue Datei mit dem Namen " hello-cron
", um unseren Job zu beschreiben.
* * * * * echo "Hello world" >> /var/log/cron.log 2>&1
# An empty line is required at the end of this file for a valid cron file.
Die folgende Docker-Datei beschreibt alle Schritte zum Erstellen Ihres Images
FROM ubuntu:latest
MAINTAINER docker@ekito.fr
RUN apt-get update && apt-get -y install cron
# Copy hello-cron file to the cron.d directory
COPY hello-cron /etc/cron.d/hello-cron
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/hello-cron
# Apply cron job
RUN crontab /etc/cron.d/hello-cron
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Run the command on container startup
CMD cron && tail -f /var/log/cron.log
(siehe Gaafar ‚s Kommentar und Wie kann ich apt-get
weniger laut installieren? :
apt-get -y install -qq --force-yes cron
kann auch funktionieren)
Wie von Nathan Lloyd in den Kommentaren bemerkt :
Kurzer Hinweis zu einem Gotcha:
Wenn Sie eine Skriptdatei hinzufügen und cron anweisen, sie auszuführen, denken Sie daran, dass Cron im Hintergrund fehlschlägt, wenn Sie es vergessen .
RUN chmod 0744 /the_script
ODER stellen Sie sicher, dass Ihr Job selbst direkt zu stdout / stderr anstatt zu einer Protokolldatei umleitet, wie in der Antwort von hugoShaka beschrieben :
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
Ersetzen Sie die letzte Dockerfile-Zeile durch
CMD ["cron", "-f"]
Siehe auch (ungefähr cron -f
, das heißt cron "Vordergrund") " Docker Ubuntu cron -f
funktioniert nicht "
Erstellen und ausführen Sie es:
sudo docker build --rm -t ekito/cron-example .
sudo docker run -t -i ekito/cron-example
Seien Sie geduldig, warten Sie 2 Minuten und Ihre Befehlszeile sollte Folgendes anzeigen:
Hello world
Hello world
Eric fügt in den Kommentaren hinzu :
Beachten Sie, dass tail
möglicherweise nicht die richtige Datei angezeigt wird, wenn sie während der Image-Erstellung erstellt wird.
In diesem Fall müssen Sie die Datei zur Laufzeit des Containers erstellen oder berühren, damit der Tail die richtige Datei aufnimmt.
Siehe " Ausgabe tail -f
am Ende eines Dockers CMD
wird nicht angezeigt ".
RUN apt-get update && apt-get install cron
-y
zur Installation von cron hinzufügen, um zu vermeiden, dass der Docker-Build beendet wirdcrontab -l
, wird kein crontab für root installiert . Außerdem bleibt mein Bildschirm leer. Wenn ich jedoch '/etc/cron.d/' überprüfe, sehe ich, dass das crontab-Feld vorhanden ist (und noch überraschender), wenn ich überprüfe/var/log/cron.log
, sehe ich, dass das Skript ausgeführt wird (der Dateiinhalt wird angehängtHello World
). Ich ziehe dieses Bild in meine Docker-Datei :FROM phusion/baseimage:0.10.0
. Irgendwelche Ideen zur Diskrepanz im Verhalten?Die angenommene Lösung kann in einer Produktionsumgebung gefährlich sein .
Wenn Sie
CMD cron && tail -f /var/log/cron.log
den Cron-Prozess grundsätzlich fork verwenden, um ihncron
im Hintergrund auszuführen , wird der Hauptprozess beendet und Sie können ihntailf
im Vordergrund ausführen . Der Hintergrund-Cron-Prozess kann angehalten werden oder fehlschlagen, Sie werden es nicht bemerken, Ihr Container wird weiterhin still ausgeführt und Ihr Orchestrierungs-Tool startet ihn nicht neu.Mit einfachen Shell-Weiterleitungen möchten Sie möglicherweise Folgendes tun:
Und Ihre CMD wird sein:
CMD ["cron", "-f"]
quelle
cron -f
ist für "Cron Vordergrund". Ich habe Ihre Antwort oben in meine aufgenommen, um mehr Sichtbarkeit zu gewährleisten. +1Für diejenigen, die ein einfaches und leichtes Bild verwenden möchten:
Wobei cronjobs die Datei ist, die Ihre cronjobs enthält, in dieser Form:
quelle
> /proc/1/fd/1 2> /proc/1/fd/2
Umleitung auch, um auf Cronjobs zuzugreifen, die direkt aus den Docker-Protokollen ausgegeben werden.-d 8
Parameter unterstützt, ist nicht der Standard-cron, sondern der crond-Befehl von busybox. Zum Beispiel können Sie dies von Ubuntu aus als ausführenbusybox crond -f -d 8
. Für ältere Versionen müssen Sie verwenden-L /dev/stdout/
.docker run -v ${PWD}/cronjobs:/etc/crontabs/root alpine:3.6 crond -f -d 8
. @Groostav Sie können eine ähnliche Sache in Docker Compose verwenden.Was @VonC vorgeschlagen hat, ist nett, aber ich bevorzuge es, alle Cron-Job-Konfigurationen in einer Zeile durchzuführen. Dies würde plattformübergreifende Probleme wie den Cronjob-Standort vermeiden und Sie benötigen keine separate Cron-Datei.
Nachdem Sie Ihren Docker-Container ausgeführt haben, können Sie sicherstellen, dass der Cron-Service funktioniert durch:
Wenn Sie ENTRYPOINT anstelle von CMD bevorzugen, können Sie das obige CMD durch ersetzen
quelle
RUN apt-get update && apt-get -y install cron
oder es wird nicht in der Lage sein, Paket zu findencron
RUN cat $APP_HOME/crons/* | crontab
Wie ein Zauber :)cron
zu einem Einstiegspunktskript scheint die beste Option zu sein: ENTRYPOINT ["entrypoint.sh"]Eine andere Möglichkeit besteht darin, Tasker zu verwenden , einen Task-Runner, der Cron (einen Scheduler) unterstützt.
Warum ? Manchmal müssen Sie zum Ausführen eines Cron-Jobs Ihr Basis-Image (Python, Java, NodeJS, Ruby) mit dem Cron mischen. Das bedeutet, dass ein anderes Image beibehalten werden muss. Tasker vermeiden Sie dies, indem Sie den Crond und Ihren Container entkoppeln. Sie können sich einfach auf das Bild konzentrieren, auf dem Sie Ihre Befehle ausführen möchten, und Tasker für die Verwendung konfigurieren.
Hier eine
docker-compose.yml
Datei, die einige Aufgaben für Sie ausführtDort gibt es 3 Aufgaben, die alle jede Minute ausgeführt werden (
every: minute
), und jede von ihnen führt denscript
Code innerhalb des imimage
Abschnitt definierten Bildes aus .Laufen Sie einfach
docker-compose up
und sehen Sie, wie es funktioniert. Hier ist das Tasker-Repo mit der vollständigen Dokumentation:http://github.com/opsxcq/tasker
quelle
docker exec
für bestimmte Container.VonCs Antwort ist ziemlich gründlich. Außerdem möchte ich eine Sache hinzufügen, die mir geholfen hat. Wenn Sie nur einen Cron-Job ausführen möchten, ohne eine Datei zu beenden, sind Sie versucht,
&& tail -f /var/log/cron.log
den Befehl einfach aus dem Cron-Befehl zu entfernen .Dies führt jedoch dazu, dass der Docker-Container kurz nach der Ausführung beendet wird, da Docker nach Abschluss des Befehls cron denkt, dass der letzte Befehl beendet wurde, und daher den Container beendet. Dies kann vermieden werden, indem cron im Vordergrund über ausgeführt wird
cron -f
.quelle
Dies zielt zwar darauf ab, Jobs neben einem laufenden Prozess in einem Container über die Docker-
exec
Oberfläche auszuführen , dies kann jedoch für Sie von Interesse sein.Ich habe einen Daemon geschrieben, der Container beobachtet und Jobs plant, die in ihren Metadaten definiert sind. Beispiel:
Eine "klassische", Cron-ähnliche Konfiguration ist ebenfalls möglich.
Hier sind die Dokumente , hier ist das Image-Repository .
quelle
docker exec <container_name> <some_command>
nach Zeitplan.Ich habe ein Docker-Image basierend auf den anderen Antworten erstellt, das wie folgt verwendet werden kann
docker run -v "/path/to/cron:/etc/cron.d/crontab" gaafar/cron
Dabei gilt
/path/to/cron
Folgendes: absoluter Pfad zur Crontab-Datei, oder Sie können ihn als Basis in einer Docker-Datei verwenden:Als Referenz ist das Bild hier .
quelle
Beachten Sie beim Bereitstellen Ihres Containers auf einem anderen Host, dass keine Prozesse automatisch gestartet werden. Sie müssen sicherstellen, dass der Cron-Dienst in Ihrem Container ausgeführt wird. In unserem Fall verwende ich Supervisord mit anderen Diensten, um den Cron-Dienst zu starten.
quelle
Definieren Sie den Cronjob in einem dedizierten Container, der den Befehl über Docker Exec an Ihren Dienst ausführt.
Dies ist eine höhere Kohäsion und das ausgeführte Skript hat Zugriff auf die Umgebungsvariablen, die Sie für Ihren Dienst definiert haben.
quelle
myservice unknown
Fehler.Wenn Sie Docker für Windows verwenden, denken Sie daran, dass Sie Ihr Zeilenendformat von CRLF in LF (dh von dos auf unix) ändern müssen, wenn Sie Ihre Crontab-Datei aus Windows in Ihren Ubuntu-Container importieren möchten. Wenn nicht, funktioniert Ihr Cron-Job nicht. Hier ist ein Arbeitsbeispiel:
Ich habe tatsächlich Stunden gebraucht, um das herauszufinden, da das Debuggen von Cron-Jobs in Docker-Containern eine mühsame Aufgabe ist. Hoffe, es hilft allen anderen da draußen, die ihren Code nicht zum Laufen bringen können!
quelle
Aus den obigen Beispielen habe ich diese Kombination erstellt:
Alpine Image & Edit mit Crontab in Nano (ich hasse vi)
quelle
Richten Sie einen Cron parallel zu einem einmaligen Job ein
Erstellen Sie eine Skriptdatei, z. B. run.sh, mit dem Job, der regelmäßig ausgeführt werden soll.
Speichern und schließen.
Verwenden Sie Entrypoint anstelle von CMD
Wenn Sie während der Docker-Containerisierung mehrere Jobs starten müssen, verwenden Sie die Entrypoint-Datei, um alle Jobs auszuführen.
Die Einstiegspunktdatei ist eine Skriptdatei, die ausgeführt wird, wenn ein Docker-Ausführungsbefehl ausgegeben wird. Alle Schritte, die wir ausführen möchten, können in diese Skriptdatei eingefügt werden.
Zum Beispiel müssen wir 2 Jobs ausführen:
Einmal Job ausführen: Echo "Docker-Container wurde gestartet"
Führen Sie einen regelmäßigen Job aus : run.sh.
Erstellen Sie entrypoint.sh
Lassen Sie uns die Crontab verstehen, die in der Datei eingerichtet wurde
* * * * *
: Cron Zeitplan; Der Job muss jede Minute ausgeführt werden. Sie können den Zeitplan entsprechend Ihren Anforderungen aktualisieren./run.sh
: Der Pfad zur Skriptdatei, die regelmäßig ausgeführt werden soll/var/log/cron.log
: Der Dateiname zum Speichern der Ausgabe des geplanten Cron-Jobs.2>&1
: Die Fehlerprotokolle (falls vorhanden) werden ebenfalls in dieselbe Ausgabedatei umgeleitet, die oben verwendet wurde.Hinweis : Vergessen Sie nicht, eine zusätzliche neue Zeile hinzuzufügen, da dies eine gültige Cron macht.
Scheduler.txt
: Das komplette Cron-Setup wird in eine Datei umgeleitet.Verwenden system- / benutzerspezifischer Umgebungsvariablen in cron
Mein eigentlicher Cron-Job erwartete die meisten Argumente, da die Umgebungsvariablen an den Docker-Befehl run übergeben wurden. Mit bash konnte ich jedoch keine der Umgebungsvariablen verwenden, die zum System oder zum Docker-Container gehören.
Dann kam dies als Umgehung für dieses Problem:
Endlich
entrypoint.sh
solltest du so aussehenLast but not least: Erstellen Sie eine Docker-Datei
Das ist es. Erstellen Sie das Docker-Image und führen Sie es aus!
quelle
Cron-Jobs werden in / var / spool / cron / crontabs gespeichert (gemeinsamer Platz in allen mir bekannten Distributionen). Übrigens, Sie können eine Cron-Registerkarte in Bash mit so etwas erstellen:
Dadurch wird eine temporäre Datei mit cron task erstellt und anschließend mit crontab programmiert. Letzte Zeile temporäre Datei entfernen.
quelle
cron
Daemon wird normalerweise nicht in einem Container ausgeführt.crond
zusätzlich zu dem Dienst, den Sie im Container ausführen , normalerweise mit einem Dienstmanager wie s6 ausgeführt werden. Stellen Sie das wahrscheinlich als Frage, um eine richtige Antwort zu erhaltenWenn ich auf einigen abgespeckten Bildern laufen wollte, die den Root-Zugriff einschränken, musste ich meinen Benutzer zu den Sudoern hinzufügen und als ausführen
sudo cron
Vielleicht hilft das jemandem
quelle
Mein Problem war also dasselbe. Das Update bestand darin, den Befehlsabschnitt in der zu ändern
docker-compose.yml
.Von
Befehl: crontab / etc / crontab && tail -f / etc / crontab
Zu
Befehl: crontab / etc / crontab
Befehl: tail -f / etc / crontab
Das Problem war das '&&' zwischen den Befehlen. Nach dem Löschen war alles in Ordnung.
quelle
Die robusteste Methode, die ich bisher gefunden habe, ist das Ausführen eines unabhängigen Cron-Containers. Installieren Sie den Docker-Client und binden Sie die Docker-Socke, damit Sie mit dem Docker-Server auf dem Host kommunizieren können.
Verwenden Sie dann einfach env vars für jeden Cron-Job und ein Einstiegspunkt-Skript, um die Datei / etc / crontab zu generieren
Hier ist ein Bild, das ich nach diesem Prinzip erstellt und in den letzten 3-4 Jahren in der Produktion verwendet habe.
https://www.vip-consult.solutions/post/better-docker-cron#content
quelle
Versuchen Sie, Aufgaben mit einem Uhrwerk zu planen. Befolgen Sie die Schritte in diesem Link.
http://fuzzyblog.io/blog/rails/2017/05/11/adding-cron-to-a-dockerized-rails-application-using-clockwork.html
Sie können die Rake-Task in der Datei lib / clock.rb wie folgt aufrufen.
Erstellen Sie einen separaten Container in der Docker-Compose-Datei und führen Sie den folgenden Befehl im Container aus.
quelle