Compose: Как `docker-compose up --force-воссоздать` без повторного использования предыдущих томов

Созданный на 2 окт. 2015  ·  23Комментарии  ·  Источник: docker/compose

С docker-compose 1.4.2 и docker 1.8.2
Ниже вы можете увидеть, что первый том e583c6a8 ... 5a93788a0 используется повторно

 $ sudo docker-compose up -d --force-recreate
   Recreating remotetransmission_torrent_1...

 $ docker inspect remotetransmission_torrent_1 | grep volumes
   "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data:/home/transmission/.config/transmission-daemon:rw",
   "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data:/home/transmission/Downloads:rw"
   "Source": "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data",
   "Source": "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data",

 $ sudo docker-compose up -d --force-recreate
   Recreating remotetransmission_torrent_1...

 $ docker inspect remotetransmission_torrent_1 | grep volumes
   "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data:/home/transmission/.config/transmission-daemon:rw",
   "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data:/home/transmission/Downloads:rw"
   "Source": "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data",
   "Source": "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data",

Я вынужден stop затем rm чтобы создать новые тома

 $ sudo docker-compose stop 
   Stopping remotetransmission_torrent_1... done

 $ sudo docker-compose rm
   Going to remove remotetransmission_torrent_1
   Are you sure? [yN] y
   Removing remotetransmission_torrent_1... done

 $ sudo docker-compose up -d --force-recreate
   Creating remotetransmission_torrent_1...

 $ docker inspect remotetransmission_torrent_1 | grep volumes
   "Source": "/mnt/docker/volumes/c5bb9a8f7b68c762c42e9c0ee92afbca3aa0d7ff9d09aaf45fd260f6fc663ec9/_data",
   "Source": "/mnt/docker/volumes/9dcce8440bafc8893e07352111d1aefb625c36df10da6dc4eaa593220266ea31/_data",

_
Есть ли способ лучше, чем метод stop/rm ?

areup kindocs kinquestion

Самый полезный комментарий

Эта политика, похоже, нарушает передовые методы работы с докерами и вызвала у нас тонны головной боли по устранению неполадок, почему при воссоздании контейнеров происходила утечка состояния. Когда я говорю докеру, что нужно воссоздать, это не означает «сохранять некоторые данные во время выполнения контейнеров, но перезапускать процессы в контейнерах». Это значит вымостить землю и начать все сначала. Если бы я хотел сохранить тома, я бы явно монтировал тома. Я _ никогда_ не ожидаю, что автоматически смонтированные тома любого типа сохранятся при запуске контейнера.

Все 23 Комментарий

stop/rm - правильный путь. Данные в томах могут быть важны, поэтому мы хотим, чтобы их случайно не удалили.

Возможно, мы могли бы задокументировать это немного лучше.

Эта политика, похоже, нарушает передовые методы работы с докерами и вызвала у нас тонны головной боли по устранению неполадок, почему при воссоздании контейнеров происходила утечка состояния. Когда я говорю докеру, что нужно воссоздать, это не означает «сохранять некоторые данные во время выполнения контейнеров, но перезапускать процессы в контейнерах». Это значит вымостить землю и начать все сначала. Если бы я хотел сохранить тома, я бы явно монтировал тома. Я _ никогда_ не ожидаю, что автоматически смонтированные тома любого типа сохранятся при запуске контейнера.

Сохранение данных между прогонами - действительно единственная причина использовать тома. Если вам не нужны постоянные данные, почему вы помещаете их в том?

Я не настраиваю громкость. В моем docker-compose.yml нет настроек томов, и я не передаю ничего docker-compose.yml для присоединения каких-либо томов.

Команда:

docker-compose up --force-recreate --abort-on-container-exit --build foo

docker-compose.yml:

version: '2'
services:
  foo:
    build:
      context: .
      dockerfile: src/integration/foo/Dockerfile
    ports:
      - "3306:3306"
      - "33060:33060"

Dockerfile:

FROM mysql:5.7

COPY schema/foo/migration.sql /data/db_schema.sql
COPY src/integration/foo/create_test_db.sh /docker-entrypoint-initdb.d/create_test_db.sh
ENV MYSQL_ALLOW_EMPTY_PASSWORD true

EXPOSE 3306 33060

create_test_db.sh:

#!/bin/bash
set -e
mysql --no-defaults -u root -e "drop database if exists agent_state; create database foo"
mysql --no-defaults -u root foo < "/data/db_schema.sql"

Если я запустил вышеуказанное, напишу что-нибудь в БД, затем SIG_INT, затем снова запустите команду, данные, которые я поместил в БД, сохраняются во время выполнения.

