Zeitzonen sind eine häufige Ursache für Verwirrung bei der Containerisierung einer Anwendung. Werden Ihre Cron-Tasks zur richtigen Zeit ausgeführt? Docker-Container erben nicht die Zeitzone des Hosts, sodass Sie auf unerwartete Planungsprobleme stoßen können, die Ihre Anwendung verwüsten.
Hier ist das date
Befehl, der nativ auf einem Ubuntu 20.04-Host in der Zeitzone British Summer Time ausgeführt wird:
Und hier ist derselbe Befehl in einem Container, der auf einem unveränderten ubuntu:20.04
basiert Bild:
Der Container verwendet die UTC-Zeitzone, wodurch ein Unterschied von einer Stunde zwischen den beiden Zeiten entsteht.
Wie funktionieren Linux-Zeitzonen?
Die meisten Linux-Distributionen verwenden tzdata
Paket, um Zeitzoneninformationen bereitzustellen. Wenn tzdata
installiert ist, können Sie die aktuelle Zeitzone überprüfen, indem Sie /etc/timezone
lesen Datei:
Sie haben auch eine /etc/localtime
Datei. Dies ist ein symbolischer Link zur richtigen Zeitzonendatenbank für den ausgewählten Standort:
Wenn Sie die Zeitzone ändern, verwenden Sie dpkg-reconfigure tzdata
, die /etc/localtime
Symlink wird aktualisiert, um auf die neue Datenbank zu verweisen. Die Ausgabe von Befehlen wie date
wird angepasst, um den Offset der aktiven Zeitzone einzubeziehen.
Das Problem mit Containern
Die Herausforderung bei Containern ergibt sich in erster Linie aus der Einstellung der Zeitzone. Wenn Sie zurückdenken, als Sie Ihren Host eingerichtet haben, hätten Sie die Zeitzone als Teil der Betriebssysteminstallation einstellen müssen. Wenn Sie einen neuen Container ausführen, startet er jedoch sofort, ohne „Installations“-Phase. Es gibt keine Möglichkeit, eine geeignete Zeitzone auszuwählen.
Theoretisch könnten Containerlaufzeiten eine automatische Vererbung der Zeitzone des Hosts anbieten. Dies geschieht nicht, da es bei der Bereitstellung in Remoteumgebungen zu unerwarteten Ergebnissen führen kann. Es wäre leicht zu übersehen, dass Ihr Cron-Zeitplan auf Ihrem lokalen Computer funktioniert, aber unerwartet in einem verwalteten Kubernetes-Cluster mit UTC-Zeit ausgeführt wird.
Container-Images werden stattdessen mit einer integrierten Zeitzone ausgeliefert. Für die beliebtesten Bilder ist dies UTC. Viele Basisbilder, insbesondere minimale, enthalten nicht einmal die tzdata
Paket. Sie haben kein /etc/timezone
oder /etc/localtime
Dateien.
Hinzufügen von Zeitzonen zu Ihren Containern
Der erste Teil der Einstellung der richtigen Zeitzone besteht darin, sicherzustellen, dass tzdata
ist installiert. Wenn Ihr Image es nicht enthält, müssen Sie das Paket manuell als Teil Ihres Dockerfile
hinzufügen .
FROM ubuntu:latest ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y tzdata
Wenn tzdata
installiert, erhalten Sie normalerweise eine interaktive Eingabeaufforderung, mit der Sie die richtige Zeitzone aus einem Menü auswählen können. Dies ist nicht hilfreich, wenn Sie Docker-Container programmgesteuert erstellen. Setzen von DEBIAN_FRONTEND
Die Umgebungsvariable unterdrückt die Eingabeaufforderung und setzt die Zeitzone standardmäßig auf UTC.
Sobald Sie tzdata
haben in Ihr Image können Sie die richtige Zeitzone für Ihre Anwendung konfigurieren. Der einfachste Ansatz besteht darin, den TZ
zu setzen Umgebungsvariable auf die Zeitzone, die Sie verwenden möchten:
FROM ubuntu:latest ENV TZ=Europe/London ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y tzdata
Wenn Sie möchten, können Sie den TZ
festlegen Variable, wenn Sie Container starten. Übergeben Sie es als Umgebungsvariable an docker run
. Auf diese Weise können Sie die Standardzeitzone eines Bildes überschreiben, sofern es die tzdata
enthält Paket.
docker run -e TZ=Europe/London -it ubuntu:latest
Eine Alternative zu Umgebungsvariablen ist /etc/timezone
Datei. Sie können die erforderliche Zeitzone als Teil Ihres Dockerfile
schreiben . Wenn Sie diese Methode verwenden, müssen Sie tzdata
neu konfigurieren mit Ihrem Paketmanager. Denken Sie daran, den nicht interaktiven Modus zu verwenden, oder Sie erhalten erneut die grafische Zeitzonen-Eingabeaufforderung.
FROM ubuntu:latest RUN echo "Europe/London" > /etc/timezone RUN dpkg-reconfigure -f noninteractive tzdata
Andere Techniken
Wenn Sie die Zeitzonensynchronisation mit dem Host garantieren möchten, können Sie Ihre lokalen tzdata
einhängen Dateien in Ihre Container. Sie benötigen weiterhin tzdata
innerhalb des Containers, damit dies korrekt funktioniert.
docker run -v /etc/timezone:/etc/timezone -v /etc/localtime:/etc/localtime -it ubuntu:latest
Obwohl Docker keine integrierte Unterstützung für Zeitzonen bietet, gilt dies nicht für alle Container-Engines. Podman hat einen eigenen --tz
Flag, mit dem Sie die Zeitzone beim Erstellen eines neuen Containers festlegen können:
podman run --tz=Europe/London -it ubuntu:latest
Hinter den Kulissen stellt Podman eine entsprechende /etc/localtime
bereit Datei für Sie. Die angegebene Zeitzone bleibt für die Lebensdauer des Containers bestehen.
Mit Podman können Sie auch eine Standardzeitzone für Container festlegen, die ohne --tz
erstellt wurden Flagge. Erstellen oder bearbeiten Sie .config/containers/containers.conf
in Ihrem Home-Verzeichnis. Fügen Sie ein tz
hinzu Einstellung in einer neuen Zeile in der Datei:
# Used when no --tz flag is given tz = "Europe/London"
Die native Zeitzonenintegration von Podman erleichtert die Arbeit mit Podman im Vergleich zu Docker. Da die CLI von Podman mit der von Docker kompatibel ist, kann der Wechsel eine Überlegung wert sein, wenn Sie häufig mit Containern in unterschiedlichen Zeitzonen arbeiten.
Zusammenfassung
Zeitzonen werden beim Einrichten von Docker-Containern oft übersehen. Die meisten Basis-Images verwenden standardmäßig die UTC-Zeit, was zu Verwirrung führen kann, wenn die Zeitzone des Hosts unterschiedlich ist.
Durch die Installation der tzdata
Paket erhält Ihr Container über den TZ
Kompatibilität mit allen Zeitzonen Umgebungsvariable, /etc/timezone
, und /etc/localtime
. Alternativ können Sie die Zeitzone Ihres Hosts synchronisieren, indem Sie die relevanten Dateien in Ihren Containern mounten.
Denken Sie schließlich daran, dass diese Überlegungen auch für gehostete Docker-Dienste und Kubernetes-Cluster gelten. Ihre Container verwenden die UTC-Zeit, sofern nicht anders angegeben. Solange Sie Umgebungsvariablen setzen können, können Sie TZ
verwenden um die Zeitzone für Ihre Workloads anzupassen.