Docker 与 Windows 时间不同步的问题及解决办法
最近突然发现 Windows 上的 Docker Container 时间滞后于 Windows 系统时间,这有时候会对 Container 造成不可预测的影响。因此在做了一番调研,解决方法记录如下。
出现原因
目前我的 Docker 容器内的时间为 Sun Jun 6 21:54:29 UTC 2021
,但是 Windows 系统时间为 2021年6月7日 15:05:10
,Docker Container 滞后了大约 9 个小时。这个问题出现的原因,简而言之就是使用了 Windows 系统的睡眠功能。当 Windows 从睡眠中醒来时,时间没有得到同步,于是 Docker Container 就滞后了睡眠所消耗的时间。
因此,要解决这个问题,我们就要让两边的时间同步。
解决方案
以下假设你的 Windows 系统装载了 PowerShell。强烈建议直接装 Windows Terminal 一步到位,在官方应用商店可以下载到。如果需要查看你的 Docker 引擎,可以进入 Docker Desktop 的设置页,看一下 Use the WSL 2 based engine
是否被勾选。
运行在 WSL2 之上的 Docker[1]
运行 WSL2 上的 Docker 很容易可以解决这个问题。关于该 bug 的讨论可以参考 GitHub[2]。解决该问题的方法非常简单,只需在 PowerShell 里运行:
1 | wsl --shutdown |
此时 Docker Desktop 会提示你 WSL2 后端已经被关闭,并问你是否需要重启。点击 restart 并等待一段时间即可修复问题。
运行在 Hyper-V 之上的 Docker[3]
这个版本的解决方案没有经过我的亲自实验(因为我的 Docker 基于 WSL2),仅供参考。
首先我们准备如下的.ps1
脚本:
1 | $vm = Get-VM -Name DockerDesktopVM |
保存该文件为 docker-time-sync.ps1
(或者你喜欢的其他名字)。通过管理员身份启动 PowerShell,定位到该文件的位置并运行它。
如果显示以下错误信息:
1 | 无法将“Get-VM”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。…… |
则需要你修改一下权限。首先运行 Get-ExecutionPolicy -List
查看一下当前的作用域,并通过 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
进行修改。修改完毕后再次尝试运行以上脚本。
根据 GitHub[4] 上的讨论,你也可以打开 Hyper-V 管理器程序,关闭并重新开启以下功能(未经翻译)即可解决:
1 | MobyLinuxVM > Settings > Integration Services > Time synchronization |