次のような単純なDockerfileがあります
FROM ubuntu:latest
ADD crontab /etc/cron.d/test-cron
RUN chmod a+x /etc/cron.d/test-cron
RUN touch /var/log/cron.log
CMD cron && tail -f /var/log/cron.log
crontab
ファイルの内容は次のように簡単です
* * * * * root echo "Hello world" >> /var/log/cron.log 2>&1
# empty line
ローカルOS Xマシンでこれを実行すると(docker-machineが実行されている場合)、正常に動作します(「Hello world」が毎分ログファイルに出力されます)。ただし、Ubuntuマシンで実行しようとすると、cronジョブは実行されません(空のログファイル)。
コンテナを実行するために使用するコマンドは次のとおりです
docker build -t crontest .
docker run --name cron crontest
なぜそうなるのかはわかりません。私が持っているUbuntuボックスに何か問題があるのだろうか(間違った時間設定?)。そのマシンを再起動しようとしても効果がありません。現在、Ubuntuボックスで実行している他のdockerコンテナーがあり、それらは正常に実行されています。
これをデバッグ/修正するために私ができることについての提案は大歓迎です。
編集:
コンテナ(docker exec -it cron /bin/bash
)、cronがそこで実行されていることを確認できます。
root@a2ad451af8d9:/# ps -ef | grep cron
root 1 0 0 20:15 ? 00:00:00 /bin/sh -c cron && tail -f /var/log/cron.log
root 6 1 0 20:15 ? 00:00:00 cron
root 7 1 0 20:15 ? 00:00:00 tail -f /var/log/cron.log
root 25 11 0 20:21 ? 00:00:00 grep --color=auto cron
_apt-get install rsyslog
_を使用してコンテナ内にrsyslogをインストールし、_cron -L15
_(最大ロギング)でcronを開始する前に、コマンドrsyslogd
を使用して起動します。次に、コンテナ内のファイル_/var/log/syslog
_を見て、cronデーモン自身のログ出力を確認します。 crontabの解析で問題が発生したかどうかがわかります。また、登録済みでジョブを実行しようとしている場合は、次のようなエントリを毎分記録します。
CRON[16]: (root) CMD (echo "Hello world" >> /var/log/cron.log 2>&1)
特にUbuntu 14.04で同様の問題が発生しました。デバッグするために、私はcronをフォアグラウンドで実行しようとしましたが、スケジュールされたジョブを実行しようとしたときにSystem error
メッセージを出力することがわかりました。
どうやら、--net=Host
パラメーターの既知の問題です(参照: https://github.com/moby/moby/issues/5899 )。提案どおり--pid=Host
を渡そうとしましたが、それでcronジョブが正常に実行され始めました。
backup.sh
という名前のバックアップスクリプトがあり、/etc/cron.daily
にコピーしました。スクリプトは適切に呼び出されませんでした。
それを実現するには、.sh
なしでbackup
に名前を変更する必要がありました
したがって、私にとってls -l /etc/cron.daily
の出力は次のとおりです。
root@0989a35b8f94:/# ls -l /etc/cron.daily
total 24
-rwxr-xr-x 1 root root 1474 Sep 13 16:47 apt-compat
-rwxrwxr-x 1 root root 45 Nov 9 11:18 dobackup
-rwxr-xr-x 1 root root 1597 Feb 22 2017 dpkg
-rwxr-xr-x 1 root root 4125 Mar 2 2016 exim4-base
-rwxr-xr-x 1 root root 249 May 17 11:59 passwd
これをテスト/分析するために、次のアプローチを使用しました。
Crontabファイルcat /etc/crontab
を調べて、毎日のcronjobsについて次の行を示しました。
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
次に、バックアップスクリプトを専用フォルダーに分離しました。
mkdir /etc/cron.test
mv /etc/cron.daily/dobackup /etc/cron.test
その後、実行することにより
test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.test)
別の端末でps auxf
を使用すると、ジョブが現在実行されていることがわかりました。 .sh
バージョンに名前を変更するときに壊れることを確認することもできます。
mv /etc/cron.test/dobackup /etc/cron.test/dobackup.sh
test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.test)
その後すぐに存在するため、ジョブは実行されません。
私の場合、COPY
ファイルを作成すると、セカンダリハードリンクが作成されました(Windowsの場合もあります)。
私がしなければならなかったことは、ファイルが実行中のコンテナ内に作成されたことを確認することでした。
FROM mysql:5.7
RUN apt-get update && apt-get install -y anacron
COPY crontab /tmp/crontab
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Run the command on container startup
CMD (cat /tmp/crontab > /etc/cron.d/hello-cron ) && cron && tail -f /var/log/cron.log
最近debianで修正されました: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=726661 およびUbuntu Wily(15.10)。
回避策として、/ etc/pam.d/cron内のpam_loginuid.soモジュールにコメントを付けて、cron(またはdockerコンテナー)を再起動してください。