Frage So legen Sie die Systemzeit dynamisch in einem Docker-Container fest


Gibt es eine Möglichkeit, ein Dockercontainer-System dynamisch (zur Laufzeit) zu setzen, ohne den Hostcomputer zu beeinträchtigen?

Verwenden

hwclock --set --date "Sat Aug 17 08:31:24 PDT 2016"

gibt folgenden Fehler:

hwclock: Cannot access the Hardware Clock via any known method.
hwclock: Use the --debug option to see the details of our search for an access method.

Verwenden

date -s "2 OCT 2006 18:00:00"

gibt folgenden Fehler:

date: cannot set date: Operation not permitted

Anwendungsfall:

Ich muss zeitsensible Software testen (Verhalten hängt vom Datum ab).

Andere häufige Anwendungsfälle:

  • Legacy-Software mit y2k Bugs laufen
  • Testsoftware für die Konformität mit dem Jahr 2038
  • zeitbezogene Probleme wie abgelaufene SSL-Zertifikate beheben
  • Ausführen von Software, die außerhalb eines bestimmten Zeitraums nicht mehr läuft
  • deterministische Build-Prozesse.

21
2018-01-06 12:48


Ursprung


Was wäre der Zweck, dies zu tun? Was ist dein Anwendungsfall? - dawud
Bitte siehe Bearbeiten. - Vingtoft
stackoverflow.com/questions/29556879/... - dawud
Tatsächlich habe ich gerade eine Lösung gefunden und positiv getestet, die libfaketime verwendet github.com/wolfcw/libfaktime Ich werde in Kürze mit einer Antwort + Arbeitsbeispiel aktualisieren. - Vingtoft


Antworten:


Es ist möglich

Die Lösung ist, es in den Container zu fälschen. Diese Bibliothek fängt alle Systemaufrufprogramme ab, die verwendet werden, um die aktuelle Uhrzeit und das aktuelle Datum abzurufen.

Die Implementierung ist einfach. Fügen Sie Ihrer Dockerdatei nach Bedarf Funktionen hinzu:

WORKDIR /
RUN git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /libfaketime/src
RUN make install

Denken Sie daran, die Umgebungsvariablen festzulegen LD_PRELOAD bevor Sie die Anwendung ausführen, auf die die gefälschte Zeit angewendet werden soll.

Beispiel:

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]

Sie können die Serverzeit jetzt dynamisch ändern:

Beispiel:

import os
def set_time(request):
    print(datetime.today())
    os.environ["FAKETIME"] = "2020-01-01"  # Note: time of type string must be in the format "YYYY-MM-DD hh:mm:ss" or "+15d"
    print(datetime.today())

15
2018-01-09 12:48



Für andere, die zu dieser Lösung kommen, beachten Sie, dass dies nicht für Golang-Anwendungen oder andere statisch verknüpfte Exes funktioniert. - Sentinel
Danke @Sentinel. Lustigerweise habe ich diese Antwort nur über Google gefunden, ich möchte sie speziell mit einer Golang-App verwenden, und mir ist aufgefallen, dass du diesen Kommentar vor zwei Stunden auf eine 1,5 Jahre alte Frage hinterlassen hast. Fühlt sich an wie es für mich war. Vielen Dank! :) - dimonomid
Warum funktioniert das nicht in deiner Situation? Verwendet Golang keine Systemaufrufe zum Abrufen der Uhrzeit? @dimonomid Ich schlage vor, Sie versuchen es, es ist schnell, die Lösung zu implementieren. - Vingtoft
@Vingtoft Lassen Sie mich wissen, ob es tatsächlich funktioniert, aber suchen Sie sich um. Golang verbindet sich nicht dynamisch in den Bibliotheken. - Sentinel
@dimonomid Ja, ich war ziemlich enttäuscht. Mehr enttäuscht von Docker eigentlich. Ich muss zeitbezogene Tests implementieren. Dies macht Docker als "Container" ziemlich nutzlos. Ich hätte gedacht, dass das Abfangen von Systemzeitanrufen für die Zeitzonensynchronisierung Punkt 1 der Docker-Agenda wäre. Scheinbar nicht. - Sentinel


Jenny D ist insofern korrekt, als der Docker-Container standardmäßig keinen Zugriff auf die Systemuhr erlaubt.

Wenn Sie jedoch unter Linux mit Ihrem Container auf diese Funktion zugreifen können, können Sie diese Funktion mit der Option "--cap-add = SYS_TIME" des Befehls "docker run" zulassen, wenn Sie einen Container erstellen:

# docker run --cap-add=SYS_TIME -d --name teamcity-server-instance -v /opt/teamcity/data:/data/teamcity_server/datadir -v /opt/teamcity/logs:/opt/teamcity/logs -p 80:8111 jetbrains/teamcity-server

Dann können Sie die Zeit innerhalb des aktiven Containers ändern:

# docker exec -it teamcity-server-instance /bin/bash
# date +%T -s "15:03:00"
15:03:00
#

Referenzdokumentation: https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities


1
2018-02-26 04:18



Dies ändert die Zeit auf dem Hostcomputer. Die Zeit auf einem Linux-System ist derzeit nicht im Namespace, es gibt nur einen Wert für den Host und alle Container. - BMitch
Ja, du hast Recht. Dies ändert die Uhrzeit der Host-Maschinenuhr. Lies einfach die Frage erneut und realisierte die Frage, die ausdrücklich erwähnt wurde, dass die Uhr des Host-Rechners NICHT geändert werden sollte. Ich stehe korrigiert :) - Oleg Kazakov


Starten Sie den Container mit einer zusätzlichen Umgebungsvariablen:

docker run -e "SET_CONTAINER_TIMEZONE=true" \
           -e "CONTAINER_TIMEZONE=US/Arizona" [docker image name]

0
2018-01-06 12:57



Ich suche nach einer Möglichkeit, die Zeit dynamisch einzustellen, dh sie kann zur Laufzeit gesetzt werden. Ich habe meine Frage aktualisiert. - Vingtoft


docker-komponieren Lösung:

Hinzufügen /etc/localtime:/etc/localtime:ro zum volumes Attribut.

Schau dir das an Verknüpfung zum Beispiel.


0
2017-08-21 05:53