Как изменить часовой пояс в контейнере docker?

Введение

Для настройки практически любого сервера требуется выполнить ряд стандартных шагов, которые мало чем отличаются в различных ситуациях. Какой бы функционал вы не готовили, вам придется настроить правильное время и включить его автообновление. Без установки сетевых настроек я вообще не представляю работу современного сервера. В голову не приходит ни один пример. Один и тот же набор настроек практически на автомате выполняется после установки. Своими наработками по этой теме я хочу поделиться с вами — то, что я в первую очередь настраиваю на новоиспеченном сервере centos.

Еще раз обращаю внимание, что данные настройки я делаю на виртуальном сервере. Если у вас железный сервер, то рекомендуется выполнить еще некоторые настройки, о которых я здесь не упоминаю

К ним относится, к примеру, настройка и проверка отказоустойчивости при выходе одного из дисков. Отключение регулярной проверки массива mdadm и др.

Синхронизация времени с помощью chrony, ntpdate

Способов синхронизации времени в centos существует как минимум три:

  • ручной с помощью утилиты ntpdate
  • автоматический при помощи сервиса ntp или chrony
  • автоматический через утилиту из пакета systemd — timesyncd.

Рассмотрим сначала вариант ручной однократной синхронизации при помощи программы ntpdate. Она позволяет разово синхронизировать локальное время с эталонным сервером времени в интернете. Подобных эталонов существует великое множество. Мы для примера воспользуемся одним из них — pool.ntp.org

Запускаем синхронизацию времени:

Если получите ошибку

значит утилита у вас не установлена. Установить ее можно из базового репозитория.

Это актуально только для 7-й версии, в В CentOS 8 ntp и ntpdate убрали из репозиториев. Для синхронизации времени можно использовать только chrony. Ее мы рассмотрим ниже.

Утилита ntpdate провела синхронизацию, в результате которой к моему системному времени было добавлено 0.001664 секунды для приближения к эталонному. Если в результате работы синхронизации вы получаете ошибку: no server suitable for synchronization found то попробуйте в работе утилиты использовать непривилегированный порт. По-умолчанию ntpdate работает по 123 порту. Если он закрыт на фаерволе, то помочь в синхронизации поможет следующий параметр:

Если у вас запуск ntpdate завершается ошибкой — the NTP socket is in use, exiting, значит у вас уже установлена и запущена служба ntpd, которая заняла udp порт, необходимый для работы ntpdate. Установкой и настройкой этой службы мы и займемся далее.

Как я уже сказал, в CentOS 8 служба ntpd и утилита ntpdate стали недоступны в базовых репозиториях. Возможно, их как-то удастся установить из сторонних репозиториев, но большого смысла нет. Можно воспользоваться программой chrony. Ставим ее:

Запускаем и добавляем в автозагрузку.

Программа стартовала и уже выполнила синхронизацию с источниками точного времени в интернете. Каких-то особых настроек для получения точного времени больше не надо. Служба будет постоянно работать и выполнять синхронизацию. Проверим это с помощью timedatectl.

systemd-timesyncd

Отдельно пару слов о службе systemd-timesyncd, которая в системах с systemd выступает в роли простого sntp клиента, в отличие от chrony и ntp, которые в том числе могут работать в качестве сервера времени. В Debian служба присутствует в составе systemd и ей можно пользоваться, что достаточно удобно. Легкий полновесный клиент, который по дефолту есть в составе системы.

Я сначала не мог понять, что с systemd-timesyncd в Centos. Команда вроде есть и работает, но как оказалось, это просто обертка над chrony. Реально команда управляет именно chrony и без него не работает. Без него вы получите ошибку, при попытке активировать компонент timesyncd.

Если вернете chrony в систему, то timedatectl будет запускать именно его. Немного погуглив, я понял в чем тут дело. Red Hat компилирует systemd без компонента systemd-timesyncd, предлагая по дефолту именно chrony.

How to change time in Docker container

The time in a Docker container can be changed in 5 ways. To know the current time, the ‘date’ command can be used.

docker exec -it container-id date

To know the timezone configured in a Docker container, the ‘ /etc/timezone ‘ file has to be checked.

docker exec -it container-id cat /etc/timezone

1. Using date command

The easiest way to change the time in a Docker container is to change the time using ‘date’ command after connecting to the container.

docker exec -it container-name /bin/bash
date +%T -s "10:00:00"

Though the time zone change usually reflects immediately, in some cases, the container needs a restart for the time to change.

2. Using environment variables

The timezone of a container can be set using an environment variable in the docker container when it is created.

docker run -e TZ=America/New_York ubuntu date

