如果服务可以在没有特权的情况下运行,请使用USER更改为非root用户。
对于cron
,这似乎不切实际,因为cron
需要root特权才能正常运行。但是,cron
运行的可执行文件不需要root特权。因此,我以cron
用户的身份运行root
本身,但是调用我的crontab
脚本以将非可执行文件(在本例中为我编写的简单Python FTP下载脚本)运行root用户通过crontab -u <user>
命令。
cron / Docker的交互性和社区经验似乎仍处于起步阶段,但是有一些不错的解决方案。利用this和this优秀文章中的经验教训,我得出了一个看起来像这样的Dockerfile:
FROM python:3.7.4-alpine
RUN adduser -S riptusk331
WORKDIR /home/riptusk331
... boilerplate not necessary to post here ...
COPY mycron /etc/cron.d/mycron
RUN chmod 644 /etc/cron.d/mycron
RUN crontab -u riptusk331 /etc/cron.d/mycron
CMD ["crond", "-f", "-l", "0"]
mycron
文件只是每分钟运行一次的简单python执行
* * * * * /home/riptusk331/venv/bin/python3 /home/riptusk331/ftp.py
这工作得很好,但是我不确定在这里如何准确地处理日志。我看不到/var/log/cron
中保存的任何内容。我可以在终端上看到cron
和ftp.py
的输出,也可以在Kitematic中将其输出到容器日志中。但是我不知道这里到底发生了什么。
所以我的第一个问题是: 这里如何处理日志和输出(在cron作业后不进行任何重定向),并且此实现方法是否安全? < / strong>
VonC对this post的回答建议将> /proc/1/fd/1 2>/proc/1/fd/2
附加到您的cron作业中,以将输出重定向到Docker的stdout
和stderr
。这是我俩都有些困惑并遇到麻烦的地方。
我的crontab文件现在看起来像这样
* * * * * /home/riptusk331/venv/bin/python3 /home/riptusk331/ftp.py > /proc/1/fd/1 2>/proc/1/fd/2
没有任何重定向的输出 出现了 ,已经准备好输出到stdout / stderr,但是我不确定。我只知道它显示在我的终端上。那么为什么需要这种重定向?
添加此重定向时,遇到权限问题。回想一下,该crontab被称为非root用户 riptusk331
。因此,我没有超级用户访问权限,并收到以下错误:
/bin/ash: can't create /proc/1/fd/1: Permission denied
答案 0 :(得分:2)
Alpine基本映像基于名为BusyBox的紧凑工具集,当您运行crond
时,此处得到的是BusyBox cron,而不是其他任何实现。它的documentation有点稀疏,但是如果您查看the crond source(在C语言中),将会发现在运行作业时根本没有任何重定向(请参见非-start_one_job
的发送邮件版本);作业的标准输出和标准错误是crond的标准输出和标准错误。在Docker中,由于crond是容器的主要进程,因此又成为了容器的输出流。
docker logs
中显示的所有内容都明确地传递到stdout或stderr或容器的主进程。如果此cron实现将任务的输出直接写在该位置,则利用它不会有任何错误或不安全感。
在较重的容器编排系统中,有一些方法可以按计划运行容器(Kubernetes CronJobs,Nomad定期作业)。您可能会发现,与这些系统相比,更容易且更一致地设置一个容器,该容器一次运行您的作业,然后退出,然后设置 host的 cron以运行您的容器(必要时,以root身份运行)
答案 1 :(得分:0)
您需要允许CAP_SETGID以用户身份运行crond
,如果将其设置为所有busybox二进制文件,则可能存在安全风险,但是您可以使用dcron
软件包而不是busybox的内置{{1 }},然后在该程序上设置crond
。使用CAP_SETGID
作为运行用户,这是为Alpine添加的内容
riptusk331