如何在 Docker 容器中动态设置系统时间

Vin*_*oft 37 time docker

有没有办法在不影响主机的情况下动态(在运行时)设置 Docker 容器系统时间?

使用

hwclock --set --date "Sat Aug 17 08:31:24 PDT 2016"
Run Code Online (Sandbox Code Playgroud)

给出以下错误:

hwclock: Cannot access the Hardware Clock via any known method.
hwclock: Use the --debug option to see the details of our search for an access method.
Run Code Online (Sandbox Code Playgroud)

使用

date -s "2 OCT 2006 18:00:00"
Run Code Online (Sandbox Code Playgroud)

给出以下错误:

date: cannot set date: Operation not permitted
Run Code Online (Sandbox Code Playgroud)

用例:

我需要测试对时间敏感的软件(行为取决于日期)。

其他常见用例:

  • 运行带有 y2k 错误的遗留软件
  • 2038 年合规性测试软件
  • 调试与时间相关的问题,例如过期的 SSL 证书
  • 运行在特定时间范围外停止运行的软件
  • 确定性的构建过程。

Vin*_*oft 30

有可能的

解决方案是在容器中伪造它。该库拦截所有用于检索当前时间和日期的系统调用程序。

实施很容易。根据需要向 Dockerfile 添加功能:

WORKDIR /
RUN git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /libfaketime/src
RUN make install
Run Code Online (Sandbox Code Playgroud)

请记住LD_PRELOAD在运行要应用伪造时间的应用程序之前设置环境变量。

例子:

CMD ["/bin/sh", "-c", "LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME_NO_CACHE=1 python /srv/intercept/manage.py runserver 0.0.0.0:3000]
Run Code Online (Sandbox Code Playgroud)

您现在可以动态更改服务器时间:

例子:

import os
def set_time(request):
    print(datetime.today())
    os.environ["FAKETIME"] = "2020-01-01"  # Note: time of type string must be in the format "YYYY-MM-DD hh:mm:ss" or "+15d"
    print(datetime.today())
Run Code Online (Sandbox Code Playgroud)

  • 对于使用此解决方案的其他人,请注意这不适用于 golang 应用程序或其他静态链接的 exe。 (7认同)
  • 谢谢@哨兵。有趣的是,我刚刚通过 google 找到了这个答案,我特别想将它与 golang 应用程序一起使用,我注意到您在 2 小时前就一个 1.5 年前的问题留下了这条评论。感觉就像是给我的。谢谢!:) (7认同)