2017-05-05 10 views
6

Sử dụng Docker cho Mac 1.13.1 với Dockerfile sau:Output của `đuôi -f` ở phần cuối của một Docker CMD không hiển thị

FROM ubuntu:latest 
MAINTAINER [email protected] 

#Install packages and clean downloaded packages in the lowest layer 
RUN apt-get update && apt-get -y install cron && rm -rf /var/lib/apt/lists/* 

# Add crontab file in the cron directory 
ADD crontab /etc/cron.d/hello-cron 

# Give execution rights on the cron job and create the log file to tail in the next layer 
RUN chmod 0644 /etc/cron.d/hello-cron && touch /var/log/cron.log 

# Run the command on container startup 
CMD echo "starting" && echo "continuing" && (cron) && echo "tailing..." && tail -f /var/log/cron.log 

Với một tập tin contab của:

* * * * * root echo "Hello world `date`" >> /var/log/cron.log 2>&1 
# Don't remove the empty line at the end of this file. It is required to run the cron job 

Khi tôi xây dựng và chạy nó với:

docker build -t docker-cron-master . 
docker run docker-cron-master 

tôi thấy kết quả:

docker run docker-cron-master 
starting 
continuing 
tailing... 

Nếu tôi đợi một phút, đầu ra tail -f không xuất hiện. Tuy nhiên, nếu tôi đăng nhập vào container chạy và đuôi tập tin tôi có thể xem nội dung:

$ docker exec -it 4eda6b1fc6ce bash 
[email protected]:/# tail -f /var/log/cron.log 
Hello world Fri May 5 09:53:01 UTC 2017 
Hello world Fri May 5 09:54:01 UTC 2017 

Tôi đã thử thêm tiếng vang khác ở phần cuối của CMD để xem nếu nó chỉ là lệnh cuối cùng của những người STDOUT bị nuốt nhưng điều đó không giúp được gì.

Tôi đã đăng mã trên github tại https://github.com/simbo1905/docker-cron

Cảm ơn!

+0

Chạy chương trình chính (đuôi) bằng 'exec' nếu không nó sẽ không nhận tín hiệu Ctrl-C (thoát). Điều đó cũng có thể khắc phục được sự cố của bạn. '&& exec tail -f ..' – Alkaline

Trả lời

6

Hệ thống tệp docker sử dụng copy-on-write với fs công đoàn phân lớp. Vì vậy, khi bạn ghi vào một tập tin là một phần của hình ảnh, trước tiên nó sẽ tạo một bản sao của tập tin đó vào hệ thống tập tin thùng chứa mà là một lớp trên tất cả các lớp hình ảnh.

Điều đó có nghĩa là khi bạn thêm một dòng vào /var/log/cron.log, nó sẽ nhận được một inode mới trong hệ thống tệp và tệp mà lệnh tail đang theo sau không còn là lệnh bạn thấy khi bạn docker exec vào vùng chứa. Bạn có thể giải quyết điều đó với một thay đổi nhỏ để phụ thêm "không có gì" vào tập tin đó cũng sẽ thay đổi dấu thời gian cập nhật cuối cùng mà buộc một copy-on-write:

CMD echo "starting" && echo "continuing" && (cron) \ 
&& echo "tailing..." && : >> /var/log/cron.log && tail -f /var/log/cron.log 

Tôi đặt cùng một ý chính mà đi qua vấn đề này với nhiều chi tiết hơn ở đây: https://gist.github.com/sudo-bmitch/f91a943174d6aff5a57904485670a9eb

+0

Không thể đợi để thử điều này. Nó sẽ giải thích rất nhiều lỗi kỳ lạ mà tôi đã nhìn thấy. – Robert

+1

Tôi kéo repo và kiểm tra trước khi đăng. Nghi ngờ đầu tiên của tôi là bộ đệm đầu ra nhưng 'stdbuf' không sửa nó. Đã xác minh với 'ls -il/var/log/cron.log' rằng nó nhận được một inode mới sau lần viết đầu tiên. – BMitch

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