dockerでBusyBox crondが動かない

webの参考例に従って実施していたのに、BusyBox crondが動かず数時間悩みました。原因が分かったので忘れないよう備忘録です。

dockerでBusyBox crondが動かなかった原因

https://github.com/jgunthorpe/busybox/blob/master/miscutils/crond.c

のソースを確認したところ、影響している部分は以下でした。

~~~
#define DaemonUid 0
~~~
static void SynchronizeFile(const char *fileName)
~~~
			if (fstat(fileno(fi), &sbuf) == 0 && sbuf.st_uid == DaemonUid) {
~~~

BusyBox crondの対象となる設定ファイルに対して、st_uidをチェックしていました。

このDaemonUid = 0 が何を意味するかというと、ユーザIDが0でユーザrootということです。

つまり、以下のようなcron設定ファイルを/var/spool/cron/crontabs配下に格納しても、

* * * * * date
# ll
drwxr-xr-x 2 root root 4096 Mar 13 17:18 ./
drwxr-xr-x 3 root root 4096 Mar 13 17:18 ../
-rw-rw-r-- 1 root root   25 Mar 11 23:55 root <= 所有者がrootでないとBusyBox crondの対象とならない

所有者がrootでないとBusyBox crondの対象となりません。

dockerでBusyBox crondを動かす参考例

# ll
-rw-rw-r--  1 xxx xxx  330  3月 13 21:50 Dockerfile
-rw-rw-r--  1 xxx xxx   15  3月 13 21:49 crontab
FROM ubuntu

RUN apt update && apt install -y \busybox-static \
        && apt install -y tzdata \
        && apt clean \
        && rm -rf /var/lib/apt/lists/*

# タイムゾーン設定
ENV TZ=Asia/Tokyo

# mai.shファイルをコピー
COPY --chown=root:root ./crontab /var/spool/cron/crontabs/root

CMD ["busybox", "crond", "-f", "-L", "/dev/stderr"]
* * * * * date

docker imageを作成します。

# sudo docker build --tag=ubuntu-crond-test .

dockerコンテナを起動します。

# sudo docker run --rm --name ubuntu-crond-test-c -d ubuntu-crond-test:latest

1分毎にdateコマンドが動いていることが確認できます。

# sudo docker logs -f ubuntu-crond-test-c
crond: crond (busybox 1.30.1) started, log level 8
crond: USER root pid   7 cmd date
Sat Mar 13 22:07:00 JST 2021
crond: USER root pid   8 cmd date
Sat Mar 13 22:08:00 JST 2021
crond: USER root pid   9 cmd date
Sat Mar 13 22:09:00 JST 2021