Ubuntu 22.04 Jammy - cron 似乎忽略了时区

Ubuntu 22.04 Jammy - cron 似乎忽略了时区

我有一个配置为使用时区的服务器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都返回预期的结果,但 cron 仍然以 UTC 运行,即

$ 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

在 crontab 中添加类似这样的内容57 0 * * * date >> /tmp/cron-test.log会导致输出Wed Jul 5 12:57:01 NZST 2023写入日志文件。我的理解是 cron 应该在本地时间运行,但这并不是我观察到的。

我读过几个 StackOverflow 帖子,并尝试了以下方法,但无济于事:

  • 设置TZCRON_TZ/etc/crontab
  • 设置TZCRON_TZcrontab -e
  • 设置TZCRON_TZ/etc/environment
  • 设置TZCRON_TZ系统/etc/systemd/system/cron.service.d/override.conf日志说它忽略了这一点
  • 设置TZCRON_TZService/Environment/etc/systemd/system/cron.service.d/override.conf

每次尝试后我都会跑sudo systemctl daemon-reload && sudo service cron restart

我的观察是,设置TZ在任何情况下的唯一效果是更改 crontab 中运行的命令的时区,而不是 cron 本身。设置CRON_TZ对任何事情都没有影响。

我也尝试过这个,env -i $(cat /proc/$(</var/run/crond.pid)/environ|xargs -0 echo) date +%Z试图查看 cron 在哪个时区运行,它返回了NZST它应该运行的时区,但不幸的是,情况似乎并非如此......

我发现这个帖子中有人看到了几乎相同的行为:https://ubuntuforums.org/showthread.php?t=2477727- 对他来说,更新软件包并重新启动似乎已经解决了这个问题,但这对我来说似乎不起作用。

任何智慧都将受到赞赏。

更新 1

这个帖子cron 采用 UTC 时间而不是本地时间有一个似乎适用于我的情况的答案:

如果你没有将硬件时间设置为与系统时间匹配,那么 cron 将根据硬件时间运行

运行sudo timedatectl set-local-rtc 1似乎让 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'.

因此,cron 似乎是在硬件时间上运行的。不幸的是,不建议将硬件时钟设置为本地时间,而且无论如何都会被撤消。遗憾的是,这不是解决方案,但确实开辟了另一条调查途径。

更新2

对硬件时钟的调查让我发现了以下几点:

  1. 你可以通过几种不同的方式将其设置为使用本地时间 - sudohwclock --systohc --localtimetimedatectl set-local-rtc 1
  2. 我发现这一页有人在那里讨论传统的方法和/etc/adjtime文件。

事实证明,timedatectl和都以不同的方式hwclock更新文件和。使用任何一种机制将其设置为本地时间都会产生抱怨。然而,在运行之前似乎保留了一些设置,允许 cron 在正确的时间运行并防止抱怨。/etc/adjtimetimedatectl statushwclock --systohc --localtimetimedatectl set-local-rtc 0timedatectl status

此时 cron 运行正常,但我不确定 NTP 更新后设置是否会保留。我将尝试重建一些服务器,并回答问题是否能解决问题。

答案1

按照这个答案经过沃伦- 问题是 cron 使用的是硬件时钟而不是系统时钟。

我发现执行以下操作可以解决此问题:

# use local time for hardware time and set drift factor
hwclock --systohc --localtime

# use UTC time for hardware time 
timedatectl set-local-rtc 0

这会使硬件时钟使用本地时间,并创建一个配置文件,然后/etc/adjtime将硬件时钟恢复为 UTC,但保留配置文件。请注意,timedatectl set-local-rtc 1不会设置配置参数这是为了工作所必需的,所以hwclock似乎是必需的。

上述解决方案创建的配置/etc/adjtime似乎使 cron 在正确的时区运行,而不会破坏 NTP 更新之类的操作。

这可能不是最好的解决方案,但它确实解决了问题。

相关内容