2015-04-01 43 views
9

Tôi đã tạo hình ảnh Docker, từ Dockerfile và tôi muốn một cronjob được thực thi định kỳ khi vùng chứa dựa trên hình ảnh này đang chạy. Dockerfile của tôi là thế này (những phần có liên quan):Bên trong thùng chứa Docker, cronjobs không được thực hiện

FROM l3iggs/archlinux:latest 

COPY source /srv/visitor 

WORKDIR /srv/visitor 

RUN pacman -Syyu --needed --noconfirm \ 
     && pacman -S --needed --noconfirm make gcc cronie python2 nodejs phantomjs \ 
     && printf "*/2 * * * *  node /srv/visitor/visitor.js \n" >> cronJobs \ 
     && crontab cronJobs \ 
     && rm cronJobs \ 
     && npm install -g node-gyp \ 
     && PYTHON=/usr/sbin/python2 && export PYTHON \ 
     && npm install 

EXPOSE 80 

CMD ["/bin/sh", "-c"] 

Sau khi tạo ra các hình ảnh tôi chạy một container và xác minh rằng thực sự là cronjob đã được thêm vào:

crontab -l 

*/2 * * * *  node /srv/visitor/visitor.js 

Bây giờ, vấn đề là các cronjob không bao giờ được thực hiện. Tôi có, tất nhiên, thử nghiệm rằng "node/srv/visitor/visitor.js" thực hiện đúng khi chạy thủ công từ giao diện điều khiển.

Bất kỳ ý tưởng nào?

+3

cron yêu cầu daemon. một nửa quá trình tạo công việc, nằm trong kho lưu trữ tệp của cron. Một nửa còn lại để cron đang thực hiện công việc. bạn có thể xem: http://stackoverflow.com/questions/20545554/how-do-i-start-cron-on-docker-ubuntu-base. Nếu bạn muốn cron daemon của máy chủ lưu trữ để làm cronwork của bạn, bạn có lẽ sẽ cần phải gắn kết thư mục cron máy chủ khi bạn bắt đầu container? Điều đó không tốt lắm! – Greg

+0

Greg, tại sao bạn không thêm câu trả lời đó làm câu trả lời? Tôi định nói như vậy. Cũng lưu ý hình ảnh Phusion đi kèm với cron đang chạy. –

+0

@Greg Bây giờ tôi có thể hiểu những gì bạn đang nói. Vấn đề là, tôi không muốn hoặc là gắn kết thư mục cron của máy chủ, hoặc chạy systemd bên trong thùng chứa (theo một số gợi ý khác). Tôi cảm thấy như cả hai phương pháp này sẽ không cần thiết "gây ô nhiễm" một hệ thống khác. Lựa chọn thay thế của tôi là gì? Tôi có thể chạy cronie mà không có systemd? Hoặc, là có một sự thay thế? – dsljanus

Trả lời

6

Đó là một chút khó khăn để trả lời này dứt khoát, như tôi không có thời gian để kiểm tra, nhưng bạn có các tùy chọn khác nhau dành cho bạn:

  • Bạn có thể sử dụng hình ảnh cơ sở Phusion, mà đi kèm với một hệ thống init và cron được cài đặt. Nó dựa trên Ubuntu và tương đối nặng (ít nhất là so với archlinux) https://registry.hub.docker.com/u/phusion/baseimage/

  • Nếu bạn sẵn sàng bắt đầu từ công việc cron, bạn có thể bắt đầu cron từ CMD và giữ nó ở tiền cảnh (cron -f).

  • Bạn có thể sử dụng trình quản lý quy trình trọng lượng nhẹ để khởi động cron và bất kỳ quy trình nào khác bạn cần (Phit use runit, Docker dường như đề xuất supervisor).

  • Bạn có thể tự viết CMD hoặc ENTRYPOINT tập lệnh bắt đầu cron và quá trình của bạn. Vấn đề duy nhất với điều này là bạn sẽ cần phải cẩn thận để xử lý tín hiệu đúng cách hoặc bạn có thể kết thúc với quá trình zombie.

Trong trường hợp bạn chỉ chơi xung quanh, tôi sẽ chọn tùy chọn cuối cùng, nếu nó nghiêm trọng hơn, tôi sẽ đi với người quản lý quy trình.

+0

Điều đầu tiên trước tiên, cảm ơn bạn đã trả lời kỹ lưỡng. Tôi có xu hướng đi với tùy chọn thứ hai, chạy cron với lệnh CMD, vì tất cả những gì tôi muốn làm là chạy một lệnh duy nhất cứ mỗi 2 phút quảng cáo vô hạn. Thing là, Arch không có "cron" vì cronie là một gói hậu mãi. Ngoài ra, nếu đây là oveecome, tôi có thể chạy cron trong nền không? Vì vậy, tôi có thể đính kèm vào container nên bao giờ tôi muốn. – dsljanus

+0

Tôi không biết gì về cronie, nhưng tôi hy vọng nó sẽ hoạt động giống nhau. Bạn vẫn có thể vào trong thùng chứa bằng 'docker exec -it CONTAINER/bin/bash', vì vậy đó không phải là vấn đề. –

+0

Bên trong vùng chứa đang chạy, crond đang chạy và được xác minh bởi "ps -aux | grep cron". Tất nhiên nó đã được ghi bằng tay. Thing là, vẫn không có cronjobs đang được thực hiện. – dsljanus

7

Một lựa chọn là sử dụng crontab của máy chủ theo cách sau:

0 5 * * * docker exec mysql mysqldump --databases myDatabase -u myUsername -pmyPassword > /backups/myDatabase.sql 

Trên đây định kỳ sẽ mất một bản sao lưu hàng ngày của một cơ sở dữ liệu MySQL.

Nếu bạn cần lệnh chuỗi phức tạp bạn cũng có thể sử dụng định dạng này:

0 5 * * * docker exec mysql sh -c 'mkdir -p /backups/`date +\%d` && for DB in myDB1 myDB2 myDB3; do mysqldump --databases $DB -u myUser -pmyPassword > /backups/`date +\%d`/$DB.sql; done' 

Trên đây có một cán backup 30 ngày của nhiều cơ sở dữ liệu và thực hiện một bash cho vòng lặp trong một dòng duy nhất chứ không phải bằng văn bản và gọi một kịch bản lệnh shell để làm như vậy. Vì vậy, nó khá linh hoạt.

Hoặc bạn cũng có thể đặt các kịch bản phức tạp bên trong container Docker và chạy chúng như vậy:

0 5 * * * docker exec mysql /dailyCron.sh 
+0

Cách tiếp cận này không thể giúp bạn giữ cho bên ứng dụng được cấu hình nhiệm vụ. – BigDong

3

Nếu bạn đang chạy chứa Docker của bạn với --net = máy chủ, xem chủ đề này: https://github.com/docker/docker/issues/5899

Tôi đã gặp sự cố tương tự và tác vụ cron của tôi bắt đầu chạy khi tôi đưa vào --pid = máy chủ trong các đối số dòng lệnh chạy docker.

Các vấn đề liên quan