Это проблема с образом MySQL. Создает объем в основе
образ. Вы можете обойти проблему, используя другой MySQL
изображение или, возможно, заставив его использовать другой путь для данных.

19 октября 2016 г. в 18:36 «Мика Золту» [email protected] написал:

Я не настраиваю громкость. В моем docker-compose.yml нет
настройки томов, и я ничего не передаю в docker-compose.yml в
прикрепить любые тома.

Команда:

docker-compose up --force -create --abort-on-container-exit --build foo

docker-compose.yml:

версия: '2'
Сервисы:
foo:
сборка:
контекст:.
dockerfile: SRC / интеграция / foo / Dockerfile
порты:
- «3306: 3306»
- «33060: 33060»

Dockerfile:

ИЗ mysql: 5.7

Копировать схему / foo / migration.sql /data/db_schema.sql
КОПИРОВАТЬ src / integration / foo / create_test_db.sh /docker-entrypoint-initdb.d/create_test_db.sh
ENV MYSQL_ALLOW_EMPTY_PASSWORD истина

EXPOSE 3306 33060

create_test_db.sh:

! / bin / bash

set -e
mysql --no-defaults -u root -e "удалить базу данных, если существует agent_state; создать базу данных foo"
mysql --no-defaults -u root foo <"/data/db_schema.sql"

Если я запустил вышеупомянутое, напишу что-нибудь в БД, затем SIG_INT, затем запустите
команда снова данные, которые я помещаю в БД, сохраняются во время выполнения.

-
Вы получили это, потому что оставили комментарий.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/docker/compose/issues/2127#issuecomment -254986952,
или отключить поток
https://github.com/notifications/unsubscribe-auth/AAa_RG_pJj0i-OSCfcBlG__8ToFDtGKMks5q1sWlgaJpZM4GHruC
.

Хм, это нарушает мое понимание докер-контейнеров. Как монтировать том без указания пути на хосте? Насколько я понимаю, контейнеры докеров эфемерны, если вы явно не монтируете том?

Тому не нужен путь к хосту. Есть три вида томов:

  • крепления для привязки хоста ( -v /host:/container )
  • именованные тома ( -v name:/container , созданные с помощью docker volume create )
  • анонимные тома ( -v /container или VOLUME внутри Dockerfile )

Образ mysql использует анонимный том. Во время выполнения вы можете указать контейнеру использовать другой том для этого пути в контейнере, но если вы этого не сделаете, анонимный том все еще существует.

Анонимные тома невелики. Они самые старые из трех, и большая часть их поведения является устаревшей, которая сохраняется только для целей обратной совместимости.

Хотелось бы хоть какой-нибудь параметр командной строки а-ля "--recreate-volume" ...

Хорошо, ребята, вот о чем стоит подумать:

1) Я хочу перемонтировать свой общедоступный каталог Rails в контейнер nginx, чтобы некоторые статические данные могли обслуживаться непосредственно nginx.
2) Я назначаю «анонимный» (не подключенный к хосту, не именованный) том в / usr / local / app / app / public и делюсь им с nginx через «volume_from»
3) "общедоступное" содержимое часто изменяется при сборке образов - не только файлы верхнего уровня, но и некоторые файлы в подкаталогах (это важно)

В настоящее время, если я воссоздаю контейнеры, я получаю старую версию «public» - содержимое изображения просто игнорируется. Да, Docker должен копировать отсутствующие файлы в анонимный том, но по разным причинам это не всегда происходит (подозреваю, что нет глубокой проверки структуры подкаталогов).

Итак, я либо вынужден выполнить последовательность «stop-rm-up» (что не так удобно в производственной среде), либо использовать отдельный каталог в качестве общего тома и явно вызывать 'rsync' при запуске контейнера приложения, чтобы заполнить / обновить его.

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

Не используйте тома для кода (или статических активов). Тома предназначены для данных, которые вы хотите сохранить между развертываниями, что противоположно тому, что вы хотите здесь. Либо создайте образ nginx со статическими активами, либо проксируйте некоторый контейнер веб-сервера, который их содержит.

Спасибо за точку зрения! Я еще не думал с этой точки зрения.

Похоже, это одна из концептуальных проблем (все еще развивающейся) архитектуры Docker. До сих пор мы видели эволюцию концепции томов данных (например, от «контейнеров данных» к «именованным томам»), и, вероятно, это еще не закончено.

