Come impostare l'ora di sistema in modo dinamico in un contenitore Docker


28

Esiste un modo per impostare un tempo del sistema di contenitori Docker in modo dinamico (in fase di esecuzione) senza influire sulla macchina host?

utilizzando

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

dà il seguente errore:

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.

utilizzando

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

dà il seguente errore:

date: cannot set date: Operation not permitted

Caso d'uso:

Devo testare un software sensibile al tempo (il comportamento dipende dalla data).

Altri casi d'uso comuni:

  • esecuzione di software legacy con bug y2k
  • software di test per la conformità anno 2038
  • debug di problemi relativi al tempo, come certificati SSL scaduti
  • esecuzione di software che cessa di funzionare al di fuori di un determinato periodo di tempo
  • processi di costruzione deterministici.

Quale sarebbe lo scopo di farlo? qual è il tuo caso d'uso?
Dawud,

Vedi modifica.
Vingtoft,


1
In realtà, ho appena trovato e testato positivamente una soluzione usando libfaketime github.com/wolfcw/libfaketime che aggiornerò con una risposta + esempio funzionante a breve.
Vingtoft,

Risposte:


21

È possibile

La soluzione è falsificarlo nel contenitore. Questa lib intercetta tutti i programmi di chiamata di sistema utilizzati per recuperare l'ora e la data correnti.

L'implementazione è semplice. Aggiungi funzionalità al tuo Dockerfile come appropriato:

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

Ricordarsi di impostare le variabili di ambiente LD_PRELOADprima di eseguire l'applicazione a cui si desidera applicare il tempo simulato.

Esempio:

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]

Ora puoi modificare dinamicamente l'ora dei server:

Esempio:

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

6
Per gli altri che arrivano a questa soluzione, tieni presente che questo non funzionerà per le applicazioni golang o altri ex collegati staticamente.
Sentinella

5
Grazie @Sentinel. Stranamente, ho appena trovato questa risposta tramite Google, in particolare voglio usarla con un'app Golang e ho notato che hai lasciato questo commento su una domanda di 1,5 anni appena 2 ore fa. Sembra che sia stato per me. Grazie! :)
dimonomid

Perché non funziona nella tua situazione? Golang non utilizza le chiamate di sistema per recuperare il tempo? @dimonomid Ti suggerisco di provarlo, è veloce implementare la soluzione.
Vingtoft,

1
@Vingtoft Fammi sapere se funziona davvero, ma cerca in giro. Golang non si collega dinamicamente alle librerie.
Sentinella

1
@dimonomid Sì, sono rimasto piuttosto deluso. Più deluso da Docker in realtà. Devo implementare test relativi al timing. Ciò rende Docker praticamente inutile come "contenitore". Avrei pensato che l'intercettazione delle chiamate orarie del sistema per la sincronizzazione del fuso orario sarebbe stata il punto 1 all'ordine del giorno di Docker. Apparentemente no.
Sentinella

4

Jenny D ha ragione in quanto, per impostazione predefinita, il contenitore Docker non consente l'accesso all'orologio di sistema.

Tuttavia, su Linux, se stai bene con il tuo container che ha accesso a questa funzionalità, puoi abilitare questa funzionalità usando l'opzione "--cap-add = SYS_TIME" del comando "docker run" durante la creazione del container:

# 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

Quindi, è possibile modificare l'ora dall'interno del contenitore in esecuzione:

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

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


2
Ciò modifica l'ora sul computer host. Il tempo su un sistema Linux non è attualmente spaziato in base al nome, c'è solo un valore per l'host e tutti i container.
BMitch,

Sì hai ragione. Ciò modifica l'ora dell'orologio della macchina host. Basta rileggere la domanda e realizzare la domanda, anzi, esplicitamente menzionata sul NON cambiare l'orologio della macchina host. Sono corretto :)
Oleg Kazakov,

0

Avviare il contenitore con una variabile d'ambiente aggiuntiva:

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

Sto cercando un modo per impostare l'ora in modo dinamico, il che significa che può essere impostato in fase di esecuzione. Ho aggiornato la mia domanda.
Vingtoft,

0

Docker-compose soluzione:

Aggiungere /etc/localtime:/etc/localtime:roal volumesattributo.

Guarda questo link per un esempio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.