OpenJDK 1.8.0 in Docker container has different timezone than /etc/timezone and from the host
我有一个运行Docker容器的Linux盒子,该容器正在运行TomEE,并运行我构建的WAR。
在基本的Linux框上,我得到的"日期"值是" PST 2017年1月20日10:37:27"。未设置TZ环境变量。
当我运行以下课程时:
1 2 3 4 5 6 7 8 |
我明白了:
1 | date[Fri Jan 20 10:39:02 PST 2017] tzoffset[-28800000] |
这很好。
在运行在该容器上的Docker容器中,其中我将" -v / etc / localtime:/ etc / localtime"作为卷映射之一,显然,我具有相同的/ etc / localtime文件。未设置TZ环境变量。当我在容器中运行"日期"时,我得到的时间值与基本主机中的时区(PST)相同。
然后我编译并运行与上述相同的Java类,并得到以下信息:
1 | date[Fri Jan 20 18:30:38 UTC 2017] tzoffset[0] |
然后我将容器中的TZ环境变量手动设置为" America / Los_Angeles"(请记住,该变量未在基本主机中设置)(我通过查看" / etc / localtime"符号链接到的文件来验证了此值在基本主机上)。
然后我在容器上重新运行该类,并得到以下信息:
1 | date[Fri Jan 20 10:35:08 PST 2017] tzoffset[-28800000] |
请注意,基本主机和容器上的两个Java版本几乎相同。它们都是OpenJDK 1.8.0_111(主机上的b15,容器上的b14)。
那么,有人可以解释一下这里发生了什么吗?在基本主机上,我有" etc / localtime"指向正确的文件,但没有设置TZ。它使用Java类中的"日期"报告正确的时区。在容器上," / etc / localtime"指向正确的文件,而我最初没有设置TZ。" date"命令返回正确的值,但是Java没有。
我不得不手动将容器上的TZ设置为主机的TZ值,这使其正常工作。我真的不愿意这样做。对我来说,这似乎是一种hack。
更新:
我在" localtime(5)"手册页中注意到以下内容:
Because the timezone identifier is extracted from the symlink target
name of /etc/localtime, this file may not be a normal file or hardlink.
所以,这可能是我的问题的一部分。仍然很好奇外壳中的"日期"工作正常,但是Java(没有TZ设置)感到困惑。
我遇到了与您相同的问题(CentOS,Docker,OpenJDK)。我们通过以下方式解决了它:
不挂载本地时间,挂载/ etc / timezone。
如果没有/ etc / timezone文件(例如,在CentOS上),则可以在主机上执行以下操作:
1 | timedatectl | awk '/Time zone:/ {print $3}' > /etc/timezone_host |
然后在容器中(例如入口点)
1 2 3 4 | TZ_HOST=$(cat /etc/timezone_host) echo $TZ_HOST > /etc/timezone export TZ=$TZ_HOST dpkg-reconfigure --frontend noninteractive tzdata |
按照https://unix.stackexchange.com/questions/452559/what-is-etc-timezone-used-for中Gilles的回答,由于历史原因,Java读取
可能会转储环境(env命令),LC _ *(通常为LC_ALL)会影响环境。