#docker #docker-compose #mount #nfs
#docker #docker-compose #смонтировать #nfs
Вопрос:
Суть этого вопроса заключается в том, чтобы заставить docker-compose ждать запуска контейнера mysql до тех пор, пока не будет смонтирована файловая система хоста. В моем случае файловая система хоста содержит файлы базы данных mysql.
Для служб, зависящих от контейнера mysql, существуют сценарии, такие как wait-for-it, которые выполняются как часть точки входа контейнера. Эти скрипты проверяют доступность служб на сетевых портах. Но я не вижу, как заставить запуск контейнера ждать, пока файловая система будет смонтирована на хосте.
При загрузке хоста файловые системы NFS и RAID могут загружаться не так быстро, как запускаются контейнеры. Если файловая система монтируется на хосте после запуска контейнера, связанный том в контейнере не обновляется. Тогда контейнер в конечном итоге не имеет доступа к смонтированной / связанной файловой системе.
Комментарии:
1. Предполагая, что ваша система использует systemd (что довольно распространено), решение состоит в том, чтобы сделать
docker
службу зависимой от соответствующего.mount
модуля для файловой системы. Это предотвратит запуск docker до монтирования файловой системы. Например, как описано здесь .2. Отличный ответ @larsks. Я предполагаю , что вы имеете в виду добавить
mnt-mountpoint.mount
в конецAfter
строки/lib/systemd/system/docker.service
. Я протестировал, размонтировав файловую систему, затем остановив и запустив демон docker. К сожалению, все контейнеры запускались с отключенной файловой системой. Затем я протестирую перезагрузку.3. Более тщательное прочтение связанного вопроса показало, что мне также нужно было добавить
mnt-mountpoint.mount
к этойRequires
строке. Теперь служба docker отказывается запускаться, если файловая система не смонтирована. @larsks, пожалуйста, опубликуйте свой ответ, чтобы я мог его принять.
Ответ №1:
Предполагая, что ваша система использует systemd (что довольно распространено), решение состоит в том, чтобы сделать службу docker зависимой от соответствующего модуля .mount для файловой системы. Это предотвратит запуск docker до монтирования файловой системы. Добавление зависимости от точки монтирования описано, например, в этом ответе над https://unix.stackexchange.com .
Для каждой файловой системы , указанной в /etc/fstab
, systemd генерирует единицу с именем <filesystem>.mount
. Например, в моей системе, в которой /etc/fstab
содержится, среди прочего:
/dev/tank/scratch /scratch xfs defaults 1 2
Я вижу следующий системный блок:
# systemctl list-units -t mount |grep scratch
scratch.mount loaded active mounted /scratch
Мы можем сделать такую службу, как Docker, зависимой от этой точки монтирования, добавив что-то вроде следующего в [Unit]
раздел модуля:
[Unit]
Requires=scratch.mount
After=scratch.mount
Requires
Директива означает «когда вы запускаете эту службу (например docker
), также запускайте перечисленные здесь устройства», а After
директива означает «запускайте именованные устройства перед этим».
Комментарии:
1. Я считаю, что это правильный ответ, но, к сожалению, он не работает у меня во время загрузки системы. Я думаю, это потому, что в systemd есть ошибка 4-летней давности, связанная именно с этим шаблоном использования. Мне трудно понять, как такая утилита, как systemd, используемая миллионами (?) хостов Linux, может иметь такую ошибку. Будут оценены предложения по обходным путям. Моя система Ubuntu 18 работает под управлением systemd версии 237.
2. Ах, облом, я думал, ты указал, что это работает. Я рассмотрю подробнее, когда у меня будет немного свободного времени завтра.
3. Спасибо. Это работает, когда вы останавливаете и запускаете демон docker после загрузки, но не как часть процесса загрузки.
Ответ №2:
Сервис самого низкого уровня — это mysql. Измените его точку входа, чтобы завершить работу, если каталог, который, как известно, находится в смонтированной файловой системе, отсутствует.
Все зависимые службы могут использовать сценарии dockerize или wait-for-it, которые ожидают открытия сетевого порта mysql.
mysql:
image: mysql:5.7.30
restart: always
entrypoint: ["bash", "-c", "touch /testdir/dir_on_filesystem/write-test amp;amp; rm /testdir/dir_on_filesystem/write-test amp;amp; echo 'Test for mounted filesystem passed' amp;amp; mysqld --user=root"]
volumes:
- /mnt/mountpoint/mysql:/var/lib/mysql
- /mnt/mountpoint:/testdir
Если вы можете гарантировать, что /mnt/mountpoint/mysql
он существует в файловой системе до первого запуска контейнера mysql, тогда вы можете использовать этот каталог для теста вместо /testdir/dir_on_filesystem
.
Обратите внимание, что этот тест точки входа также гарантирует, что файловая система не смонтирована только для чтения. Когда RAID-массив повторно синхронизируется во время загрузки системы, он может запускаться в состоянии только для чтения, пока не будет достигнут некоторый прогресс в повторной синхронизации. Проверка возможности записи не является строго необходимой, поскольку контейнер mysql завершит работу, если он не сможет выполнить запись в свои файлы базы данных.