Możesz skopiować crontab do obrazu, aby kontener uruchomiony z tego obrazu mógł uruchomić zadanie.
Zobacz „ Uruchom pracę z cronem z Dockerem ” Juliena Boulaya w jego Ekito/docker-cron
:
Utwórzmy nowy plik o nazwie „ hello-cron
”, aby opisać naszą pracę.
* * * * * 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.
Poniższy plik Docker opisuje wszystkie etapy tworzenia obrazu
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
(patrz Gaafar dydaktycznego komentarz i Jak zrobić apt-get
zainstalować mniej hałaśliwe? :
apt-get -y install -qq --force-yes cron
może pracować zbyt)
Jak zauważył Nathan Lloyd w komentarzach :
Szybka uwaga na temat gotcha:
jeśli dodajesz plik skryptu i każesz cronowi go uruchomić, pamiętaj, że Cron zawiedzie cicho, jeśli zapomnisz .
RUN chmod 0744 /the_script
OR, upewnij się, że praca sama przekierowuje bezpośrednio do stdout / stderr zamiast pliku dziennika, w sposób opisany w hugoShaka jest odpowiedź :
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
Zamień ostatnią linię Dockerfile na
CMD ["cron", "-f"]
Zobacz także (about cron -f
, czyli cron „pierwszy plan”) „ ubuntu dokera cron -f
nie działa ”
Zbuduj i uruchom:
sudo docker build --rm -t ekito/cron-example .
sudo docker run -t -i ekito/cron-example
Bądź cierpliwy, poczekaj 2 minuty, a Twój wiersz poleceń powinien wyświetlać:
Hello world
Hello world
Eric dodaje w komentarzach :
Pamiętaj, że tail
może nie wyświetlać poprawnego pliku, jeśli zostanie on utworzony podczas kompilacji obrazu.
W takim przypadku należy utworzyć plik lub go dotknąć podczas działania kontenera, aby tail mógł pobrać poprawny plik.
Zobacz „Dane wyjściowe tail -f
na końcu okna dokowanego CMD
nie są wyświetlane ”.
RUN apt-get update && apt-get install cron
-y
do instalacji crona, aby uniknąć wyjścia kompilacjicrontab -l
piszę, otrzymuję Brak zainstalowanego crontab dla roota , a także mój ekran pozostaje pusty. Jednak gdy zaznaczam „/etc/cron.d/”, widzę, że jest tam/var/log/cron.log
plik crontab (i jeszcze bardziej zaskakujące), kiedy sprawdzam , widzę, że skrypt działa (zawartość pliku jest dołączanaHello World
). Ja ciągnąc ten obraz w moim Dockerfile:FROM phusion/baseimage:0.10.0
. Wszelkie pomysły dotyczące rozbieżności w zachowaniu?Przyjęte rozwiązanie może być niebezpieczne w środowisku produkcyjnym .
Gdy używasz
CMD cron && tail -f /var/log/cron.log
procesu cron w zasadzie fork, aby wykonać gocron
w tle, główny proces kończy działanie i umożliwia wykonanietailf
na pierwszym planie. Proces cron w tle może zostać zatrzymany lub zawieść, czego nie zauważysz, kontener nadal będzie działał w trybie cichym, a narzędzie do aranżacji go nie uruchomi ponownie.Używając podstawowych przekierowań powłoki, możesz chcieć zrobić coś takiego:
A twoje CMD będzie:
CMD ["cron", "-f"]
źródło
cron -f
jest dla „pierwszego planu crona”. Dla większej widoczności umieściłem twoją odpowiedź powyżej. +1Dla tych, którzy chcą użyć prostego i lekkiego obrazu:
Gdzie cronjobs to plik zawierający twoje cronjobs, w tej formie:
źródło
> /proc/1/fd/1 2> /proc/1/fd/2
przekierowania, aby uzyskać dostęp do danych wyjściowych cronjobs bezpośrednio z dzienników dokera.-d 8
parametr nie jest standardowym cronem, jest to komenda crond z busybox. Na przykład z Ubuntu możesz uruchomić to jakobusybox crond -f -d 8
. W przypadku starszych wersji musisz użyć-L /dev/stdout/
.docker run -v ${PWD}/cronjobs:/etc/crontabs/root alpine:3.6 crond -f -d 8
. @Groostav możesz użyć podobnej rzeczy w Docker Compose.CMD ["crond"
czyCMD ["cron"
?To, co sugeruje @VonC, jest fajne, ale wolę wykonywać wszystkie konfiguracje zadań cron w jednym wierszu. Pozwoli to uniknąć problemów międzyplatformowych, takich jak lokalizacja cronjob i nie potrzebujesz osobnego pliku cron.
Po uruchomieniu kontenera dokowanego możesz sprawdzić, czy usługa cron działa:
Jeśli wolisz mieć ENTRYPOINT zamiast CMD, możesz zastąpić CMD powyżej
źródło
RUN apt-get update && apt-get -y install cron
w przeciwnym razie nie będzie w stanie znaleźć paczkicron
RUN cat $APP_HOME/crons/* | crontab
Like a charm :)cron
do skryptu punktu wejścia wydaje się najlepszą opcją: ENTRYPOINT ["entrypoint.sh"]Można to zrobić na inny sposób, korzystając z Taskera , programu uruchamiającego zadania, który obsługuje cron (harmonogram).
Czemu ? Czasami, aby uruchomić zadanie crona, musisz mieszać obraz podstawowy (python, java, nodejs, ruby) z crond. To oznacza kolejny obraz do utrzymania. Tasker uniknie tego, oddzielając crond i kontener. Możesz po prostu skupić się na obrazie, który chcesz wykonać, i skonfigurować Taskera, aby go używał.
Oto
docker-compose.yml
plik, który uruchomi dla ciebie niektóre zadaniaSą tam 3 zadania, wszystkie będą uruchamiane co minutę (
every: minute
) i każde z nich wykonascript
kod wewnątrz obrazu zdefiniowanego wimage
sekcji.Po prostu biegnij
docker-compose up
i zobacz, jak działa. Oto repozytorium Tasker z pełną dokumentacją:http://github.com/opsxcq/tasker
źródło
docker exec
na określonych kontenerach.Odpowiedź VonC jest dość dokładna. Ponadto chciałbym dodać jedną rzecz, która mi pomogła. Jeśli chcesz po prostu uruchomić zadanie crona bez modyfikowania pliku, pokusa może po prostu usunąć plik
&& tail -f /var/log/cron.log
z polecenia cron.Spowoduje to jednak zamknięcie kontenera Docker wkrótce po uruchomieniu, ponieważ gdy komenda cron zakończy działanie, Docker uważa, że ostatnia komenda została zakończona, a zatem zabija kontener. Można tego uniknąć, uruchamiając crona na pierwszym planie przez
cron -f
.źródło
Chociaż ma to na celu uruchamianie zadań obok uruchomionego procesu w kontenerze za pośrednictwem Dockera
exec
interfejsu , może to być dla Ciebie interesujące.Napisałem demona, który obserwuje na nich kontenery i planuje zadania zdefiniowane w ich metadanych. Przykład:
Możliwa jest także „klasyczna” konfiguracja podobna do crona.
Oto dokumenty , oto repozytorium obrazów .
źródło
docker exec <container_name> <some_command>
według harmonogramu.Stworzyłem obraz Dockera na podstawie innych odpowiedzi, które można wykorzystać jak
docker run -v "/path/to/cron:/etc/cron.d/crontab" gaafar/cron
gdzie
/path/to/cron
: ścieżka bezwzględna do pliku crontab lub można go użyć jako podstawy w pliku Docker:W celach informacyjnych obraz jest tutaj .
źródło
Po wdrożeniu kontenera na innym hoście pamiętaj, że nie uruchomi on automatycznie żadnych procesów. Musisz upewnić się, że usługa „cron” działa w twoim kontenerze. W naszym przypadku używam Supervisord z innymi usługami do uruchomienia usługi cron.
źródło
Zdefiniuj cronjob w dedykowanym kontenerze, który uruchamia polecenie za pośrednictwem exec docker do twojej usługi.
Zapewnia to większą spójność, a uruchomiony skrypt będzie miał dostęp do zmiennych środowiskowych zdefiniowanych dla usługi.
źródło
myservice unknown
błędy.Jeśli używasz okna dokowanego dla systemu Windows, pamiętaj, że musisz zmienić format zakończenia linii z CRLF na LF (tj. Z dos na unix), jeśli zamierzasz importować plik crontab z systemu Windows do kontenera ubuntu. Jeśli nie, twoje zadanie cron nie zadziała. Oto działający przykład:
Właściwie zajęło mi to wiele godzin, ponieważ debugowanie zadań cron w kontenerach dokerów jest żmudnym zadaniem. Mam nadzieję, że pomoże to każdemu, kto nie może uruchomić swojego kodu!
źródło
Z powyższych przykładów stworzyłem tę kombinację:
Alpine Image & Edit przy użyciu Crontab w Nano (nienawidzę vi)
źródło
Skonfiguruj crona równolegle do jednorazowego zadania
Utwórz plik skryptu, powiedzmy run.sh, z zadaniem, które ma być uruchamiane okresowo.
Zapisz i wyjdź.
Użyj Entrypoint zamiast CMD
Jeśli masz wiele zadań do uruchomienia podczas konteneryzacji dokera, użyj pliku punktu wejścia, aby je wszystkie uruchomić.
Plik punktu wejścia to plik skryptu, który zaczyna działać po wydaniu polecenia uruchamiania dokera. Tak więc wszystkie kroki, które chcemy uruchomić, można umieścić w tym pliku skryptu.
Na przykład mamy 2 zadania do uruchomienia:
Uruchom raz zadanie : echo „Kontener Docker został uruchomiony”
Uruchom okresową pracę : run.sh
Utwórz entrypoint.sh
Rozumiemy crontab, który został ustawiony w pliku
* * * * *
: Harmonogram Cron; zadanie musi działać co minutę. Możesz zaktualizować harmonogram zgodnie ze swoimi wymaganiami./run.sh
: Ścieżka do pliku skryptu, który ma być uruchamiany okresowo/var/log/cron.log
: Nazwa pliku do zapisania wyniku zaplanowanego zadania cron.2>&1
: Dzienniki błędów (jeśli istnieją) również zostaną przekierowane do tego samego pliku wyjściowego, który został użyty powyżej.Uwaga : Nie zapomnij dodać nowej nowej linii, ponieważ czyni ją to prawidłowym cronem.
Scheduler.txt
: pełna konfiguracja crona zostanie przekierowana do pliku.Używanie zmiennych środowiskowych specyficznych dla systemu / użytkownika w cron
Moje rzeczywiste zadanie cron oczekiwało większości argumentów, gdy zmienne środowiskowe były przekazywane do komendy uruchamiania dokera. Ale dzięki bash nie byłem w stanie użyć żadnej ze zmiennych środowiskowych należących do systemu lub kontenera dokowanego.
Później pojawiło się to obejście tego problemu:
W końcu
entrypoint.sh
powinieneś wyglądaćLast but not least: utwórz plik Docker
Otóż to. Zbuduj i uruchom obraz Docker!
źródło
Zadania Crona są przechowywane w / var / spool / cron / crontabs (wspólne miejsce we wszystkich dystrybucjach, jakie znam). BTW, możesz utworzyć kartę cron w bash, używając czegoś takiego:
Spowoduje to utworzenie pliku tymczasowego z zadaniem cron, a następnie zaprogramowanie go za pomocą crontab. Ostatnia linia usuwa plik tymczasowy.
źródło
cron
Demon zwykle nie działają w pojemniku.crond
oprócz usługi uruchomionej w kontenerze, zwykle z menedżerem usług, takim jak s6. Prawdopodobnie zadaj to pytanie, aby uzyskać właściwą odpowiedźPodczas pracy z niektórymi przyciętymi obrazami, które ograniczają dostęp do roota, musiałem dodać mojego użytkownika do sudoers i uruchomić jako
sudo cron
Może to komuś pomaga
źródło
Mój problem był taki sam. Poprawka polegała na zmianie sekcji poleceń w
docker-compose.yml
.Z
polecenie: crontab / etc / crontab && tail -f / etc / crontab
Do
polecenie: crontab / etc / crontab
polecenie: tail -f / etc / crontab
Problemem był „&&” pomiędzy poleceniami. Po usunięciu tego wszystko było w porządku.
źródło
Najbardziej niezawodnym sposobem, jaki do tej pory znalazłem, jest uruchomienie niezależnego kontenera cron - zainstaluj klienta dokera i powiąż zamontowanie skarpety dokera, aby móc rozmawiać z serwerem dokera na hoście.
Następnie wystarczy użyć zmiennych env dla każdego zadania cron i skryptu punktu wejścia do wygenerowania pliku / etc / crontab
Oto obraz, który stworzyłem, stosując tę zasadę i używając go w produkcji przez ostatnie 3-4 lata.
https://www.vip-consult.solutions/post/better-docker-cron#content
źródło
Spróbuj użyć klejnotu w zegarku, aby zaplanować zadania. Postępuj zgodnie z instrukcjami podanymi w tym łączu.
http://fuzzyblog.io/blog/rails/2017/05/11/adding-cron-to-a-dockerized-rails-application-using-clockwork.html
Możesz wywołać zadanie prowizji w pliku lib / clock.rb jak poniżej.
Utwórz osobny kontener w pliku skompiluj okno dokowane i uruchom poniższe polecenie w kontenerze.
źródło