Dockerコンテナーでシステム時間を動的に設定する方法


28

ホストマシンに影響を与えることなく、Dockerコンテナのシステム時間を動的に(実行時に)設定する方法はありますか?

を使用して

hwclock --set --date "Sat Aug 17 08:31:24 PDT 2016"

次のエラーが発生します。

hwclock: Cannot access the Hardware Clock via any known method.
hwclock: Use the --debug option to see the details of our search for an access method.

を使用して

date -s "2 OCT 2006 18:00:00"

次のエラーが発生します。

date: cannot set date: Operation not permitted

使用事例:

時間に敏感なソフトウェアをテストする必要があります(動作は日付によって異なります)。

その他の一般的な使用例:

  • y2kバグがあるレガシーソフトウェアの実行
  • 2038年準拠のテストソフトウェア
  • 期限切れのSSL証明書などの時間関連の問題のデバッグ
  • 特定の期間外に実行を停止するソフトウェアの実行
  • 確定的なビルドプロセス。

そうする目的は何でしょうか?あなたのユースケースは何ですか?
-dawud

編集をご覧ください。
ヴィングトフト


1
実際、libfaketime github.com/wolfcw/libfaketimeを使用してソリューションを見つけ、積極的にテストしました。すぐに回答+作業例を更新します。
ヴィングトフト

回答:


21

可能です

解決策は、コンテナで偽造することです。このライブラリは、現在の日時を取得するために使用するすべてのシステムコールプログラムをインターセプトします。

実装は簡単です。必要に応じて、Dockerfileに機能を追加します。

WORKDIR /
RUN git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /libfaketime/src
RUN make install

LD_PRELOAD偽の時間を適用するアプリケーションを実行する前に、環境変数を設定することを忘れないでください。

例:

CMD ["/bin/sh", "-c", "LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME_NO_CACHE=1 python /srv/intercept/manage.py runserver 0.0.0.0:3000]

サーバーの時間を動的に変更できるようになりました。

例:

import os
def set_time(request):
    print(datetime.today())
    os.environ["FAKETIME"] = "2020-01-01"  # Note: time of type string must be in the format "YYYY-MM-DD hh:mm:ss" or "+15d"
    print(datetime.today())

6
このソリューションを使用する他のユーザーの場合、これはgolangアプリケーションまたは他の静的にリンクされたexeでは機能しないことに注意してください。
センチネル

5
@Sentinelに感謝します。おもしろいことに、私はこの回答をグーグルで見つけました。具体的にはgolangアプリで使用したいと思います。1.5年前の質問に2時間前にこのコメントを残したことに気付きました。それは私のためだったように感じます。ありがとう!:)
dimonomid

なぜあなたの状況では機能しないのですか?Golangはシステムコールを使用して時間を取得しませんか?@dimonomid試してみることをお勧めします。ソリューションをすぐに実装できます。
ヴィングトフト

1
@Vingtoft実際に動作するかどうかを教えてください。Golangはライブラリ内で動的にリンクしません。
センチネル

1
@dimonomidええ、私はかなりがっかりしました。実際にはDockerにはもっとがっかりしました。タイミング関連のテストを実装する必要があります。これにより、Dockerは「コンテナー」としてほとんど役に立たなくなります。タイムゾーンの同期のためにシステム時間の呼び出しを傍受することは、Dockerの議題の項目1であると思っていたでしょう。どうやら。
センチネル

4

Jenny Dは、デフォルトではDockerコンテナーがシステムクロックへのアクセスを許可しないという点で正しいです。

ただし、Linuxでは、コンテナがこの機能にアクセスできる場合は、コンテナの作成時に「docker run」コマンドの「--cap-add = SYS_TIME」オプションを使用してこの機能を許可できます。

# docker run --cap-add=SYS_TIME -d --name teamcity-server-instance -v /opt/teamcity/data:/data/teamcity_server/datadir -v /opt/teamcity/logs:/opt/teamcity/logs -p 80:8111 jetbrains/teamcity-server

次に、実行中のコンテナ内から時間を変更できます。

# docker exec -it teamcity-server-instance /bin/bash
# date +%T -s "15:03:00"
15:03:00
#

リファレンスドキュメント:https : //docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities


2
これにより、ホストマシンの時間が変更されます。Linuxシステムの時間は現在名前空間ではなく、ホストとすべてのコンテナに1つの値しかありません。
BMitch

はい、あなたが正しい。これにより、ホストマシンのクロックの時刻が変更されます。質問を読み直し、質問を実現しました。実際、ホストマシンのクロックを変更しないことについて明示的に言及しました。私は修正スタンド:)
オレグKazakov

0

追加の環境変数を使用してコンテナを起動します。

docker run -e "SET_CONTAINER_TIMEZONE=true" \
           -e "CONTAINER_TIMEZONE=US/Arizona" [docker image name]

動的に時間を設定する方法を探しています。つまり、実行時に設定することができます。質問を更新しました。
ヴィングトフト

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.