Если вы посмотрите https://docs.docker.com/engine/tutorials/dockervolumes/#/data -volumes, вы увидите, что большинство описанных преимуществ (обход AUFS, совместное использование) не обязательно связаны с сохранением данных ( для которых изначально были разработаны тома).

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

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

Еще раз спасибо за ваш ответ, разъяснения и за отличную работу, которую вы делаете!

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

Существенной проблемой для меня было понимание того, что тег VOLUME в файле dockerfile вызывает создание согласованного анонимного тома. Возможно, я пропустил это в документации, но не нашел упоминания о нем.

@dnephin

Как уже упоминалось @ hleb-rubanau. Решение - запуск одного контейнера с Rails и Nginx? (Как это: https://docs.docker.com/engine/admin/multi-service_container/?)

Должен ли я нарушать лучшие практики ("Каждый контейнер должен иметь только одну проблему
") только для обслуживания активов? :(

Для желающих я получил следующее:

1) В моих настройках я теперь всегда использую тома, подключенные к привязке (также известные как подключенные к хосту). Анонимные и именованные тома имеют слишком много особой / неочевидной / условной / непоследовательной / непонятной логики, чтобы их можно было принять во внимание. Да, легко понять специфику жизненного цикла и управления каждого типа, но я обнаружил, что мне легче думать об архитектуре, когда меня не беспокоят все эти несущественные различия. Для распределенной FS Gluster работает нормально (с точки зрения Docker все еще монтируется на привязку).

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

Спасибо @ hleb-rubanau

В любом случае, я не уверен, что некоторые инструменты оркестровки, такие как RancherOS, поддерживают эти конфигурации тома или являются правильным способом масштабирования. В конце концов, с докером сложнее развернуть ...

Я предпочитаю использовать анонимные тома и в какой-то момент убирать сирот.

Это мой стек производственных рельсов: https://github.com/brunocascio/AR-MTB/blob/master/docker-compose.prod.yml

Это также вызвало у меня _существенную_ путаницу, когда я тестировал образ jenkins / jenkins, и он не соблюдал мои изменения из файлов в / usr / share / jenkins / ref, потому что он уже скопировал их.

Это довольно неожиданный пользовательский опыт - docker compose создает «скрытый» том для всех намерений и целей. Если вы используете обычный docker run то каждый раз вы получаете новый том. Это скрытый том в том смысле, что ничего в docker-compose up говорится об этом, поэтому, если вы не знаете подробно, что делает изображение, вам придется копать.

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

Привет @dnephin!

Я вызываю sudo rm -rf /var/lib/docker/volumes/aa_dbdatavol и теперь я больше не могу docker-compose up my postgres docker-compose .

Получение этой ошибки

Создание сети "aa_default" с драйвером по умолчанию
Создание aa_postgres_1
ОШИБКА: для postgres невозможно создать контейнер для службы postgres: нет такого файла или каталога
ОШИБКА: обнаружены ошибки при запуске проекта.
Ответ об ошибке от демона: Нет такого контейнера: aa_postgres_1

Если у вас есть идея, как это обойти, поделитесь, пожалуйста. Спасибо!

https://github.com/docker/compose/issues/2127#issuecomment -347152650

Просто воссоздание папки решит мою проблему.
/var/lib/docker/volumes/aa_dbdatavol/_data

Большое спасибо @dnephin , ваш ответ сработал отлично, в первый раз. Muchos gracias.

@dnephin сказал:

Сохранение данных между прогонами - действительно единственная причина использовать тома. Если вам не нужны постоянные данные, почему вы помещаете их в том?

для обмена файлами между контейнерами. Есть ли лучший способ сделать это без использования томов?

Что вы имеете в виду под «обмениваться файлами»?

Ожидаете ли вы, что один контейнер будет записывать в файл, а другой - видеть эти записи? Файловая система обычно не является хорошим интерфейсом между двумя службами, но в этом случае одна из служб может «управлять» файловой системой, записывая обновления на том.

Если «совместное использование» означает, что два контейнера читают одни и те же файлы, тогда нет необходимости в томе. Добавьте файл в оба контейнера с помощью COPY .

Я использую Docker version 18.06.1-ce, build e68fc7a и могу использовать следующую команду для воссоздания анонимных томов:

docker-compose up -d --build --force-recreate --renew-anon-volumes db

Кажется, недавно был добавлен флаг --renew-anon-volumes

Я использую Docker version 18.06.1-ce, build e68fc7a и могу использовать следующую команду для воссоздания анонимных томов:

docker-compose up -d --build --force-recreate --renew-anon-volumes db

Кажется, недавно был добавлен флаг --renew-anon-volumes

Спасибо, что предоставили эту возможность.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги