如何确保Docker与主机时间同步?

133

我在Linode服务器上运行着Docker。有时候,我发现Docker上的时间不正确。目前,我已经在每个Docker的运行脚本中添加了以下代码行。

yum install -y ntp
service ntpd stop
ntpdate pool.ntp.org

然而,我最理想的情况是Docker应该与主机同步时间。是否有一种方法可以实现这一点?


1
可能是Will docker container auto sync time with the host machine?的重复问题。 - Ben Whaley
容器将使用与主机相同的时间。请参阅此问答,其中包含来自Docker核心开发人员之一的答案。 - Ben Whaley
这是一个明显的重复问题,但即使对于其他问题的答案也在谈论时区,而我并不真的关心。对答案的评论表明,时钟漂移不会发生,因为Docker和主机使用相同的时钟。感谢Ben指出这一点。 - Ranjith Ramachandra
12
警告:有些人对于什么是“主机”存在一些混淆。除了Linux和Windows 10 +带有Linux子系统的操作系统外,Docker机器(即主机)实际上是一台虚拟机。当Docker主机不是您运行docker命令的机器时,您可能会看到时间偏差,并且像挂载卷这样的事情可能无法按照您的预期工作。当您设置远程Docker机器时,例如在DigitalOcean上,也会发生这种情况。 - Codebling
22个回答

128
本答案的来源是回答该问题的评论: Will docker container auto sync time with the host machine? 经过研究后,我意识到在docker容器上不可能发生时钟漂移。Docker使用与主机相同的时钟,而且docker不能更改它。这意味着在docker内执行ntpdate无效。
正确的做法是使用ntpdate更新主机时间。
至于同步时区,-v /etc/localtime:/ etc/localtime:ro可以工作。

6
请告诉我这是怎么回事?如果Docker使用的是和系统相同的时钟,那么它的时钟怎么可能与主机不同?如果发生时钟漂移,那么漂移会发生在Docker主机上,需要在那里解决时钟漂移问题。我很想知道我是否理解正确。 - Ranjith Ramachandra
11
在 Mac 上使用 boot2docker 运行 Docker 时,可能会导致 boot2docker 虚拟机时间不同步。Docker 与其主机仍然保持同步,但其主机提供了错误的时间。重新启动虚拟机是最简单的解决方法。 - Nathaniel Waisbrot
60
这是一个完全不同的问题,与虚拟机失去时间有关。从技术上讲,Docker 仍与其主机(即虚拟机)保持同步。 - Ranjith Ramachandra
3
如果您使用的是boot2docker,请执行boot2docker restart来重启虚拟机。如果您在运行自己的虚拟机,则可以在其中执行ntpdate命令来同步时间。 - Nathaniel Waisbrot
7
我在使用Windows操作系统。主机的时间是15:06,但容器的时间显示是18:41。这是怎么回事? - willem
显示剩余4条评论

68

您可以将本地文件(/etc/timezone和/etc/localtime)作为卷添加到Docker容器中。

使用以下行更新您的docker-compose.yml文件。

volumes:
    - "/etc/timezone:/etc/timezone:ro"
    - "/etc/localtime:/etc/localtime:ro"

现在容器时间与您的主机时间相同。


50

3
现在我找到了我想要的秘密!我错过了几天,证书也很不爽。谢谢你! - Josiah
2
谢谢这个。非常顺利地完成了工作。 - Ryan Nutt
2
我曾经遇到过广为报道的Docker for Windows在睡眠后无法同步时间的问题,这个修复方法就像魔法一样奏效!它是做什么的? - StackG
2
太棒了,我在Docker / Win10上解决了我的问题。 - Eric Kramer
1
这正是我所需要的,花了一个小时尝试所有不同的ntpdate解决方案,但是Docker阻止了它。这对我的.devcontainer起作用了。 - Morrious
显示剩余2条评论

40
如果您正在使用boot2docker,并且在docker虚拟机内无法正常工作(您在代理后面,该代理未转发ntp数据包),但您的主机已经进行了时间同步,那么您可以从主机上运行以下命令:
docker-machine ssh default "sudo date -u $(date -u +%m%d%H%M%Y)"

这样做会将您机器当前的时间(在UTC时区)作为字符串发送,使用date设置docker虚拟机的时间(同样在UTC时区)。

注意:在Windows中,在msys git的bash shell内使用:

