[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 -fCMD “을 참조하십시오.


답변

채택 된 솔루션 은 프로덕션 환경에서 위험 할 수 있습니다 .

도커에서는 컨테이너 당 하나의 프로세스 만 실행해야합니다.

당신이 사용하는 경우 CMD cron && tail -f /var/log/cron.log실행하기 위해 기본적으로 포크 크론 프로세스를 cron백그라운드에서 주요 프로세스 종료하고 실행하자 tailf전경. 백그라운드 크론 프로세스가 중지되거나 실패 할 수 있습니다. 컨테이너는 여전히 자동으로 실행되며 오케스트레이션 도구는 다시 시작하지 않습니다.

당신은 당신의 고정 표시기에 직접 크론의 명령 출력을 리디렉션하여 이러한 일을 방지 할 수 있습니다 stdoutstderr각각 위치 /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 저장소입니다.

http://github.com/opsxcq/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

‘클래식’, 크론과 같은 구성도 가능합니다.

여기 문서 가 있고 이미지 저장소가 있습니다.