Les fuseaux horaires sont une source courante de confusion lors de la conteneurisation d'une application. Vos tâches cron s'exécuteront-elles au bon moment ? Les conteneurs Docker n'héritent pas du fuseau horaire de l'hôte, vous pouvez donc rencontrer des problèmes de planification inattendus qui perturbent votre application.
Voici la date
commande s'exécutant nativement sur un hôte Ubuntu 20.04 dans le fuseau horaire de l'heure d'été britannique :
Et voici la même commande dans un conteneur basé sur un ubuntu:20.04
non modifié image :
Le conteneur utilise le fuseau horaire UTC, créant une différence d'une heure entre les deux heures.
Comment fonctionnent les fuseaux horaires Linux ?
La plupart des distributions Linux utilisent le tzdata
package pour fournir des informations sur le fuseau horaire. Lorsque tzdata
est installé, vous pouvez inspecter le fuseau horaire actuel en lisant le /etc/timezone
fichier :
Vous aurez également un /etc/localtime
dossier. Il s'agit d'un lien symbolique vers la base de données de fuseaux horaires correcte pour l'emplacement sélectionné :
Si vous modifiez le fuseau horaire, utilisez dpkg-reconfigure tzdata
, le /etc/localtime
le lien symbolique est mis à jour pour pointer vers la nouvelle base de données. La sortie de commandes comme date
sera ajusté pour inclure le décalage du fuseau horaire actif.
Le problème des conteneurs
Le défi avec les conteneurs découle de la définition du fuseau horaire en premier lieu. Si vous repensez à la configuration de votre hôte, vous auriez dû définir le fuseau horaire dans le cadre de l'installation du système d'exploitation. Lorsque vous exécutez un nouveau conteneur, il démarre immédiatement, sans aucune étape "d'installation". Il n'est pas possible de sélectionner un fuseau horaire approprié.
Théoriquement, les runtimes de conteneurs pourraient offrir un héritage automatique du fuseau horaire de l'hôte. Cela ne se produit pas car cela pourrait entraîner des résultats inattendus lors du déploiement dans des environnements distants. Il serait facile d'oublier que votre planification cron fonctionne sur votre machine locale mais s'exécute de manière inattendue dans un cluster Kubernetes géré en utilisant l'heure UTC.
Les images de conteneurs sont livrées avec un fuseau horaire intégré à la place. Pour les images les plus populaires, ce sera UTC. De nombreuses images de base, en particulier les images minimales, n'incluront même pas le tzdata
emballer. Vous n'aurez pas de /etc/timezone
ou /etc/localtime
fichiers.
Ajouter des fuseaux horaires à vos conteneurs
La première partie de la définition du fuseau horaire approprié consiste à s'assurer que tzdata
est installé. Si votre image ne l'inclut pas, vous devrez ajouter manuellement le package dans le cadre de votre Dockerfile
.
FROM ubuntu:latest ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y tzdata
Lorsque tzdata
installe, vous obtenez généralement une invite interactive qui vous permet de sélectionner le fuseau horaire correct à partir d'un menu. Cela n'est pas utile lorsque vous créez par programme des conteneurs Docker. Définition du DEBIAN_FRONTEND
La variable d'environnement supprime l'invite et définit par défaut le fuseau horaire sur UTC.
Une fois que vous avez tzdata
dans votre image, vous êtes prêt à configurer le fuseau horaire correct pour votre application. L'approche la plus simple consiste à définir le TZ
variable d'environnement au fuseau horaire que vous souhaitez utiliser :
FROM ubuntu:latest ENV TZ=Europe/London ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y tzdata
Si vous préférez, vous pouvez définir le TZ
variable lorsque vous démarrez des conteneurs. Passez-le en tant que variable d'environnement à docker run
. Cela vous permet de remplacer le fuseau horaire par défaut d'une image, à condition qu'il inclue le tzdata
paquet.
docker run -e TZ=Europe/London -it ubuntu:latest
Une alternative aux variables d'environnement est le /etc/timezone
dossier. Vous pouvez écrire le fuseau horaire requis dans le cadre de votre Dockerfile
. Si vous utilisez cette méthode, vous devez reconfigurer tzdata
en utilisant votre gestionnaire de paquets. N'oubliez pas d'utiliser le mode non interactif ou vous recevrez à nouveau l'invite de fuseau horaire graphique.
FROM ubuntu:latest RUN echo "Europe/London" > /etc/timezone RUN dpkg-reconfigure -f noninteractive tzdata
Autres techniques
Si vous souhaitez garantir la synchronisation du fuseau horaire avec l'hôte, vous pouvez monter votre tzdata
local fichiers dans vos conteneurs. Vous aurez toujours besoin de tzdata
à l'intérieur du conteneur pour que cela fonctionne correctement.
docker run -v /etc/timezone:/etc/timezone -v /etc/localtime:/etc/localtime -it ubuntu:latest
Bien que Docker ne fournisse aucune prise en charge intégrée des fuseaux horaires, ce n'est pas le cas de tous les moteurs de conteneurs. Podman a un --tz
dédié drapeau qui vous permet de définir le fuseau horaire lors de la création d'un nouveau conteneur :
podman run --tz=Europe/London -it ubuntu:latest
Dans les coulisses, Podman montera un /etc/localtime
approprié fichier pour vous. Le fuseau horaire spécifié persistera pendant toute la durée de vie du conteneur.
Podman vous permet également de définir un fuseau horaire par défaut pour les conteneurs créés sans le --tz
drapeau. Créer ou modifier .config/containers/containers.conf
dans votre répertoire personnel. Ajouter un tz
réglage sur une nouvelle ligne dans le fichier :
# Used when no --tz flag is given tz = "Europe/London"
L'intégration native du fuseau horaire de Podman facilite le travail avec Docker. Comme la CLI de Podman est compatible avec Docker, il peut être intéressant d'envisager de changer si vous travaillez fréquemment avec des conteneurs dans différents fuseaux horaires.
Résumé
Les fuseaux horaires sont souvent négligés lors de la configuration des conteneurs Docker. La plupart des images de base utilisent par défaut l'heure UTC, ce qui peut prêter à confusion lorsque le fuseau horaire de l'hôte est différent.
En installant le tzdata
package, votre conteneur devient compatible avec tous les fuseaux horaires via le TZ
variable d'environnement, /etc/timezone
, et /etc/localtime
. Alternativement, vous pouvez synchroniser le fuseau horaire de votre hôte en montant les fichiers pertinents dans vos conteneurs.
Enfin, rappelez-vous que ces considérations s'appliquent également aux services Docker hébergés et aux clusters Kubernetes. Vos conteneurs utiliseront l'heure UTC, sauf indication contraire. Tant que vous pouvez définir des variables d'environnement, vous pourrez utiliser TZ
pour ajuster le fuseau horaire de vos charges de travail.