ウェブサイト検索

Dockerコンテナ内のタイムゾーンの扱い方


タイムゾーンは、アプリケーションをコンテナ化する際によく混乱をもたらす原因です。あなたのcronタスクは正しい時間に実行されますか?Dockerコンテナはホストのタイムゾーンを引き継がないため、アプリケーションに混乱を引き起こす予期しないスケジューリングの問題が発生する可能性があります。

ここにあります

date

イギリス夏時間のタイムゾーン内で、Ubuntu 20.04ホスト上でネイティブに実行されているコマンド:

そして、これは未修正のコンテナに基づいた同じコマンドです。

ubuntu:20.04

画像 :

コンテナはUTCタイムゾーンを使用しており、2つの時間の間に1時間の差を生じさせています。

Linuxのタイムゾーンはどのように機能していますか?

ほとんどのLinuxディストリビューションは、タイムゾーン情報を提供するためにtzdataパッケージを使用します。tzdataがインストールされている場合、/etc/timezoneファイルを読み取ることで現在のタイムゾーンを確認できます:

あなたはまた、/etc/localtimeというファイルを持っています。これは選択した場所の正しいタイムゾーンデータベースへのシンボリックリンクです:

タイムゾーンを変更すると、使用することになります

dpkg-reconfigure tzdata

, /etc/localtime シンボリックリンクは新しいデータベースを指すように更新されます。コマンドの出力は、例えば

date

アクティブタイムゾーンのオフセットが含まれるように調整されます。

コンテナの問題

コンテナに関する課題は、最初にタイムゾーンを設定することから生じます。ホストの設定を思い出すと、オペレーティングシステムのインストールの一部としてタイムゾーンを設定する必要がありました。しかし、新しいコンテナを実行すると、インストール段階なしにすぐに開始されます。そのため、適切なタイムゾーンを選ぶ機会がありません。

理論的には、コンテナランタイムはホストのタイムゾーンを自動的に継承することができる。しかし、これはリモート環境にデプロイする際に予期しない結果を引き起こす可能性があるため、実際には行われない。あなたのcronスケジュールがローカルマシンでは正常に動作しているが、UTC時間を使用する管理されたKubernetesクラスターでは予期しない形で実行されることを見落とすのは簡単である。

コンテナイメージには代わりに組み込まれたタイムゾーンが付属しています。最も人気のあるイメージでは、これがUTCになります。特に最小限のベースイメージの多くには、tzdata パッケージすら含まれていません。/etc/timezone や /etc/localtime ファイルは存在しません。

コンテナにタイムゾーンを追加する

適切なタイムゾーンを設定するための最初のステップは、tzdataがインストールされていることを確認することです。もしあなたのイメージにそれが含まれていない場合は、Dockerfileの一部として手動でパッケージを追加する必要があります。

FROM ubuntu:latest

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y tzdata

tzdataをインストールすると、通常、メニューから正しいタイムゾーンを選択するための対話型プロンプトが表示されます。しかし、これはプログラム上でDockerコンテナを構築しているときには役に立ちません。DEBIAN_FRONTEND環境変数を設定することで、プロンプトが抑制され、タイムゾーンがデフォルトでUTCに設定されます。

一度tzdataをイメージに追加したら、アプリケーションの正しいタイムゾーンを設定する準備が整いました。最も簡単な方法は、使用したいタイムゾーンにTZ環境変数を設定することです:

FROM ubuntu:latest

ENV TZ=Europe/London

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y tzdata

必要に応じて、コンテナを起動するときにTZ変数を設定できます。これを環境変数としてdocker runに渡します。これにより、イメージのデフォルトのタイムゾーンをオーバーライドすることができますが、tzdataパッケージが含まれている必要があります。

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

環境変数の代替として、/etc/timezone ファイルがあります。必要なタイムゾーンを Dockerfile の一部として記述できます。この方法を使用する場合は、パッケージマネージャーを使用して tzdata を再構成する必要があります。非対話モードを使用することを忘れないでください。そうしないと、グラフィカルなタイムゾーンのプロンプトが再度表示されます。

FROM ubuntu:latest

RUN echo "Europe/London" > /etc/timezone

RUN dpkg-reconfigure -f noninteractive tzdata

他の技術

ホストとのタイムゾーン同期を保証したい場合は、ローカルのtzdataファイルをコンテナにマウントできます。そのためには、コンテナ内にtzdataが必要です。

docker run -v /etc/timezone:/etc/timezone -v /etc/localtime:/etc/localtime -it ubuntu:latest

Dockerにはタイムゾーンに対する組み込みサポートがありませんが、すべてのコンテナエンジンがそうではありません。Podmanには、新しいコンテナを作成する際にタイムゾーンを設定できる専用の--tzフラグがあります。

podman run --tz=Europe/London -it ubuntu:latest

裏側で、Podman はあなたのために適切な /etc/localtime ファイルをマウントします。指定されたタイムゾーンはコンテナのライフタイムの間ずっと持続します。

Podmanは、--tzフラグを指定せずに作成されたコンテナ用のデフォルトのタイムゾーンを設定することもできます。ホームディレクトリ内にある.config/containers/containers.confを作成または編集します。ファイル内の新しい行にtz設定を追加してください:

Used when no --tz flag is given

tz = "Europe/London"

Podmanのネイティブなタイムゾーン統合により、Dockerよりも扱いやすくなっています。PodmanのCLIはDockerと互換性があるため、異なるタイムゾーンで頻繁にコンテナを扱う場合は、切り替える価値を検討することができます。

要約

Dockerコンテナを設定する際、タイムゾーンはしばしば見落とされがちです。ほとんどの基本イメージはUTC時間がデフォルトで設定されており、ホストのタイムゾーンが異なると混乱を招く可能性があります。

tzdata パッケージをインストールすることで、コンテナは TZ 環境変数、/etc/timezone、および /etc/localtime を介してすべてのタイムゾーンとの互換性を得ます。もしくは、関連するファイルをコンテナにマウントすることでホストのタイムゾーンを同期することもできます。

最後に、これらの考慮事項はホストされたDockerサービスやKubernetesクラスターにも適用されることを忘れないでください。コンテナは他に指示がない限りUTC時間を使用します。環境変数を設定できる限り、TZを使用してワークロードのタイムゾーンを調整できます。

関連記事: