Docker Swarm игнорирует команды VOLUME из Dockerfiles? - PullRequest
1 голос
/ 15 мая 2019

Развертываем стек, составляем список файлов двух сервисов:

  • * 1004 MediaWiki *
  • MYSQL

Мы видели, что MySQL Dockerfile имеет директиву VOLUME , чтобы сохранить базы данных на томе Docker

Тем не менее, если мы docker stack rm затем docker stack deploy создадим наш файл, мы потеряем все содержимое базы данных.

Это ожидаемое поведение? Что было бы для этого обоснованием?

Ответы [ 3 ]

2 голосов
/ 15 мая 2019

Режим Swarm не создает образы Docker, поэтому можно с уверенностью сказать, что Docker Swarm игнорирует каждую строку вашего Dockerfile. Полученное изображение будет иметь идентифицированный том, который будет создан при запуске контейнера, будь то внутри или вне режима роя. Если вы не укажете монтирование тома во время выполнения, докер предоставит вам анонимный том в этом месте, который будет сложно определить позже, и локальный для узла, на котором работает контейнер. С новым стеком предыдущий анонимный том не будет использоваться, и в различных ситуациях анонимный том может быть автоматически удален (например, когда контейнеры настроены на автоматическое удаление при выходе, что я не уверен, применимо ли это к рою) режим).

Именованный том может упростить повторное использование данных в кластере с одним узлом. Когда вы попадаете в многоузловой кластер, вам нужно переместить эти данные из узла, в котором работает контейнер. Подробнее о том, как использовать что-то вроде NFS для внешнего хранения данных, см. этот ответ на связанный вопрос.

1 голос
/ 15 мая 2019

Нахождение в режиме роя в этом случае не имеет значения.

Если вы полагаетесь только на анонимный том, определенный в Dockerfile, при запуске нового контейнера будет создан и смонтирован новый свежий том.Вам нужно специально смонтировать именованный том при запуске контейнера (в вашем случае добавьте его в файл compose), чтобы перемонтировать один и тот же том между запусками.

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

Я сыграл следующий сценарий, чтобы проиллюстрировать свою точку зрения:

Сначала получите изображение и посмотрите:

$ docker pull mysql:latest
$ docker image inspect mysql:latest

Из этой последней команды мы видим, что объявляется том для /var/lib/mysql

Я на моей машине разработчика.Вычистил все, поэтому у меня нет томов на данный момент

$ docker volume ls
DRIVER              VOLUME NAME
$

Запустите контейнер, затем посмотрите на тома снова

$ docker run -d --name test -e MYSQL_ALLOW_EMPTY_PASSWORD=1 mysql:latest 
37a92341f52b189d00636d1f03ecfbd4e3e7e5d55b685f5ec254971d7732566c
$ docker volume ls
DRIVER              VOLUME NAME
local               50f9810d13271c7c91b7e025e139db480f288a936f0a55f85d9580ef3aa83af7

Теперь добавьте некоторые данные в контейнер

$ docker exec -it test bash
root@37a92341f52b:/# mysql
Welcome to the MySQL monitor.  [... snip ...]
mysql> create database testso;
Query OK, 1 row affected (0.03 sec)
mysql> use testso;
Database changed
mysql> create table test (id int not null primary key);
Query OK, 0 rows affected (0.08 sec)
mysql> insert into test values (1);
Query OK, 1 row affected (0.05 sec)
mysql> select * from test;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

mysql> exit
Bye
root@37a92341f52b:/# exit
$ 

Создайте новый контейнер

$ docker rm -f test
test
$ docker run -d --name test -e MYSQL_ALLOW_EMPTY_PASSWORD=1 mysql:latest
79148de09d7a3e13db338da133cfd7d44fe3590dc1c7ffe6129722c5c6baea21
$ docker volume ls
DRIVER              VOLUME NAME
local               50f9810d13271c7c91b7e025e139db480f288a936f0a55f85d9580ef3aa83af7
local               ef6fb2647c11c10ef98d25ca0dc2bd43231729ed18386c65768a0ad808fca93b

Как видите, у нас есть второй том для нового контейнера.Я не буду показывать это здесь, но если я подключусь, данные будут пустыми, как в вашем случае.Теперь давайте попробуем восстановить.

Сначала небольшая очистка

$ docker rm -f test
test
$ docker volume rm ef6fb2647c11c10ef98d25ca0dc2bd43231729ed18386c65768a0ad808fca93b
ef6fb2647c11c10ef98d25ca0dc2bd43231729ed18386c65768a0ad808fca93b

Мы хотим иметь удобочитаемое имя, но не можем переименовать том.То, что я сделал, это подключил старый и новый именованный том в контейнер busybox для передачи данных.

$ docker run -it --rm -v 50f9810d13271c7c91b7e025e139db480f288a936f0a55f85d9580ef3aa83af7:/mysql/old -v mysql_data:/mysql/new busybox:latest 
/ # cd /mysql/
/mysql # mv old/* new/
/mysql # exit

Теперь у нас есть этот новый том, и мы можем избавиться от анонимного

$ docker volume ls
DRIVER              VOLUME NAME
local               50f9810d13271c7c91b7e025e139db480f288a936f0a55f85d9580ef3aa83af7
local               mysql_data
$ docker volume rm 50f9810d13271c7c91b7e025e139db480f288a936f0a55f85d9580ef3aa83af7
50f9810d13271c7c91b7e025e139db480f288a936f0a55f85d9580ef3aa83af7

И, наконец, мы перемонтируем именованный том в новый контейнер mysql, чтобы вернуть наши данные

$ docker run -d --name test -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -v mysql_data:/var/lib/mysql mysql:latest
3f6eff0b7660f3f8e9518564affc6555acb17184845156099d18300b3e76f4a2
$ docker exec -it test bash
root@3f6eff0b7660:/# mysql
Welcome to the MySQL monitor.  [... snip ...]

mysql> use testso
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from test;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.01 sec)
1 голос
/ 15 мая 2019

В Dockerfile есть том, но вы, вероятно, не смонтировали этот том как доступный за пределами этого контейнера, что означает, что он, вероятно, не извлекается в постоянное оверлейное хранилище для совместного использования между контейнерами / развертываниями контейнеров.

В вашей службе базы данных в файле docker-compose.yml вам понадобится раздел volumes. Я опускаю ваши текущие настройки, так как вы не предоставили их, и я собираюсь заменить их на эллипсы ....

mySQL:
  ...
  volumes:
    - mySQL-data:/var/lib/mysql

Это говорит системе, что вы хотите сохранить каталог /var/lib/mysql вне контейнера в вашем общем оверлее, которое я случайно назвал mySQL-data.

...