Časová pásma jsou častým zdrojem zmatků při kontejnerizaci aplikace. Spustí se vaše úlohy cronu ve správný čas? Kontejnery Dockeru nedědí časové pásmo hostitele, takže se můžete setkat s neočekávanými problémy s plánováním, které s vaší aplikací způsobí zmatek.
Zde je date
příkaz běžící nativně na hostiteli Ubuntu 20.04 v časovém pásmu britského letního času:
A zde je stejný příkaz v kontejneru založeném na neupraveném ubuntu:20.04
obrázek:
Kontejner používá časové pásmo UTC, takže mezi těmito dvěma časy je jednohodinový rozdíl.
Jak fungují časová pásma Linuxu?
Většina distribucí Linuxu používá tzdata
balíček poskytující informace o časovém pásmu. Když tzdata
je nainstalován, můžete si aktuální časové pásmo prohlédnout přečtením /etc/timezone
soubor:
Budete mít také /etc/localtime
soubor. Toto je symbolický odkaz na správnou databázi časového pásma pro vybrané umístění:
Pokud změníte časové pásmo, použijte dpkg-reconfigure tzdata
, /etc/localtime
symbolický odkaz se aktualizuje, aby ukazoval na novou databázi. Výstup příkazů jako date
bude upraveno tak, aby zahrnovalo posun aktivního časového pásma.
Problém s kontejnery
Problém s kontejnery vychází především z nastavení časového pásma. Pokud si vzpomenete na dobu, kdy jste nastavili hostitele, museli byste nastavit časové pásmo jako součást instalace operačního systému. Když spustíte nový kontejner, spustí se okamžitě, bez jakékoli fáze „instalace“. Není možnost vybrat vhodné časové pásmo.
Teoreticky by běhové moduly kontejneru mohly nabízet automatické dědění časového pásma hostitele. To se nestane, protože to může vést k neočekávaným výsledkům při nasazení do vzdálených prostředí. Bylo by snadné přehlédnout, že váš plán cron funguje na vašem místním počítači, ale neočekávaně se spouští ve spravovaném clusteru Kubernetes pomocí času UTC.
Obrázky kontejneru se místo toho dodávají se zapečeným časovým pásmem. U většiny oblíbených obrázků to bude UTC. Mnoho základních obrázků, zejména těch minimálních, nebude obsahovat ani tzdata
balík. Nebudete mít žádné /etc/timezone
nebo /etc/localtime
soubory.
Přidání časových pásem do vašich kontejnerů
První částí nastavení správného časového pásma je zajistit tzdata
je nainstalován. Pokud to váš obrázek neobsahuje, budete muset balíček přidat ručně jako součást vašeho Dockerfile
.
FROM ubuntu:latest ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y tzdata
Když tzdata
instalace, obvykle dostanete interaktivní výzvu, která vám umožní vybrat správné časové pásmo z nabídky. To není užitečné, když programově vytváříte kontejnery Docker. Nastavení DEBIAN_FRONTEND
proměnná prostředí potlačí výzvu a výchozí časové pásmo nastaví na UTC.
Jakmile získáte tzdata
do svého obrázku, jste připraveni nakonfigurovat správné časové pásmo pro vaši aplikaci. Nejjednodušší přístup je nastavit TZ
proměnná prostředí na časové pásmo, které chcete použít:
FROM ubuntu:latest ENV TZ=Europe/London ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y tzdata
Pokud chcete, můžete nastavit TZ
proměnná při spuštění kontejnerů. Předejte ji jako proměnnou prostředí docker run
. To vám umožní přepsat výchozí časové pásmo obrázku za předpokladu, že obsahuje tzdata
balíček.
docker run -e TZ=Europe/London -it ubuntu:latest
Alternativou k proměnným prostředí je /etc/timezone
soubor. Požadované časové pásmo můžete napsat jako součást svého Dockerfile
. Pokud použijete tuto metodu, musíte překonfigurovat tzdata
pomocí správce balíčků. Nezapomeňte použít neinteraktivní režim, jinak se znovu zobrazí grafické upozornění na časové pásmo.
FROM ubuntu:latest RUN echo "Europe/London" > /etc/timezone RUN dpkg-reconfigure -f noninteractive tzdata
Další techniky
Pokud chcete zaručit synchronizaci časového pásma s hostitelem, můžete připojit místní tzdata
soubory do vašich kontejnerů. Stále budete potřebovat tzdata
uvnitř kontejneru, aby to fungovalo správně.
docker run -v /etc/timezone:/etc/timezone -v /etc/localtime:/etc/localtime -it ubuntu:latest
Přestože Docker neposkytuje žádnou vestavěnou podporu pro časová pásma, neplatí to pro všechny kontejnerové motory. Podman má vyhrazený --tz
příznak, který vám umožní nastavit časové pásmo při vytváření nového kontejneru:
podman run --tz=Europe/London -it ubuntu:latest
Podman v zákulisí připojí vhodné /etc/localtime
soubor pro vás. Zadané časové pásmo zůstane zachováno po celou dobu životnosti kontejneru.
Podman vám také umožňuje nastavit výchozí časové pásmo pro kontejnery vytvořené bez --tz
vlajka. Vytvořte nebo upravte .config/containers/containers.conf
ve vašem domovském adresáři. Přidejte tz
nastavení na nový řádek v souboru:
# Used when no --tz flag is given tz = "Europe/London"
Nativní integrace časového pásma Podman usnadňuje práci než s Dockerem. Protože Podman's CLI je kompatibilní s Docker's, provedení tohoto přechodu může stát za zvážení, pokud často pracujete s kontejnery v různých časových pásmech.
Přehled
Časová pásma jsou při nastavování kontejnerů Docker často přehlížena. Většina základních obrázků má výchozí čas UTC, což může vést k nejasnostem, když je časové pásmo hostitele jiné.
Instalací tzdata
balíček, váš kontejner získá kompatibilitu se všemi časovými pásmy prostřednictvím TZ
proměnná prostředí, /etc/timezone
a /etc/localtime
. Případně můžete synchronizovat časové pásmo hostitele připojením příslušných souborů do kontejnerů.
Nakonec nezapomeňte, že tyto úvahy platí také pro hostované služby Docker a clustery Kubernetes. Pokud nedostanete jiný pokyn, vaše kontejnery budou používat čas UTC. Dokud můžete nastavit proměnné prostředí, budete moci používat TZ
upravit časové pásmo pro vaše pracovní vytížení.