[docker] 도커 컨테이너 내에서 크론 작업을 실행하는 방법은 무엇입니까?
쉘 스크립트를 호출하는 도커 컨테이너 내에서 cronjob을 실행하려고합니다.
어제 웹과 스택 오버플로를 검색했지만 실제로 작동하는 솔루션을 찾을 수 없었습니다.
어떻게해야합니까?
편집하다:
주어진 간격마다 쉘 스크립트를 호출하는 작동하는 docker cron 컨테이너로 주석 처리 된 github 저장소 를 만들었습니다 .
답변
해당 이미지에서 시작된 컨테이너가 작업을 실행하기 위해 crontab을 이미지로 복사 할 수 있습니다.
자세한 내용은 ” 부두 노동자와 cron 작업을 실행 에서” 줄리앙 Boulay 자신에 Ekito/docker-cron
:
hello-cron
작업을 설명하기 위해 ” ” 라는 새 파일을 만들어 봅시다 .
* * * * * 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.
다음 Dockerfile은 이미지를 빌드하는 모든 단계를 설명합니다.
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
( Gaafar 의 의견 과 설치를 덜 시끄럽게 만드는 방법을apt-get
참조하십시오 : :
apt-get -y install -qq --force-yes cron
작동 가능)
댓글 에서 Nathan Lloyd 가 지적한 바와 같이 :
문제에 대한 빠른 참고 사항 :
스크립트 파일을 추가하고 cron에이를 실행하도록 지시하는 경우, 잊어 버린 경우 Cron이 자동으로 실패 한다는 것을 기억하십시오 .
RUN chmod 0744 /the_script
또는 hugoShaka 의 답변에 설명 된대로 작업 자체가 로그 파일 대신 stdout / stderr로 직접 리디렉션되도록하십시오 .
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
마지막 Dockerfile 줄을
CMD ["cron", "-f"]
(에 대한 참조 cron -f
크론 “전경”라고하는 것입니다있는) ” 우분투는 고정 표시기 cron -f
작동하지 않습니다 “
빌드하고 실행하십시오.
sudo docker build --rm -t ekito/cron-example .
sudo docker run -t -i ekito/cron-example
인내심을 갖고 2 분 동안 기다리면 명령 행이 표시되어야합니다.
Hello world
Hello world
참고 수행
tail
이 이미지 빌드하는 동안 생성 된 경우 올바른 파일을 표시하지 않을 수 있습니다.
이 경우 테일이 올바른 파일을 선택하도록 컨테이너 런타임 동안 파일을 작성하거나 터치해야합니다.
” 도커 끝에 출력이 표시되지 않음tail -f
CMD
“을 참조하십시오.
답변
채택 된 솔루션 은 프로덕션 환경에서 위험 할 수 있습니다 .
도커에서는 컨테이너 당 하나의 프로세스 만 실행해야합니다.
당신이 사용하는 경우 CMD cron && tail -f /var/log/cron.log
실행하기 위해 기본적으로 포크 크론 프로세스를 cron
백그라운드에서 주요 프로세스 종료하고 실행하자 tailf
전경. 백그라운드 크론 프로세스가 중지되거나 실패 할 수 있습니다. 컨테이너는 여전히 자동으로 실행되며 오케스트레이션 도구는 다시 시작하지 않습니다.
당신은 당신의 고정 표시기에 직접 크론의 명령 출력을 리디렉션하여 이러한 일을 방지 할 수 있습니다
stdout
및stderr
각각 위치/proc/1/fd/1
및/proc/1/fd/2
.
기본 셸 리디렉션을 사용하면 다음과 같이 할 수 있습니다.
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
CMD는 다음과 같습니다. CMD ["cron", "-f"]
답변
간단하고 가벼운 이미지를 사용하려는 사람들을 위해 :
FROM alpine:3.6
# copy crontabs for root user
COPY config/cronjobs /etc/crontabs/root
# start crond with log level 8 in foreground, output to stderr
CMD ["crond", "-f", "-d", "8"]
여기서 cronjobs 는 다음 형식의 cronjob을 포함하는 파일입니다.
* * * * * echo "hello stackoverflow" >> /test_file 2>&1
# remember to end this file with an empty new line
답변
@VonC가 제안한 것은 좋지만 모든 cron 작업 구성을 한 줄로 수행하는 것을 선호합니다. 이것은 cronjob 위치와 같은 플랫폼 간 문제를 피하고 별도의 cron 파일이 필요하지 않습니다.
FROM ubuntu:latest
# Install cron
RUN apt-get -y install cron
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Setup cron job
RUN (crontab -l ; echo "* * * * * echo "Hello world" >> /var/log/cron.log") | crontab
# Run the command on container startup
CMD cron && tail -f /var/log/cron.log
도커 컨테이너를 실행 한 후 다음을 수행하여 cron 서비스가 작동하는지 확인할 수 있습니다.
# To check if the job is scheduled
docker exec -ti <your-container-id> bash -c "crontab -l"
# To check if the cron service is running
docker exec -ti <your-container-id> bash -c "pgrep cron"
CMD 대신 ENTRYPOINT를 선호하는 경우 위의 CMD를
ENTRYPOINT cron start && tail -f /var/log/cron.log
답변
cron (스케줄러)을 지원하는 작업 러너 인 Tasker 를 사용하는 것이 다른 방법 입니다.
왜 ? 때로는 cron 작업을 실행하려면 기본 이미지 (python, java, nodejs, ruby)를 크론과 혼합해야합니다. 그것은 유지해야 할 또 다른 이미지를 의미합니다. Tasker는 크론과 컨테이너를 분리하여이를 피합니다. 명령을 실행하려는 이미지에 초점을 맞추고이를 사용하도록 Tasker를 구성 할 수 있습니다.
여기 docker-compose.yml
당신을 위해 몇 가지 작업을 실행할 파일
version: "2"
services:
tasker:
image: strm/tasker
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
environment:
configuration: |
logging:
level:
ROOT: WARN
org.springframework.web: WARN
sh.strm: DEBUG
schedule:
- every: minute
task: hello
- every: minute
task: helloFromPython
- every: minute
task: helloFromNode
tasks:
docker:
- name: hello
image: debian:jessie
script:
- echo Hello world from Tasker
- name: helloFromPython
image: python:3-slim
script:
- python -c 'print("Hello world from python")'
- name: helloFromNode
image: node:8
script:
- node -e 'console.log("Hello from node")'
거기에는 3 개의 작업이 있으며, 모든 작업은 1 분마다 실행되며 ( every: minute
) 섹션에 script
정의 된 이미지 내에서 각각의 코드 를 실행합니다 image
.
그냥 실행 docker-compose up
하고 작동하는지 확인하십시오. 다음은 전체 설명서가 포함 된 Tasker 저장소입니다.
답변
VonC의 답변은 매우 철저합니다. 또한 저에게 도움이 된 한 가지를 추가하고 싶습니다. 파일을 미행하지 않고 cron 작업을 실행 && tail -f /var/log/cron.log
하려면 cron 명령에서 cron을 제거하려는 유혹을 받습니다.
그러나 cron 명령이 완료되면 Docker는 마지막 명령이 종료되었다고 생각하여 컨테이너를 종료하기 때문에 Docker 컨테이너가 실행 직후 종료됩니다. 이를 통해 포 그라운드에서 cron을 실행하면 피할 수 있습니다 cron -f
.
답변
Docker exec
인터페이스 를 통해 컨테이너에서 실행중인 프로세스 옆에 작업을 실행하는 것이 목표이지만 관심이있을 수 있습니다.
컨테이너를 관찰하고 메타 데이터에 정의 된 작업을 예약하는 데몬을 작성했습니다. 예:
version: '2'
services:
wordpress:
image: wordpress
mysql:
image: mariadb
volumes:
- ./database_dumps:/dumps
labels:
deck-chores.dump.command: sh -c "mysqldump --all-databases > /dumps/dump-$$(date -Idate)"
deck-chores.dump.interval: daily
‘클래식’, 크론과 같은 구성도 가능합니다.