LoginSignup
20
11

More than 1 year has passed since last update.

Dockerコンテナ内でcronが動かない時の対処

Last updated at Posted at 2020-05-11

経緯

こちらの本の通りに進めていたところcronが動きませんでした。
Docker/Kubernetes 実践コンテナ開発入門

設定とエラー内容

設定はubuntuイメージのタグ以外本の通りです。

Dockerfile
FROM ubuntu:20.10 #バージョンは本のものではなく現時点の最新にしております。

RUN apt update
RUN apt install -y cron

COPY task.sh /usr/local/bin/
COPY cron-example /etc/cron.d/
RUN chmod 0644 /etc/cron.d/cron-example

CMD ["cron", "-f"]
cron_example
* * * * *         root  sh /usr/local/bin/task.sh
task.sh
#!/bin/sh
echo "[`date`] Hello!" >> /var/log/cron.log

この内容にてビルドし、コンテナを実行

docker image build -t xxx/cronjob:latest .
docker container run -d --rm --name cronjob xxx/cronjob:latest

頃合いを見てコンテナ内のログを確認するとログファイルが作成されていない

docker container exec -it cronjob tail -f /var/log/cron.log
tail: cannot open '/var/log/cron.log' for reading: No such file or directory
tail: no files remaining

コンテナの中に入ってcronまわりを確認してもおかしいところ見当たらず

#コンテナ内へ
docker exec -it cronjob bash

#クーロンの稼働状況は問題なし
#念の為再起動しても変わらず
service cron status
 * cron is running

#ロックファイルを確認するも削除しても別のプロセスのロックファイルが作成されるのみ
#こちらもロック対象のプロセスIDをkillしたりしましたがすぐに別プロセスでロックファイルが作成されるだけなので関係なしと判断。
cron -f 
cron: can't lock /var/run/crond.pid, otherpid may be 1: Resource temporarily unavailable
rm /var/run/crond.pid
cron -f 
cron: can't lock /var/run/crond.pid, otherpid may be 297: Resource temporarily unavailable

#cronの内容を直接実行するとシェル実行されることを確認(シェル内で出力しているログが動くため)
sh /usr/local/bin/task.sh

その他、サーバー時間がUTCだったりしましたが、cron内で特定の時間帯を指定していないので関係ない。

解決方法

まずはじめに、再現性のある解決方法だったもののなぜこれでうまくいくのかわかっていません。(どなたか思い当たる方おりましたらお教えください)
経緯としてはcron_exampleの記述に誤りがあるのかもと思ったのですが、修正都度コンテナを作り直すのが面倒だったのでviで直接編集したところcronが動いたので手順としました。

(追記)コメントにて教えていただきました!

どうもcron_exampleの改行コードがCRLFが原因だったみたいです。

cron_exampleの作成時に改行コードをLFにすれば、本事象は発生しないと思います。

1.ubuntuにviをインストール

コンテナ作成しただけだとviが入っていないので。(入っているのならこの手順は不要です)

#コンテナ内へ
docker exec -it cronjob bash
#aptにてインストール
apt-get update
apt-get install vim

2.cron.d配下のcron_exampleを一度viで開いて保存(文法的に問題ないのであれば何か変更する必要はないです)

なお文字コードが変わったりするのかもと思い、fileで観察していましたが変わらず
#(以下コンテナ内にて実施しています)
#変更前のファイル情報
file -i /etc/cron.d/cron-example 
cron-example: text/plain; charset=us-ascii

#viで編集(内容を変える必要はないです)
vi /etc/cron.d/cron-example 

#変更後のファイル情報(変わっていない・・・)
file -i /etc/cron.d/cron-example 
cron-example: text/plain; charset=us-ascii

3.すでに作成されているロックファイルの削除

#(以下コンテナ内にて実施しています)
rm /var/run/crond.pid

4.cronが動いていることを確認(これはコンテナの外で実行しています)

#(以下コンテナ外にて実施しています)
docker container exec -it cronjob tail -f /var/log/cron.log
[Mon May 11 08:30:01 UTC 2020] Hello!

その後

Dockerfileにviインストールまで記述し、再度イメージ作成&コンテナ実行をし、手順2から行なったところ問題なく動きました。

Dockerfile
FROM ubuntu:20.10

RUN apt update
RUN apt install -y cron
RUN apt install -y vim #追加(ただし、コンテナ起動後、vi編集&保存の手間は省けず・・・。

COPY task.sh /usr/local/bin/
COPY cron-example /etc/cron.d/
RUN chmod 0644 /etc/cron.d/cron-example

CMD ["cron", "-f"]

おわりに

なぜこの手順でcronが動いたのか(そもそもコンテナ起動時になぜ動かないのか)わかる方おられましたら教えていただけると嬉しいです。
(追記)コメントにて教えていただきました!

どうもcron_exampleの改行コードがCRLFが原因だったみたいです。

cron_exampleの作成時に改行コードをLFにすれば、本事象は発生しないと思います。

20
11
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
11