docker-machine.exe ssh default "sudo date -u $(date -u +%m%d%H%M%Y)"

太好了!那正是我的问题,它立即解决了它,而不需要重新启动docker-machine。 - qwertzguy
1
能否设置秒数?我尝试添加%S,但时间无效。 - Sakib
@Sakib,date命令只接受格式为MMDDhhmm[[CC]YY][.ss]的日期设置方式,因此要添加秒数,您需要将它们放在字符串的末尾,如下所示:+%m%d%H%M%Y.%S - gvlx

31

以下是我在Fedora 20主机上使用的方法。我运行了一个容器:

docker run -v /etc/localtime:/etc/localtime:ro -i -t mattdm/fedora /bin/bash

最初,/etc/localtime 是一个软链接,指向印度标准时间 /usr/share/zoneinfo/Asia/Kolkata。在容器内执行 date 命令,显示的时间与主机上相同。我退出了 shell 并停止了容器,使用命令 docker stop <container-id>

接下来,我删除了这个文件,并将其链接到测试目的地新加坡时区 /usr/share/zoneinfo/Singapore。主机时间已设置为新加坡时区。然后运行命令 docker start <container-id>。再次使用 nsenter 访问其 shell,发现时间现在已设置为新加坡时区。

docker start <container-id>
docker inspect -f {{.State.Pid}} <container-id>
nsenter -m -u -i -n -p -t <PID> /bin/bash

所以关键在于第一次运行容器时使用-v /etc/localtime:/etc/localtime:ro。我在这个链接上找到了它。 希望能对你有所帮助。

这个对我在 CentOS Linux 发行版 7.6.1810 上运行成功。 - k4cy

17

这个简单的解决方案修复了我们在WSL2中使用docker内核的时间同步问题。

在Windows中打开PowerShell,运行以下命令以重新同步时钟。

wsl -d docker-desktop -e /sbin/hwclock -s

您可以使用以下方式进行测试:

docker run -it alpine date

参考文献:https://github.com/docker/for-win/issues/10347#issuecomment-776580765


1
我正在使用带有WSL的Windows操作系统;这解决了我的运行容器中的时间问题,而且在容器运行时也是如此。 - b01
1
在Windows 11上,这个不起作用了,使用Docker Engine v20,使用Docker Compose v2。 - bovino Marcelo Bezerra

12

我在compose文件中有以下内容

volumes:
  - "/etc/timezone:/etc/timezone:ro"
  - "/etc/localtime:/etc/localtime:ro"

然后在 Gerrit Docker 中,其 replication_log 设置正确的时间戳后一切良好。


我在CentOS(7)主机上有Debian(9)容器,挂载本地时间可以正常工作,但时区无法正常工作,因为在主机上它是目录而在容器中它是文件。 - tometchy
在编程中,“:ro”是什么意思? - Aldo Inácio da Silva
1
:ro = 只读 - j3ffyang

12

docker-compose 表单:

volumes 属性中添加 /etc/localtime:/etc/localtime:ro

version: '3'

services:
  a-service:
      image: service-name
      container_name: container-name
      volumes:
        - /etc/localtime:/etc/localtime:ro

什么意思:ro? - Aldo Inácio da Silva
@AldoInáciodaSilva 表示只读。 - Benyamin Jafari

11

如果您正在使用docker-machine,虚拟机可能会漂移。要在不重启虚拟机的情况下更新虚拟机上的时钟,请运行:

docker-machine ssh <machine-name|default>
sudo ntpclient -s -h pool.ntp.org

这将使用NTP更新虚拟机上的时钟,然后启动的所有容器都将具有正确的日期。


命令已经生效并更新了时间,但时间又开始漂移,我又不得不再次运行命令。如何使它在Docker主机内自动同步? - chitti
对我来说,我需要重启docker-machine - docker-machine restart,然后运行eval "$(docker-machine env default)"以解决时间差的问题。 - Silas Palmer

10

我遇到了一个时间偏移量为-1小时4分钟的问题。

重新启动Docker解决了我的问题。

设置时区的方法如下:

  1. 通过ssh进入你的容器: docker exec -it my_website_name bash

  2. 运行dpkg-reconfigure tzdata

  3. 运行date

这个命令在我的macOS High Sierra 10.13.6 (17G65)上的控制台中使用docker-compose成功运行:docker-compose exec <servicename> bundle exec dpkg-reconfigure tzdata - Zack Morris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接