The time zone data package tzdata needs to be installed in the container for setting this timezone variable.

By configuring an NTP server, we ensure that the time zones in the containers are always synced.

3. Using Dockerfile

In hosting environment or cases which need too many identical containers to be spun up, the easiest way to manage is using Dockerfile.

The Dockerfile contains the basic configuration settings for each container. To change time in Docker container, the changes can be done in the corresponding Dockerfile.

The settings in the Dockerfile would reflect while recreating or adding a new container. And, all commands from the Docker file will be run as the root user. The entry in Dockerfile would look like:

RUN echo "Europe/Stockholm" > /etc/timezone
RUN dpkg-reconfigure -f noninteractive tzdata

The installation command for tzdata package would vary based on the OS image that the container is using.

We also update the entry point script of the containers to include the timezone settings. This ensures that the date would be set whenever the container is restarted.

4. Using volumes

A major issue with Docker containers is that the data in the container is not persistent over restarts. To work around this, we use Docker data volumes.

Data volumes in Docker machines are shared directories that contains the data specific to containers. The data in volumes are persistent and will not be lost during container recreation.

The directory ‘/usr/share/zoneinfo’ in Docker contains the container time zones available.  The desired time zone from this folder can be copied to /etc/localtime file, to set as default time.

This time zone files of the host machine can be set in Docker volume and shared among the containers by configuring it in the Dockerfile as shown.

volumes:
- "/etc/timezone:/etc/timezone:ro"
- "/etc/localtime:/etc/localtime:ro"

The containers created out of this Dockerfile (docker-compose.yml) will have the same timezone as the host OS (as set in /etc/localtime file) .

5. Using images

Manually changing time zone is not feasible when there are too many containers. To create more Docker instances with the same time zone, we use images.

After setting the desired time zone in a Docker container, we exit it and create a new image from that container using ‘docker commit’. NTP service is also configured in that image.

docker commit container-name image-name

Using this image, we can create one or more containers with the same time zone. The images are stored in repositories for future use.

Часто задаваемые вопросы по теме статьи (FAQ)

Есть ли принципиальная разница, что использовать для синхронизации времени, ntp или chrony?

Мне отличия не известны. В общем случае, обе утилиты делают одно и то же. Формат конфигов у них тоже одинаковый. Конечно же, программы имеют отличия, но в общем случае, для типового сервера нет принципиальной разницы.

Нужно ли перезагружать сервер после изменения времени?

Я бы рекомендовал так делать. Если перезагрузиться совсем нельзя, я рекомендую вручную перезапустить основные сервисы. Не все могут автоматически корректно отработать внезапное изменение времени. Может начаться путаница в логах, особенно если время изменилось существенно (на несколько часов).

У меня никак не синхронизируется время на сервере. С чем это может быть связано?

Некоторые провайдеры блокируют порты, необходимые для синхронизации времени. Связано это с тем, что серверы времени могут быть использованы для организации ddos атак. Обычно в таком случае провайдер предоставляет адреса своих внутренних ntp серверов, с которых можно произвести синхронизацию. Так что если у вас никак не работает синхронизация времени на арендованном сервере, рекомендую написать вопрос в тех. поддержку и прояснить этот момент. Подробнее об этом рассказываю в отдельной статье.

Возможна ли одновременная работа chrony и ntpd?

Нет, это не возможно. Да и не имеет практического смысла. Обе эти программы проверяют при запуске, свободен ли udp порт 123 на сетевом интерфейсе. Если он занят другой программой, то запуск завершится с ошибкой.

Как лучше сделать — синхронизировать время всех серверов с внешним источником или настроить сервер времени внутри своей локальной сети?

В общем случае лучше настроить у себя в локальной сети сервер времени и синхронизироваться с него. Так у вас гарантированно у всех серверов будет одинаковое время, даже если по какой-то причине сам сервер времени не будет синхронизироваться с внешним источником. Это лучше, нежели разное время на всех серверах.

CentOS 7 установка на raid

Теперь рассмотрим наиболее сложный вариант установки. Мы будем ставить CentOS 7 на программный рейд. Для примера возьмем 2 диска и raid 1. Все установки будут такие же, как мы рассмотрели ранее, кроме одной — INSTALLATION DESTINATION.

Подключаем 2 диска к системе, загружаемся с установочного диска и идем в раздел разбивки диска. Видим 2 жестких диска. Выбираем оба и отмечаем пункт I will configure partition:

Жмем Done. Открывается немного кривое окно управления разделами жесткого диска.

Здесь мы первым делом удаляем все существующие разделы:

Должно получиться примерно так:

