Comment gérer les fuseaux horaires dans les conteneurs Docker

0
477

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 font des ravages dans votre application.

Voici la commande date s'exécutant en natif 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 une image ubuntu:20.04 non modifiée :

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 package tzdata pour fournir des informations sur le fuseau horaire. Lorsque tzdata est installé, vous pouvez inspecter le fuseau horaire actuel en lisant le fichier /etc/timezone :

Publicité

Vous aurez également un fichier /etc/localtime. Ceci est un lien symbolique vers la base de données de fuseau horaire correcte pour l'emplacement sélectionné :

Si vous modifiez le fuseau horaire à l'aide de dpkg-reconfigure tzdata, le lien symbolique /etc/localtime est mis à jour pour pointer vers la nouvelle base de données. La sortie des commandes comme la date sera ajustée pour inclure le décalage du fuseau horaire actif.

Le problème avec les 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 “installation” étape. Il n'est pas possible de sélectionner un fuseau horaire approprié.

Théoriquement, les environnements d'exécution de conteneur pourraient offrir un héritage automatique du fuseau horaire de l'hôte. Cela ne se produit pas car cela peut 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é à l'aide de 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 package tzdata. Vous n'aurez pas de fichiers /etc/timezone ou /etc/localtime.

Ajout de 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:dernier ENV DEBIAN_FRONTEND=exécution non interactive apt-get update && apt-get install -y tzdata Advertisement

Lorsque tzdata s'installe, vous obtenez généralement une invite interactive qui vous permet de sélectionner le fuseau horaire correct dans un menu. Cela n'est pas utile lorsque vous créez des conteneurs Docker par programmation. La définition de la variable d'environnement DEBIAN_FRONTEND supprime l'invite et définit le fuseau horaire par défaut 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 la variable d'environnement TZ sur le 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 la variable TZ lorsque vous démarrez les conteneurs. Transmettez-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 package tzdata.

docker run -e TZ=Europe/London -it ubuntu:latest

Une alternative aux variables d'environnement est le fichier /etc/timezone. Vous pouvez écrire le fuseau horaire requis dans votre Dockerfile. Si vous utilisez cette méthode, vous devez reconfigurer tzdata à l'aide de votre gestionnaire de packages. 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 tzdata non interactif

Autres techniques

Si vous souhaitez garantir la synchronisation du fuseau horaire avec l'hôte, vous pouvez monter vos fichiers tzdata locaux dans vos conteneurs. Vous aurez toujours besoin de tzdata dans le 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 indicateur –tz dédié 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 Advertisement

En coulisse, Podman montera un fichier /etc/localtime approprié 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 l'indicateur –tz. Créez ou modifiez .config/containers/containers.conf dans votre répertoire personnel. Ajoutez un paramètre tz sur une nouvelle ligne du fichier :

# Utilisé lorsqu'aucun indicateur –tz n'est donné tz = “Europe/London”

L'intégration de fuseau horaire natif de Podman facilite le travail avec Docker. Comme la CLI de Podman est compatible avec celle de Docker, il peut être intéressant d'envisager le changement si vous travaillez fréquemment avec des conteneurs dans des fuseaux horaires différents.

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 package tzdata, votre conteneur gagne en compatibilité avec tous les fuseaux horaires via la variable d'environnement TZ,/etc/timezone et /etc/localtime. Vous pouvez également synchroniser le fuseau horaire de votre hôte en montant les fichiers pertinents dans vos conteneurs.

Enfin, n'oubliez pas 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.