【问题标题】:Time in Docker container out of sync with host machineDocker 容器中的时间与主机不同步
【发布时间】:2020-03-31 20:23:24
【问题描述】:

我正在尝试通过我的SpringBoot 应用程序连接到CosmosDB。如果我使用SpringIntellij 运行应用程序,我就可以完成所有这些工作。但是,当我在 Docker 中运行应用程序时,我收到以下错误消息:

com.azure.data.cosmos.CosmosClientException: The authorization token is not valid at the current time.
Please create another token and retry
(token start time: Thu, 26 Mar 2020 04:32:10 GMT, 
token expiry time: Thu, 26 Mar 2020 04:47:10 GMT, current server time: Tue, 31 Mar 2020 20:12:42 GMT).

请注意,在上述错误消息中,current server time 是正确的,但其他时间晚了 5 天。

我觉得有趣的是我只在 docker 容器中收到过这个。

FROM {copy of zulu-jdk11}

ARG JAR_FILE

#.crt file in the same folder as your Dockerfile
ARG CERT="cosmos.cer"
ARG ALIAS="cosmos2"

#import cert into java
COPY $CERT /
RUN chmod +x /$CERT
WORKDIR $JAVA_HOME/lib/security
RUN keytool -importcert -file /$CERT -alias $ALIAS -cacerts -storepass changeit -noprompt

WORKDIR /
COPY /target/${JAR_FILE} app.jar
COPY run-java.sh /
RUN chmod +x /run-java.sh

ENV JAVA_OPTIONS "-Duser.timezone=UTC"
ENV JAVA_APP_JAR "/app.jar"

# run as non-root to mitigate some security risks
RUN addgroup -S pcc && adduser -S nonroot -G nonroot
USER nonroot:nonroot

ENTRYPOINT ["/run-java.sh"]

需要注意的是ENV JAVA_OPTIONS "-Duser.timezone=UTC",但删除它对我没有任何帮助

我基本上从 IntelliJ 运行相同的步骤,我对此没有任何问题,但在 docker 中,到期日期似乎晚了 5 天。

version: "3.7"
services:
  orchestration-agent:
    image: {image-name}
    ports:
      - "8080:8080"
    network_mode: host
    environment:
      - COSMOSDB_URI=https://host.docker.internal:8081/
      - COSMOSDB_KEY={key}
      - COSMOSDB_DATABASE={database}
      - COSMOSDB_POPULATEQUERYMETRICS=true
      - COSMOSDB_ITEMLEVELTTL=60

我认为还应该提到我将network_mode 更改为host。我还将 CosmosDB URI 从 https://localhost:8081 更改为 https://host.docker.internal:8081/

我还想提一下,我在以下人员的帮助下构建了 dockerfile

Importing self-signed cert into Docker's JRE cacert is not recognized by the service

How to add a SSL self-signed cert to Jenkins for LDAPS within Dockerfile?

【问题讨论】:

  • 感觉好像你的容器(图像)没有正确获取|更新时间。如果它有壳,你能docker run --interactive --tty {image-name} /bin/sh -c 'date'。如果您的客户在时间上依赖于图像并且图像时间不正确,这可以解释问题。我假设 CosmosDB 服务正在返回 current server time
  • @DazWilkin 我应该看到什么作为输出,我看到的错误和我通常做的一样
  • 由于我没有关闭我的工作计算机,它会在周末睡觉,当计算机进入睡眠状态时,它会使 docker 不同步。重启我的电脑解决了这个问题
  • 啊,抱歉,您可能需要调整入口点:docker run --interactive --tty --entrypoint=/bin/sh {image-name} date 以根据容器获取日期。显然,此日期时间与您的主机错误匹配。
  • @DazWilkin 我在您的解决方案中收到“/bin/sh: can't open 'date': No such file or directory”。我在窗户上

标签: docker


【解决方案1】:

Docker 容器不维护单独的时钟,它与 Linux 主机相同,因为时间不是命名空间值。这也是为什么 Docker 取消了更改容器内时间的权限的原因,因为这会影响主机和其他容器,从而破坏隔离模型。

但是,在 Docker Desktop 上,docker 在虚拟机内部运行(允许您在非 Linux 桌面上运行 Linux 容器),当笔记本电脑暂停时,该虚拟机的时间可能会不同步。目前正在 github 上的一个 issue 中对此进行跟踪,您可以关注该问题以查看进度:https://github.com/docker/for-win/issues/4526

可能的解决方案包括重新启动计算机、重新启动 docker 的 VM、将 NTP 作为特权容器运行,或使用以下 PowerShell 在 windows VM 中重置时间同步:

Get-VMIntegrationService -VMName DockerDesktopVM -Name "Time Synchronization" | Disable-VMIntegrationService
Get-VMIntegrationService -VMName DockerDesktopVM -Name "Time Synchronization" | Enable-VMIntegrationService

使用 WSL 2,重新启动 VM 涉及:

wsl --shutdown
wsl

【讨论】:

    【解决方案2】:

    WSL 2 time shift after sleep 最近存在一个已知问题,即 fixed in 5.10.16.3 WSL 2 Linux kernel,它仍然不包含在 Windows 10 版本 21H1 更新中,但 can be installed manually

    如何查看 WSL 内核版本:

    > wsl uname -r
    

    旧内核的临时解决方法有助于直到下一次睡眠:

    > wsl hwclock -s
    

    【讨论】:

      【解决方案3】:

      这是一个在 WSL2 上使用 Windows 上的 Docker Desktop 对我有用的替代方法:

      由于无法在 Docker 容器中设置日期,我只是在 WSL2 中打开 Ubuntu 并运行以下命令来同步时钟:

      sudo date -s "$(wget -qSO- --max-redirect=0 google.com 2>&1 | grep Date: | cut -d' ' -f5-8)Z"
      

      效果很好,所以我在根用户的 crontab 中添加了以下行:

      # Edit root user's crontab
      sudo crontab -e
      
      # Add the following line to run it every minute of every day:
      * * * * * sudo date -s "$(wget -qSO- --max-redirect=0 google.com 2>&1 | grep Date: | cut -d' ' -f5-8)Z"
      

      在那之后,我刚刚重新启动了我的 Docker 容器,并且日期是正确的,因为它们似乎使用了 WSL2 Ubuntu 日期。

      之前的日期(不正确):

      date
      Thu Feb  4 21:50:35 UTC 2021
      

      之后的日期(正确):

      date
      Fri Feb  5 19:01:05 UTC 2021
      

      【讨论】:

        猜你喜欢
        • 2017-04-26
        • 2014-05-13
        • 1970-01-01
        • 1970-01-01
        • 2018-12-08
        • 1970-01-01
        • 1970-01-01
        • 2015-11-11
        相关资源
        最近更新 更多