Нажимаем Done, когда закончим. В новом окне подтверждаем разбивку диска, нажимая Accept Сhanges:

Все остальные параметры выставляем как было рассказано выше. Теперь можно начинать установку CentOS 7 на программный raid, который мы только что создали.

Во время установки нужно указать пароль root, либо создать дополнительных пользователей. Пароль рекомендую установить, пользователей по необходимости.

После завершения установки на raid зайдем в систему и проверим состояние массива:

# df -h
# cat /proc/mdstat

Посмотрим информацию о корневом массиве:

# mdadm -D /dev/md126

Все в порядке, установка сервера закончена. Рейд раздел нормально функционирует, обеспечивая отказоустойчивость сервера.

Я очень рекомендую использовать софтовый raid линукса mdadm в повседневной деятельности. Он намного надежнее, понятнее и стабильнее встроенных в материнскую плату контроллеров. Отдавать предпочтение аппаратному рейду следует только в том случае, если он действительно аппаратный, он имеет батарейку и он действительно увеличивает производительность сервера. Во всех остальных случаях рекомендую пользоваться mdadm.

Напоминаю, что данная статья является частью единого цикла статьей про сервер Centos.

Native Time Zone Information and the JRE

The JRE reads the native time zone information to determine your default time zone.

For example, on Windows, the JRE queries the registry to determine the default time zone.

However, the JRE also maintains its own time zone database. This provides cross-platform support because the different operating system APIs are not sufficient to support the Java APIs. The Java time zone database supports time zone IDs and determines daylight saving time rules for all the time zones that the JRE supports. The tool is available for download from the Java SE Download Page.

Modifications to the JRE for each specific operating system are necessary so that the operating system can deliver the system time to the JRE. Then, if a Java application requests the system date by calling date and time related constructors, the system time is returned.

Examples of such constructors are:

  • java.util.Date()
  • java.util.GregorianCalendar()

Constructors related to date and time include:

  • System.currentTimeMillis()
  • System.nanoTime()

Operating system-specific patches might be required to ensure that the correct system time is delivered to the JRE.

The following sections describe troubleshooting techniques for time zone settings.

Determine the Time Zone Data Version in Use

The time zone database version that ships in any JRE from Oracle is documented in the release notes. However, the actual version can be different from the version mentioned there if the JRE was patched using the tool.

To determine the current time zone data version of your JRE, either run the tool with the Version option, or examine the header of the file.

Follow these two steps to determine the time zone data:

  • Determine the Time Zone with TZupdater: The Java time zone updater tool is called . To determine the time zone database version of your JRE, run this tool as follows:

    java -jar tzupdater.jar -V
    

    Here is a typical output from running the tool.

    tzupdater version 2.1.0-b04
    JRE tzdata version: tzdata2016f
    

    You can download the tool from this web page: Timezone Updater Tool.

  • Examine the ZoneInfoMappings File: Even without the tool, you can quickly check the version by examining the header of the file . This data is stored in a binary format that is specific to Java. On the Oracle Solaris, Linux and Mac macOS operating systems, you can use the octal dump command to see the header of this file.

    The following example shows the octal dump command format.

    /usr/bin/od -c -j 11 -N 11 <java-home>/lib/zi/ZoneInfoMappings
    

    The following example shows the typical result of the dump command.

    /usr/bin/od -c -j 11 -N 11 /farfaraway/jdks/jdk1.6.0_21/jre/lib/zi/ZoneInfoMappings0000000   t   z   d   a   t   a   2   0   1   0   i0000013
    

    The following example shows the time zone data version that is embedded in that JRE is .

    On Microsoft Windows, you can use the command to examine the file. Here is an example.

    findstr tzdata <java-home>\lib\zi\ZoneInfoMappings
    

Время на сервере CentOS

Во время установки CentOS вам обязательно предлагается настроить текущее время, указать временную зону, в которой находится машина. По-умолчанию инсталлятор берет время из bios и предлагает его откорректировать. Кто-то во время установки не придал этому значение и не откорректировал часы, кто-то ошибся в выборе часового пояса. Так же популярна ситуация, когда сервер арендуется за границей, там уже предустановлена система и ее настройки времени и часового пояса не соответствуют необходимым. Все это можно исправить после установки, я подробно обо всем расскажу. Но начнем с самого простого.

