You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Ubuntu 22.04 Jammy中cron忽略本地时区设置仍以UTC触发任务的问题求助

Ubuntu 22.04 Jammy中cron忽略本地时区设置仍以UTC触发任务的问题求助

我最近碰到了一个非常棘手的问题:我的服务器已经配置为Pacific/Auckland时区,但cron却始终以UTC时间来触发任务。

在之前的系统版本中,我只需要执行以下几条命令,就能让所有服务(包括cron)都遵循指定时区运行:

sudo ln -sf /usr/share/zoneinfo/$TIMEZONE /etc/localtime
echo "$TIMEZONE" | sudo tee /etc/timezone
sudo dpkg-reconfigure --frontend noninteractive tzdata
sudo timedatectl set-timezone $TIMEZONE

但现在这套操作对cron完全无效——datetimedatectl都能返回正确的本地时间:

$ date
Wed Jul  5 12:50:01 NZST 2023
$ timedatectl
Local time: Wed 2023-07-05 12:50:01 NZST
Universal time: Wed 2023-07-05 00:50:01 UTC
RTC time: Wed 2023-07-05 00:50:00
Time zone: Pacific/Auckland (NZST, +1200)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no

可cron还是顽固地用UTC时间运行。比如我在crontab里添加了这条测试任务:

57 0 * * * date >> /tmp/cron-test.log

结果日志里记录的执行时间是Wed Jul 5 12:57:01 NZST 2023——这明显是UTC的0点57分触发的,对应本地时间12点57分,完全不符合预期(我本来想让它在本地0点57分执行)。

我查了不少相关讨论,试了各种方法都没解决:

  • /etc/crontab中设置TZCRON_TZ变量
  • 在用户crontab(crontab -e)中添加TZCRON_TZ
  • /etc/environment里配置这两个时区变量
  • /etc/systemd/system/cron.service.d/override.conf中直接设置,结果syslog显示cron忽略了这个配置
  • 在override.conf的[Service]段里通过Environment字段设置TZCRON_TZ

每次修改后我都执行了sudo systemctl daemon-reload && sudo service cron restart,但结果只有设置TZ会改变crontab中任务执行时的时区,cron本身的触发时间还是UTC;CRON_TZ则完全没任何效果。

我还尝试查看cron进程的实际时区环境,执行了这条命令:

env -i $(cat /proc/$(</var/run/crond.pid)/environ|xargs -0 echo) date +%Z

返回的是NZST,看起来时区是对的,但实际任务触发时间就是不对。


更新1

后来看到一个思路说:如果硬件时钟(RTC)没有和系统时间同步,cron会使用硬件时间。我试了执行sudo timedatectl set-local-rtc 1,刚开始cron确实按正确的本地时间触发了,但timedatectl status会弹出警告,而且过一段时间后RTC又被自动改回UTC,cron也跟着变回UTC触发了。这种方法不仅不被官方推荐,还不稳定,显然不是可行的解决方案,但至少让我找到了一个新的排查方向。

执行timedatectl status的警告信息如下:

Local time: Wed 2023-07-05 14:13:01 NZST
Universal time: Wed 2023-07-05 02:13:01 UTC
RTC time: Wed 2023-07-05 14:13:01
Time zone: Pacific/Auckland (NZST, +1200)
System clock synchronized: yes
NTP service: active
RTC in local TZ: yes

Warning: The system is configured to read the RTC time in the local time zone.
This mode cannot be fully supported. It will create various problems
with time zone changes and daylight saving time adjustments. The RTC
time is never updated, it relies on external facilities to maintain it.
If at all possible, use RTC in UTC by calling
'timedatectl set-local-rtc 0'.

更新2

顺着硬件时钟的方向继续排查,我发现有两种方式可以将RTC设置为本地时间:sudo hwclock --systohc --localtimetimedatectl set-local-rtc 1,而且这两个命令对/etc/adjtime文件的修改方式不一样。

我尝试了一个组合操作:先执行sudo hwclock --systohc --localtime,再执行sudo timedatectl set-local-rtc 0。现在cron终于能按正确的本地时间触发任务了,而且timedatectl status也不会再弹出警告。不过目前我还不确定NTP更新后这个设置会不会被覆盖,打算重建几台服务器测试,如果稳定的话会再来更新最终的解决方法。


备注:内容来源于stack exchange,提问作者Az Ilari

火山引擎 最新活动