Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Time in Docker container out of sync with host machine

Tags:

docker

I'm trying to connect to CosmosDB through my SpringBoot app. I have all of this working if I run the app with Spring or via Intellij. But, when I run the app in Docker I get the following error message:

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).

Note that in the above error message the current server time is correct but the other times are 5 days behind.

What I find interesting is that I only ever receive this in the docker container.

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"]

One thing to note is ENV JAVA_OPTIONS "-Duser.timezone=UTC" but removing this didn't help me at all

I basically run the same step from IntelliJ and I have no issues with it but in docker the expiry date seems to be 5 days behind.

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

I think it should also be mentioned that I changed the network_mode to host. And I also changed the CosmosDB URI from https://localhost:8081 to https://host.docker.internal:8081/

I would also like to mention that I built my dockerfile with the help of:

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?

like image 283
Archmede Avatar asked Jan 01 '23 05:01

Archmede


1 Answers

Docker containers don't maintain a separate clock, it's identical to the Linux host since time is not a namespaced value. This is also why Docker removes the permission to change the time inside the container, since that would impact the host and other containers, breaking the isolation model.

However, on Docker Desktop, docker runs inside of a VM (allowing you to run Linux containers on non-Linux desktops), and that VM's time can get out of sync when the laptop is suspended. This is currently being tracked in an issue over on github which you can follow to see the progress: https://github.com/docker/for-win/issues/4526

Potential solutions include restarting your computer, restarting docker's VM, running NTP as a privileged container, or resetting the time sync in the windows VM with the following PowerShell:

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

With WSL 2, restarting the VM involves:

wsl --shutdown
wsl
like image 133
BMitch Avatar answered Jan 19 '23 11:01

BMitch