Як динамічно встановити системний час у контейнері 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

Перегляньте редагування.
Vingtoft


1
Насправді я лише знайшов і позитивно перевірив рішення, використовуючи libfaketime github.com/wolfcw/libfaketime, я скоро оновлю відповідь + робочий приклад.
Vingtoft

Відповіді:


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
Для інших, хто приходить до цього рішення, пам’ятайте, що це не працюватиме для програм голангів або інших статично пов'язаних програм.
Sentinel

5
Дякую @Sentinel. Як не дивно, що я просто знайшов цю відповідь через google, я спеціально хочу використовувати її з додатком golang, і я помітив, що ви залишили цей коментар на 1,5-річне запитання лише 2 години тому. Мені здається, що це було для мене. Спасибі! :)
димономід

Чому у вашій ситуації не працює? Чи Golang не використовує системні дзвінки для отримання часу? @dimonomid Я пропоную вам спробувати, це швидко реалізувати рішення.
Vingtoft

1
@Vingtoft Дайте мені знати, чи справді це працює, але пошукайте навколо. Golang не динамічно зв'язується в бібліотеках.
Sentinel

1
@dimonomid Так, я був дуже розчарований. Більше насправді розчарував Докер. Мені потрібно впровадити тести, пов’язані з термінами. Це робить Docker в значній мірі марним як "контейнер". Я б подумав, що перехоплення системних часових дзвінків для синхронізації часових поясів було б пунктом 1 порядку денного Докера. Мабуть, ні.
Sentinel

4

Дженні D вірна в тому, що контейнер Docker за замовчуванням не дозволяє отримати доступ до системних годин.

Однак, в Linux, якщо ви добре, що ваш контейнер має доступ до цієї можливості, ви можете дозволити цю можливість за допомогою команди "--cap-add = SYS_TIME" команди "docker run" під час створення контейнера:

# 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-capa sposobnosti


2
Це змінює час роботи хост-машини. Наразі час у системі Linux не є простором імен, є лише одне значення для хоста та всіх контейнерів.
BMitch

Так, ви праві. Це змінює час роботи хост-машини. Просто перечитав питання і зрозумів питання, дійсно, прямо сказано про НЕ зміну годинника хост-машини. Я стою виправлений :)
Олег Казаков

0

Запустіть контейнер із додатковою змінною середовища:

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

Я шукаю спосіб динамічно встановити час, тобто його можна встановити під час виконання. Я оновив своє запитання.
Vingtoft

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.