Cara mengatur waktu sistem secara dinamis dalam wadah Docker

28

Apakah ada cara untuk mengatur waktu sistem wadah Docker secara dinamis (saat berjalan) tanpa mempengaruhi mesin host?

Menggunakan

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

memberikan kesalahan berikut:

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.

Menggunakan

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

memberikan kesalahan berikut:

date: cannot set date: Operation not permitted

Gunakan kasus:

Saya perlu menguji perangkat lunak yang sensitif waktu (perilaku tergantung pada tanggal).

Kasus penggunaan umum lainnya:

  • menjalankan perangkat lunak lama dengan bug y2k
  • perangkat lunak pengujian untuk kepatuhan tahun-2038
  • men-debug masalah terkait waktu, seperti sertifikat SSL yang kadaluwarsa
  • menjalankan perangkat lunak yang berhenti berjalan di luar jangka waktu tertentu
  • proses membangun deterministik.
Vingtoft
sumber
Apa tujuan melakukannya? apa kasus penggunaan Anda?
dawud
Silakan lihat edit.
Vingtoft
1
Sebenarnya, saya baru saja menemukan dan secara positif menguji solusi menggunakan libfaketime github.com/wolfcw/libfaketime. Saya akan memperbarui dengan jawaban + contoh kerja segera.
Vingtoft

Jawaban:

21

Itu mungkin

Solusinya adalah memalsukannya di wadah. Lib ini memotong semua program panggilan sistem yang digunakan untuk mengambil waktu dan tanggal saat ini.

Implementasinya mudah. Tambahkan fungsionalitas ke Dockerfile Anda yang sesuai:

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

Ingatlah untuk mengatur variabel lingkungan LD_PRELOADsebelum Anda menjalankan aplikasi yang Anda inginkan waktu palsunya diterapkan.

Contoh:

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]

Anda sekarang dapat secara dinamis mengubah waktu server:

Contoh:

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())
Vingtoft
sumber
6
Bagi yang lain yang datang ke solusi ini, ketahuilah bahwa ini tidak akan berfungsi untuk aplikasi golang atau ongkos yang terhubung secara statis lainnya.
Sentinel
5
Terima kasih @Sentinel. Lucunya, saya baru saja menemukan jawaban ini melalui google, saya secara khusus ingin menggunakannya dengan aplikasi golang, dan saya perhatikan bahwa Anda meninggalkan komentar ini pada pertanyaan 1,5 tahun hanya 2 jam yang lalu. Rasanya seperti itu untukku. Terima kasih! :)
dimonomid
Mengapa tidak berhasil dalam situasi Anda? Apakah Golang tidak menggunakan panggilan sistem untuk mengambil waktu? @dimonomid Saya sarankan Anda mencobanya, cepat untuk mengimplementasikan solusinya.
Vingtoft
1
@Vingtoft Beri tahu saya jika itu benar-benar berfungsi, tetapi cari di sekitar. Golang tidak terhubung secara dinamis di perpustakaan.
Sentinel
1
@dimonomid Ya saya cukup kecewa. Lebih kecewa dengan Docker sebenarnya. Saya perlu menerapkan tes terkait waktu. Ini membuat Docker sangat tidak berguna sebagai "wadah". Saya akan berpikir mencegat panggilan waktu sistem untuk sinkronisasi zona waktu akan menjadi item 1 pada agenda Docker. Sepertinya tidak.
Sentinel
4

Jenny D benar karena secara default wadah Docker tidak mengizinkan akses ke jam sistem.

Namun, di Linux, jika Anda setuju dengan container Anda yang memiliki akses ke kapabilitas ini, Anda dapat mengizinkan kapabilitas ini menggunakan opsi "--cap-add = SYS_TIME" dari perintah "docker run" saat membuat Anda container:

# 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

Kemudian, Anda dapat mengubah waktu dari dalam wadah yang sedang berjalan:

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

Dokumentasi referensi: https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities

Oleg Kazakov
sumber
2
Ini mengubah waktu pada mesin host. Waktu pada sistem Linux saat ini tidak menggunakan namespace, hanya ada satu nilai untuk host dan semua kontainer.
BMitch
Ya kau benar. Ini mengubah waktu jam mesin host. Cukup baca ulang pertanyaan dan sadari pertanyaannya, memang, secara eksplisit disebutkan tentang TIDAK mengubah jam mesin host. Saya berdiri dikoreksi :)
Oleg Kazakov
0

Mulai wadah dengan variabel lingkungan tambahan:

docker run -e "SET_CONTAINER_TIMEZONE=true" \
           -e "CONTAINER_TIMEZONE=US/Arizona" [docker image name]
13ditarik
sumber
Saya mencari cara untuk mengatur waktu secara dinamis, artinya dapat diatur pada saat runtime. Saya telah memperbarui pertanyaan saya.
Vingtoft
0

solusi docker-compose:

Tambahkan /etc/localtime:/etc/localtime:roke volumesatribut.

Lihatlah tautan ini sebagai contoh.

Benyamin Jafari
sumber