web-dev-qa-db-fra.com

Comment définir l'heure système dynamiquement dans un conteneur Docker

Existe-t-il un moyen de définir l'heure système d'un conteneur Docker de manière dynamique (au moment de l'exécution) sans affecter la machine hôte?

En utilisant

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

donne l'erreur suivante:

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.

En utilisant

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

donne l'erreur suivante:

date: cannot set date: Operation not permitted

Cas d'utilisation:

J'ai besoin de tester un logiciel sensible au temps (le comportement dépend de la date).

Autres cas d'utilisation courants:

  • exécution d'un logiciel hérité avec des bogues y2k
  • test des logiciels pour la conformité à l'année 2038
  • débogage des problèmes liés au temps, tels que les certificats SSL expirés
  • exécuter un logiciel qui cesse de fonctionner en dehors d'un certain délai
  • processus de construction déterministes.
32
Vingtoft

C'est possible

La solution est de le truquer dans le récipient. Cette lib intercepte tous les programmes d'appels système utilisés pour récupérer l'heure et la date actuelles.

La mise en œuvre est simple. Ajoutez des fonctionnalités à votre Dockerfile, le cas échéant:

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

N'oubliez pas de définir les variables d'environnement LD_PRELOAD avant d'exécuter l'application à laquelle vous souhaitez appliquer le temps factice.

Exemple:

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]

Vous pouvez maintenant modifier dynamiquement l'heure des serveurs:

Exemple:

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

Jenny D a raison, car par défaut, le conteneur Docker ne permet pas d'accéder à l'horloge système.

Cependant, sous Linux, si votre conteneur a accès à cette capacité, vous pouvez autoriser cette capacité en utilisant l'option "--cap-add = SYS_TIME" de la commande "docker run" lors de la création de votre conteneur:

# 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

Ensuite, vous pouvez modifier l'heure depuis l'intérieur du conteneur en cours d'exécution:

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

Documentation de référence: https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities

5
Oleg Kazakov

solution docker-compose:

Ajouter /etc/localtime:/etc/localtime:ro à l'attribut volumes.

Regardez ceci lien pour un exemple.

0
Benyamin Jafari

Démarrez le conteneur avec une variable d'environnement supplémentaire:

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