是否可以在docker容器中更改日期?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以在docker容器中更改日期?相关的知识,希望对你有一定的参考价值。
我有一个容器,在tomcat中有一个正在运行的程序。我只需要在此容器中更改日期并测试我的程序行为。我有时间敏感的逻辑,有时需要看看几天或几个月后会发生什么。在码头工具中有可能吗?我读到如果我在容器中更改日期,日期将在主机系统上更改。但对我来说这是一个坏主意。我需要在一台服务器上有一些这个应用程序的实例,并且有可能为每个实例设置不同的时间。
但是当我尝试更改容器内的日期时,我收到错误:
sudo date 04101812
date: cannot set date: Operation not permitted
Fri Apr 10 18:12:00 UTC 2015
很有可能动态更改Docker容器中的时间,而不会影响主机操作系统。
解决方案是伪造它。 This lib拦截所有系统调用程序用于检索当前时间和日期。
实施很容易。根据需要向Dockerfile添加功能:
WORKDIR /
RUN git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /libfaketime/src
RUN make install
请记住在运行要应用伪造时间的应用程序之前设置环境变量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]
您现在可以动态更改服务器时间:
例:
def set_time(request):
import os
import datetime
print(datetime.datetime.today())
os.environ["FAKETIME"] = "2020-01-01" # string must be "YYYY-MM-DD hh:mm:ss" or "+15d"
print(datetime.today())
这对Docker来说是不可能的。 Docker使用与外部内核相同的时钟。您需要的是完全虚拟化,它模拟完整的PC。
sudo
失败,因为它只会使你在容器内的虚拟环境的root
。这个用户与主机系统的真实root
无关(除了名称和UID),它不能做真正的root
可以做的事情。
在使用像Python或Java这样的高级语言时,您经常可以使用钩子来模拟测试的某个系统时间,或者编写包含“从系统获取当前时间”并返回测试所需内容的代码。
专门针对Java,使用joda-time。在那里,您可以使用DateTimeUtils.setCurrentMillis*()
注入自己的时间源。
这对我有用,也许你可以尝试一下:
dpkg-reconfigure tzdata
编辑:在您遇到问题的容器内执行它。将出现一个界面。在那里你可以编辑时区和本地时间,例如,并正确设置,解决了我的问题,这与你的问题相同。
祝好运!
对我来说,我实际上需要设置测试的实际日期。我发现以下选项适用于Mac,但您必须意识到您将更改所有容器的日期,因为您正在更改Docker用于其所有容器的基础Alpine VM的日期。
选项1:更改主机的日期并重新启动docker
在以下时间使用此
- 你可以重启docker。
- 您可以更改主机的日期
脚步:
- 停止你的容器。
- 通过日期和时间首选项更改机器的日期
- 重启docker。
- 启动你的容器。
再次运行此序列以返回正确的日期和时间。
选项2:更改Alpine VM的日期
在以下时间使用此
- 你无法重启docker。
- 您无法设置主机的日期
脚步:
screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
屏幕开始空白,点击输入几次。date -s [hh:mm]
所有的docker容器现在都有你的新时间。您还可以使用其他格式,查找“busybox date”上的文档,因为它与其他日期实现不完全相同。- 退出命中
control-a :
并输入d
这将分离屏幕会话,但保持tty运行。
要重置时间:
screen -r
这将恢复你的tty。ntpd -q
这使用了/etc/ntp.conf中定义的服务器(这看起来像是回到主机时钟的魔桥)- 退出命中
control-a :
并输入quit
这将终止您的屏幕和tty会话。
我创建了一个包含libfaketime的Docker镜像,用于Alpine,但该过程可以在其他发行版中完成。
下面是使用Groovy作为示例使用Java的示例。但也可以使用Tomcat。
FROM groovy:alpine
COPY --from=trajano/alpine-libfaketime /faketime.so /lib/faketime.so
ENV LD_PRELOAD=/lib/faketime.so
DONT_FAKE_MONOTONIC=1
然后在执行docker运行时构建并传递FAKETIME
环境变量
docker build -f fakedemo-java.Dockerfile . -t fakedemo
docker run --rm -e FAKETIME=+15d fakedemo groovy -e "print new Date();"
来源位于https://github.com/trajano/alpine-libfaketime,码头图像位于https://hub.docker.com/r/trajano/alpine-libfaketime
我还基于Ubuntu https://github.com/trajano/ubuntu-faketime创建了它的变体
是的,我测试了它,它的工作!
破坏图像时使用--privileged
例:
docker run -i -t --rm --privileged my_image /bin/bash
以上是关于是否可以在docker容器中更改日期?的主要内容,如果未能解决你的问题,请参考以下文章
监听更改并在代码更改时重新加载容器 - docker-compose
为啥使用 Docker 容器的 NextJS 在更改开发环境的代码后没有重新加载?