Почему важно, чтобы в системе было правильное время? Причин может быть несколько:

  • Для корректного логирования событий той или иной службы. Например, у вас в сети случился какой-то инцидент и вы его расследуете. Удобно, когда время на всех машинах сети одинаковое, это упрощает проверку и сопоставление различных действий.
  • Могут возникнуть проблемы с работой в доменной среде windows, если у вас существенно различаются данные системных часов. Это актуально, если у вас файловый сервер centos интегрирован в доменную сеть windows. Пользователь в определенный момент не сможет получить доступ к файлам, если время сервера превысит допустимое отклонение от контроллера домена (более 5 минут). Это связано с особенностью работы протокола аутентификации Kerberos.
  • На вашем сервере может располагаться web хостинг с сайтами, в которых указано время публикации материала. Если часы сервера не будут совпадать с временной зоной основной аудитории, то могут возникать курьезные моменты, когда посетители увидят статьи, опубликованные в будущем. Так же некорректно будет работать статистика, основанная на анализе логов apache или nginx.
  • Вы используете планировщик cron в своей работе. Для корректной и предсказуемой работы запланированных событий дата и часовой пояс на сервере должны быть настроены правильно.

Чтобы избежать проблем в подобных ситуациях, займемся настройкой времени, даты и часового пояса. Кратко этот вопрос я разбирал в отдельном материале по базовой настройке centos после установки. Рекомендую с ним ознакомиться, там много полезного.

Как работает время в Linux?

Операционная система Linux хранит и обрабатывает системное время в специальном Unix формате — количество секунд прошедших с полуночи первого января 1970 года. Эта дата считается началом эпохи Unix. И используется не ваше локальное время, а время по гринвичскому меридиану.

Для преобразования времени по Гринвичу в региональное время используется часовой пояс. Это преобразование выполняется для каждого пользователя. Это необходимо, чтобы каждый пользователь мог настроить для себя правильное по его временной зоне время. Такое поведение просто необходимо на серверах, когда на одной машине могут работать люди из разных частей мира.

По умолчанию в системе может быть установлен неправильный часовой пояс, это приведет к путанице в логах событий, да и другим трудностям. Но все это легко исправить. Дальше мы рассмотрим несколько способов изменить часовой пояс Linux.

Настройка сервера ntp в CentOS 7

Сервер времени ntp использует в своей работе одноименный протокол — Network Time Protocol, которому для работы необходим UDP порт 123. Так что перед установкой и настройкой службы времени убедитесь, что на фаерволе открыт этот порт.

Устанавливаем сервер ntp:

Теперь отредактируем файл конфигурации /etc/ntp.conf , удалив все лишнее:

Параметр Описание
server Список серверов для синхронизации времени
driftfile Задает адрес файла, в котором хранится история изменений времени во время синхронизации. Если по каким-то причинам синхронизация времени с внешними источниками станет невозможна, служба времени изменит системные часы в соответствии с записями в этом файле.
restrict 127.0.0.1

Указывает, что пользоваться нашим сервером времени можно только непосредственно с локального интерфейса. Если вам необходимо разрешить другим компьютерам в вашей локальной сети синхронизировать время с текущей машины, то укажите в данном параметре адрес вашей сети, например:

restrict  192.168.10.0 mask 255.255.255.0
restrict default nomodify notrap nopeer noquery Параметры указывают на то, что клиентам данного сервиса времени запрещено изменять его настройки, получать его статус. Они могут только забрать с него значения точного времени.
disable monitor Данный параметр повышает безопасность, предотвращая использования одной из уязвимостей сервиса ntpd, которую можно использовать для проведения DDoS атак.
logfile Указывает путь к файлу с логами сервиса

После завершения редактирования файла настроек запускаем службу синхронизации времени:

Проверяем запустился ли сервер:

Все в порядке, служба слушает положенный порт 123. Проверим еще на всякий случай системные логи centos:

Все в порядке, сервер запущен и полностью готов к работе.

Теперь настроим автозапуск ntp вместе с загрузкой centos:

Наблюдать за работой службы ntp можно с помощью команды ntpq -p:

Что значат все эти данные:

remote Адрес удаленного эталона времени, с которого была синхронизация
refid Указывает, откуда каждый эталон получает точное время. Это могут быть другие сервера времени, система GPS и другое
st Stratum (уровень) это число от 1 до 16, которое указывает на точность эталона. 1- максимальная точность, 16 — сервер недоступен. Уровень вашего сервера будет равен уровню наименее точного удаленного эталона плюс 1.
poll Интервал в секундах между опросами
reach Восьмеричное представление массива из 8 бит, отражающего результаты последних восьми попыток соединения с эталоном. Бит выставлен, если удаленный сервер ответил.
delay Время задержки ответа на запрос о точном времени
offset Разница между вашим и удаленным сервером
jitter Дисперсия (Jitter) — это мера статистических отклонений от значения смещения (поле offset) по нескольким успешным парам запрос-ответ. Чем меньше значение дисперсии, тем лучше, поскольку позволяет точнее синхронизировать время.

