tomcat 是否可以更改Docker容器中的日期?

6rqinv9w  于 2022-11-13  发布在  Docker
关注(0)|答案(8)|浏览(180)

我有一个容器,里面有一个正在运行的程序在tomcat里面。我只需要在这个容器中更改日期,并测试我的程序行为。我有时间敏感的逻辑,有时需要看看几天或几个月后会发生什么。这在docker中可能吗?我读到如果我在容器中更改日期,日期将在主机系统上更改。但这对我来说是个坏主意。我需要在一个服务器上有这个应用程序的几个示例,并有可能为每个示例设置不同的时间。
但是,当我尝试更改容器内的日期时,出现错误:

sudo date 04101812
date: cannot set date: Operation not permitted
Fri Apr 10 18:12:00 UTC 2015
zkure5ic

zkure5ic1#

在不影响主机操作系统的情况下,动态更改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())
4bbkushb

4bbkushb2#

这在Docker上是不可能的。Docker使用与外部内核相同的时钟。你需要的是完全虚拟化,模拟一个完整的PC。
sudo失败是因为它只让您在容器内的虚拟环境中使用root。此用户与主机系统的真实的root没有关系(除了名称和UID),并且它不能执行真实root所能执行的操作。
如果你使用像Python或Java这样的高级语言,你经常会有钩子,你可以在那里模拟特定的系统时间进行测试,或者你可以编写代码, Package “从系统中获取当前时间”并返回你的测试所需的内容。
特别是对于Java,使用joda-time,在那里你可以使用DateTimeUtils.setCurrentMillis*()注入你自己的时间源。

pu82cl6c

pu82cl6c3#

我创建了一个包含libfaketime的Docker映像,用于Alpine,但该过程可以在其他发行版中完成。
这里有一个使用它的例子,Java使用Groovy作为例子,但是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();"

源代码的格式为trajano / alpine-libfaketime | Github,Docker映像的格式为trajano/alpine-libfaketime | dockerhub
我还创建了一个基于Ubuntu的变体:trajano / ubuntu-faketime | Github

axr492tv

axr492tv4#

这对我很有效,也许你可以试试:
dpkg-重新配置tzdata
编辑:在你有问题的容器中执行它。一个界面会出现。在那里你可以编辑时区和本地时间,并正确地设置它,这修复了我的问题,这和你的一样。
祝你好运!

rkttyhzu

rkttyhzu5#

对我来说,我实际上需要设置测试的实际日期。我发现以下选项在Mac上有效,但您必须意识到,您将更改所有容器的日期,因为您将更改Docker用于其所有容器的底层Alpine VM的日期。

选项1:更改主机日期并重新启动Docker

在以下情况下使用此选项:

  • 你可以重新启动Docker。
  • 您可以更改主机的日期

操作步骤:
1.停下你们的集装箱。
1.通过日期和时间首选项更改机器的日期
1.重启Docker。
1.启动容器。
再次运行此序列以返回到正确的日期和时间。

选项2:更改Alpine VM的日期

在以下情况下使用此选项:

  • 无法重新启动Docker。
  • 您不能设置主机日期

操作步骤:

  • screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
  • 屏幕一开始是空白的,按几次Enter键。
  • date -s [hh:mm]
  • 你所有的docker容器现在都有了新的时间。你也可以使用其他格式,查找关于“busybox date”的文档,因为它和其他的 date 实现不太一样。
  • 要退出,请单击control-a :并键入d
  • 这将分离屏幕会话,但tty仍在运行。

要重置时间:

  • screen -r
  • 这将恢复您的TTY。
  • ntpd -q
  • 这使用了/etc/ntp.conf中定义的服务器(这看起来像是回到主机时钟的魔法桥)
  • 要退出,请单击control-a :并键入quit
  • 这将终止您的屏幕和tty会话。
epfja78i

epfja78i6#

docker exec -it [Container Id] /bin/bash(执行到容器中)
rm /etc/localtime(请参阅时区)
ln -s /usr/share/zoneinfo/Asia/Karachi /etc/localtime(设置新时区)

d8tt03nd

d8tt03nd7#

我的解决方案:我通过vagrant在virtualbox虚拟机上运行Docker。

这并不像听起来那么复杂。下面的Vagrantfile在机器启动之前将虚拟机的日期时间重置为一个特定的日期时间。相应的docker-compose配置程序负责自动运行docker-compose.yml
流浪者档案:

Vagrant.configure("2") do |config|
  config.vm.define "ubuntuvm" do |ubuntuvm|
    config.vm.box = "ubuntu/focal64"
    config.vm.provision :docker

    ubuntuvm.trigger.before :up do |trigger|
      trigger.info = "changing time"
      trigger.ruby do |env,machine|
        require 'time'
        machineTime = "2022/07/02 00:20:00"
        offset = DateTime.parse(machineTime).strftime("%Q").to_i - DateTime.now.strftime("%Q").to_i
        puts "Updating machine time to: #{machineTime} by shifting biossystemtime #{offset} ms"
        puts `VBoxManage setextradata #{machine.id} "VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled" 1`
        puts `VBoxManage modifyvm #{machine.id} --biossystemtimeoffset #{offset}`
      end
    end
  end

  config.vm.hostname = "ubuntuvm"
  # config.vm.network "forwarded_port", guest: 80 host: 8080
  # config.vm.synched_folter "../data"", "/vagrant_data"

  config.vm.provider "virtualbox" do |vb|
      # vb.memory = "1024"
  end
  config.vm.provision :docker_compose, yml: "/vagrant/docker-compose.yml", rebuild: true, run: "always"
end

然后我只需要执行以下操作

# start the machine and run the docker-compose
vagrant up

每次启动机器时,我都会看到以下消息:

ubuntuvm: Updating machine time to: 2022/07/02 00:20:00 by shifting biossystemtime -212710744 ms
ubuntuvm: Running docker-compose up...

其他命令:

# get inside the machine with ssh to check its time and also check the container's time (docker commands already exist inside there due to the provisioner).
vagrant ssh ubuntuvm
# stop the machine
vagrant halt
# destroy the machine
vagrant destroy

先决条件

已知问题:

仅在第一次运行时,vagrant up将无法更新时间,因为由于某种原因,before-up触发器甚至在创建机器之前就已执行。在所有其他执行中,机器已经在那里,因此时间将按预期重置。

vof42yt1

vof42yt18#

我有同样的问题与我的jenkins docker示例以下步骤修复了我的问题
1.执行到容器中

扩充程式执行-it 9d 41 c699 a8 f4/bin/bash

1.请参阅时区**cat /etc/timezone**:输出Etc/UTC
1.设置新时区,使用nano:亚洲/科隆博(此处显示您的时区)
1.重新启动容器

相关问题