Ik heb een container met een draaiend programma in Tomcat. Ik hoef alleen de datum in deze container te wijzigen en mijn programmagedrag te testen. Ik heb tijdgevoelige logica en moet soms zien wat er een paar dagen of maanden later gebeurt.
Is het mogelijk in Docker? Ik heb gelezen dat als ik de datum in de container verander, de datum op het hostsysteem wordt gewijzigd. Maar het is een slecht idee voor mij. Ik moet een paar instanties van deze applicatie op één server hebben en de mogelijkheid hebben om voor elke instantie een andere tijd in te stellen.
Maar als ik de datum in de container probeer te wijzigen, krijg ik de foutmelding:
sudo date 04101812
date: cannot set date: Operation not permitted
Fri Apr 10 18:12:00 UTC 2015
Antwoord 1, autoriteit 100%
Het is heel goed mogelijk om de tijd in een Docker-container dynamisch te wijzigen, zonder het host-besturingssysteem te beïnvloeden.
De oplossing is om het te vervalsen. Deze libonderschept alle systeemaanroepprogramma’s die worden gebruikt om de huidige tijd en datum op te halen.
De implementatie is eenvoudig. Voeg zo nodig functionaliteit toe aan uw Dockerfile:
WORKDIR /
RUN git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /libfaketime/src
RUN make install
Vergeet niet om de omgevingsvariabelen LD_PRELOAD
in te stellen voordat u de toepassing uitvoert waarop u de vervalste tijd wilt toepassen.
Voorbeeld:
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]
U kunt de servertijd nu dynamisch wijzigen:
Voorbeeld:
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())
Antwoord 2, autoriteit 33%
Dat is niet mogelijk met Docker. Docker gebruikt dezelfde klok als de buitenste kernel. Wat je nodig hebt is volledige virtualisatie die een complete pc emuleert.
De sudo
mislukt omdat het je alleen root
maakt van de virtuele omgeving in de container. Deze gebruiker is niet gerelateerd aan de echte root
van het hostsysteem (behalve op naam en UID) en kan niet doen wat de echte root
zou kunnen doen.
Als je een taal op hoog niveau gebruikt, zoals Python of Java, heb je vaak hooks waar je een bepaalde systeemtijd voor tests kunt simuleren of je kunt code schrijven die “haal de huidige tijd van het systeem” omhult en teruggeeft wat je test vereist.
Gebruik specifiek voor Java joda-time. Daar kunt u uw eigen tijdbron injecteren met behulp van DateTimeUtils.setCurrentMillis*()
.
Antwoord 3, autoriteit 18%
Dit werkte voor mij, misschien kun je het proberen:
dpkg-reconfigure tzdata
Bewerken: voer het uit in de container waar je problemen mee hebt. Er verschijnt een interface. Daar kun je bijvoorbeeld de tijdzone en lokale tijd bewerken en correct instellen, dat loste mijn probleem op, dat was hetzelfde als het jouwe.
Veel succes!
Antwoord 4, autoriteit 12%
Ik heb een Docker-image gemaakt met libfaketime voor gebruik met Alpine, maar het proces kan in andere distributies worden gedaan.
Hier is een voorbeeld van het gebruik van Java met Groovy als voorbeeld. Maar Tomcat kan ook worden gebruikt.
FROM groovy:alpine
COPY --from=trajano/alpine-libfaketime /faketime.so /lib/faketime.so
ENV LD_PRELOAD=/lib/faketime.so \
DONT_FAKE_MONOTONIC=1
Bouw vervolgens de omgevingsvariabele FAKETIME
en geef deze door wanneer u bijvoorbeeld een docker-run uitvoert
docker build -f fakedemo-java.Dockerfile . -t fakedemo
docker run --rm -e FAKETIME=+15d fakedemo groovy -e "print new Date();"
Bron is in trajano
/
alpine-libfaketime | Githuben de docker-afbeelding staan in trajano/alpine-libfaketime | dockerhub
Ik heb er ook een variant van gemaakt op basis van Ubuntu: trajano
/
ubuntu-neptime | Github
Antwoord 5, autoriteit 9%
Voor mij moest ik de daadwerkelijke testdatum instellen. Ik heb geconstateerd dat de volgende opties werken op Mac, maar u moet zich realiseren dat u de datum voor al uw containers gaat wijzigen, omdat u de datum wijzigt van de onderliggende Alpine VM die Docker voor al zijn containers gebruikt.
OPTIE 1: Wijzig de datum van uw hostmachine & herstart docker
Gebruik dit wanneer:
- Je kunt docker opnieuw starten.
- U kunt de datum van uw hostmachine wijzigen
Stappen:
- Stop je containers.
- Wijzig de datum van uw machine via de Datum & Tijdvoorkeuren
- Herstart docker.
- Start je containers.
Voer deze reeks opnieuw uit om terug te gaan naar de juiste datum & tijd.
OPTIE 2: Wijzig de datum van de Alpine VM
Gebruik dit wanneer:
- Je kunt docker niet herstarten.
- U kunt de datum van uw hostcomputer niet instellen
Stappen:
screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
- Het scherm begint leeg, druk een paar keer op enter.
date -s [hh:mm]
- Al je docker-containers hebben nu je nieuwe tijd. Jij kan
gebruik ook andere formaten, zoek naar documentatie over “busybox date” als
het is niet helemaal hetzelfde als andere dateimplementaties.
- Al je docker-containers hebben nu je nieuwe tijd. Jij kan
- Om af te sluiten drukt u op
control-a :
en typt ud
- Hiermee wordt de schermsessie losgekoppeld, maar blijft de tty actief.
Om de tijd opnieuw in te stellen:
screen -r
- Hiermee wordt je tty hervat.
ntpd -q
- Dit gebruikt de server die is gedefinieerd in /etc/ntp.conf (dit ziet eruit als een magische brug terug naar de hostklok)
- Om af te sluiten druk je op
control-a :
en typ jequit
- Hiermee worden uw scherm- en tty-sessie beëindigd.
Antwoord 6
docker exec -it [Container Id] /bin/bash
(exec in container)
rm /etc/localtime
(zie tijdzone)
ln -s /usr/share/zoneinfo/Asia/Karachi /etc/localtime
(nieuwe tijdzone instellen)
Antwoord 7
Ik had hetzelfde probleem met mijn jenkins docker-instantie. De volgende stappen hebben mijn probleem opgelost
-
exec in container
docker exec -it 9d41c699a8f4 /bin/bash
-
Zie tijdzone
cat /etc/timezone
: uitvoer enz./UTC -
stel nieuwe tijdzone in, met nano: Azië/Colombo (uw tijdzone hier)
-
Start de container opnieuw