Настройка часового пояса в linux

1. Ссылка /etc/localtime

Наиболее популярный и поддерживаемый в большинстве дистрибутивов способ установки часового пояса для всех пользователей — с помощью символической ссылки /etc/localtime на файл нужного часового пояса. Список доступных часовых поясов можно посмотреть командой:

Сначала создайте резервную копию текущего часового пояса:

Для создания символической ссылки используйте команду ln -sf. Файл зоны нужно выбрать из доступных в системе. Например, мой часовой пояс — Украина, Киев, для установки будет использоваться следующая команда:

Теперь можете проверить текущее системное время с помощью утилиты date:

Если у вас установлена утилита rdate можно синхронизировать время с сетью:

Осталось только синхронизировать ваши аппаратные часы с новыми настройками, для этого выполните команду:

Если нужно изменить часовой пояс только для определенной программы или скрипта, просто измените для нее переменную окружения TZ, например:

Эта настройка сохраняется только для текущего сеанса командной оболочки. Чтобы сменить часовой пояс linux для определенного пользователя тоже нужно использовать переменную среды TZ. Только ее нужно добавить в файл ~/.environment. Этот файл читается по умолчанию при входе в систему, а значит переменная будет доступна всем программам:

Готово, теперь вы знаете как выполняется настройка часового пояса linux для определенного пользователя.

2. Настройка с помощью tzdata

Если вы не хотите использовать описанный выше способ, можно воспользоваться специальными утилитами. Вот только в разных дистрибутивах используются свои утилиты. Рассмотрим варианты для самых популярных дистрибутивов.

В Red Hat Linux:

В CentOS и Fedora:

В Slackware или FreeBSD:

В Ubuntu:

В большинстве случаев вы увидите подобное диалоговое окно:

Здесь просто нужно выбрать нужный часовой пояс и нажать кнопку Enter. После этого для окончательного применения настроек нужно будет перезагрузить систему.

3. Настройка с помощью systemd

В systemd есть своя утилита для настройки даты и часового пояса. Чтобы узнать текущее состояние выполните:

Для просмотра всех доступных временных зон выполните такую команду:

А для установки нужного часового пояса используйте команду set-timezone, например, тот же Europe/Kiev:

4. Настройка часового пояса в GUI

В дистрибутиве Ubuntu и других, использующих Gnome, настройка часового пояса Linux может быть выполнена прямо в параметрах системы. Для этого выберите пункт Сведения о системе, затем Дата и время, выберите свое местоположение на карте, или наберите название для поиска в поле ввода:

В KDE аналогично можно установить часовой пояс в настройках системы. Запустите утилиту настроек, откройте пункт Локализация, перейдите в раздел Дата и время, а затем откройте вкладку Часовой пояс:

Остается выбрать часовой пояс в списке и нажать кнопку Применить. Здесь уже изменения должны проявиться моментально.

ARG против ENV

1) Краткое пояснение: ARG доступен только во время сборки образа Docker (RUN и т. д.), но не после создания образа и запуска из него контейнеров (ENTRYPOINT, CMD).

Для контейнеров доступны значения ENV , а также команды в стиле RUN во время сборки Docker, начиная со строки, в которой они введены. Если вы установите переменную среды в промежуточном контейнере с помощью bash (RUN export VARI = 5 &&…), она не сохранится в следующей команде.

2) Более подробное объяснение: ARG также известны как переменные времени сборки. Они доступны только с момента «объявления» в Dockerfile с помощью инструкции ARG до момента создания образа. Запущенные контейнеры не могут получить доступ к значениям переменных ARG. Это также относится к инструкциям CMD и ENTRYPOINT, которые просто говорят, что контейнер должен запускаться по умолчанию. Если вы укажете Dockerfile ожидать различные переменные ARG (без значения по умолчанию), но при запуске команды сборки они не будут предоставлены, появится сообщение об ошибке.

Однако значения ARG можно легко проверить после создания образа, просмотрев историю Docker для образа. Таким образом, они не подходят для конфиденциальных данных.

Переменные ENV также доступны во время сборки, как только вы вводите их с помощью инструкции ENV. Однако, в отличие от ARG, они также доступны из контейнеров, запускаемых из финального образа. Значения ENV можно переопределить при запуске контейнера, подробнее об этом ниже.

3) С диагремом: Вот упрощенный обзор возможностей ARG и ENV в процессе создания образа Docker из файла Docker и запуска контейнера.

Они перекрываются, но ARG нельзя использовать изнутри контейнеров.

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Мой редактор ОС
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: