Как работать с постоянным хранилищем (например, базами данных) в Docker
как люди справляются с постоянным хранением для ваших контейнеров Docker?
в настоящее время я использую этот подход: создайте образ, например, для PostgreSQL, а затем запустите контейнер с
docker run --volumes-from c0dbc34fd631 -d app_name/postgres
IMHO, что имеет недостаток, что я никогда не должен (случайно) удалить контейнер "c0dbc34fd631".
другой идеей было бы смонтировать Тома хоста "- v " в контейнер, однако,userid внутри контейнера не обязательно совпадение userid от хоста, а затем разрешения могут быть перепутаны.
Примечание: вместо --volumes-from 'cryptic_id' вы также можете использовать --volumes-from my-data-container здесь my-data-container - это имя, присвоенное контейнеру только для данных, например docker run --name my-data-container ... (см. принятый ответ)
14 ответов:
настройки 1.9.0 и выше
использовать volume API
docker volume create --name hello docker run -d -v hello:/container/path/for/volume container_image my_commandэто означает, что шаблон контейнера только для данных должен быть оставлен в пользу новых томов.
на самом деле API Тома-это только лучший способ достичь того, что было шаблоном контейнера данных.
если вы создаете контейнер с
-v volume_name:/container/fs/pathDocker автоматически создаст для вас именованный том, который может:
- перечислите до конца элемент
docker volume ls- быть идентифицированы через
docker volume inspect volume_name- резервное копирование в обычный каталог
- резервное копирование, как и раньше через
--volumes-fromподключениеновый API Тома добавляет полезную команду, которая позволяет идентифицировать висячие Тома:
docker volume ls -f dangling=trueи затем удалить его через его имя:
docker volume rm <volume name>как подчеркивает @mpugach в комментариях, вы можете избавиться от всех висячих томов с хорошим один-лайнер:
docker volume rm $(docker volume ls -f dangling=true -q) # Or using 1.13.x docker volume pruneДокер 1.8.X и ниже
подход, который, кажется, лучше всего подходит для производства, заключается в использовании контейнер только для данных.
контейнер только для данных запускается на изображении barebones и фактически ничего не делает, кроме предоставления тома данных.
затем вы можете запустить любой другой контейнер, чтобы иметь доступ к контейнерооборота данные:
docker run --volumes-from data-container some-other-container command-to-execute
- здесь вы можете получить хороший изображение как аранжировать различные контейнеры.
- здесь существует хорошее представление о том, как работают Тома.
на этот блог есть хорошее описание так называемого контейнер как шаблон объема что проясняет главный момент наличия контейнеры только для данных.
документация Docker теперь имеет окончательное описание контейнер volume / s узор.
Ниже приведена процедура резервного копирования/восстановления для Docker 1.8.X и ниже.
резервное копирование:
sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
- --rm: извлеките контейнер, когда он выйдет
- --volumes-from DATA: прикрепление к томам, совместно используемым контейнером данных
- - v $(pwd):/backup: bind монтирует текущий каталог в контейнер; чтобы записать файл tar в
- busybox: немного проще хороший для быстрого обслуживания
- tar cvf / backup / резервное копирование.tar / data: создает несжатый tar-файл из всех файлов в каталоге /data
восстановить:
# Create a new data container $ sudo docker run -v /data -name DATA2 busybox true # untar the backup files into the new container᾿s data volume $ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar data/ data/sven.txt # Compare to the original container $ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data sven.txtвот хороший статья от превосходного Брайана Гоффа объясняя, почему хорошо использовать одно и то же изображение для контейнера и контейнера данных.
In Docker release v1. 0, привязка монтирования файла или каталога на главной машине может быть выполнена с помощью данной команды:
$ docker run -v /host:/container ...вышеуказанный том может использоваться в качестве постоянного хранилища на хосте, на котором работает Docker.
начиная с Docker Compose 1.6, теперь улучшена поддержка томов данных в Docker Compose. Следующий файл compose создаст образ данных, который будет сохраняться между перезапусками (или даже удалением) родительских контейнеров:
вот это объявление в блог: Compose 1.6: новый файл Compose для определения сетей и томов
вот пример создания файла:
version: "2" services: db: restart: on-failure:10 image: postgres:9.4 volumes: - "db-data:/var/lib/postgresql/data" web: restart: on-failure:10 build: . command: gunicorn mypythonapp.wsgi:application -b :8000 --reload volumes: - .:/code ports: - "8000:8000" links: - db volumes: db-data:насколько я могу понять: это создаст контейнер тома данных (
db_data), который будет сохраняться между перезапусками.если вы запустите:
docker volume lsвы должны увидеть ваш объем указаны:local mypthonapp_db-data ...вы можете получить более подробную информацию об объеме данных:
docker volume inspect mypthonapp_db-data [ { "Name": "mypthonapp_db-data", "Driver": "local", "Mountpoint": "/mnt/sda1/var/lib/docker/volumes/mypthonapp_db-data/_data" } ]некоторые испытания:
# Start the containers docker-compose up -d # .. input some data into the database docker-compose run --rm web python manage.py migrate docker-compose run --rm web python manage.py createsuperuser ... # Stop and remove the containers: docker-compose stop docker-compose rm -f # Start it back up again docker-compose up -d # Verify the data is still there ... (it is) # Stop and remove with the -v (volumes) tag: docker-compose stop docker=compose rm -f -v # Up again .. docker-compose up -d # Check the data is still there: ... (it is).Примечания:
вы также можете указать различные драйверы в
volumesблок. Например, можно указать драйвер Flocker для db_data:volumes: db-data: driver: flocker- поскольку они улучшают интеграцию между Docker Swarm и Docker Compose (и, возможно, начинают интегрировать Flocker в экосистему Docker (я слышал слух, что Docker купил Flocker), я думаю, что этот подход должен стать все более мощным.
отказ от ответственности: этот подход перспективен, и я успешно использую его в среде разработки. Я бы опасался использовать это в производстве просто еще бы!
в случае, если это не ясно из обновления 5 выбранного ответа, начиная с Docker 1.9, вы можете создавать тома, которые могут существовать без привязки к определенному контейнеру, что делает шаблон "только для данных" устаревшим.
посмотреть контейнеры только для данных устарели с docker 1.9.0? #17798.
Я думаю, что Docker maintainers поняли, что шаблон контейнера только для данных был немного дизайнерским запахом и решил сделать Тома a отдельная сущность, которая может существовать без соответствующего контейнера.
пока это еще часть Docker что нужно, вы должны поместить том в Dockerfile с инструкция по громкости поэтому вам не нужно копировать тома из другого контейнера.
это сделает ваши контейнеры менее взаимозависимыми, и вам не придется беспокоиться об удалении одного контейнера, влияющего на другой.
при использовании Docker Compose просто прикрепите именованный том, например,
version: '2' services: db: image: mysql:5.6 volumes: - db_data:/var/lib/mysql:rw environment: MYSQL_ROOT_PASSWORD: root volumes: db_data:
ответ@tommasop хорош и объясняет некоторые механики использования контейнеров только для данных. Но как кто-то, кто изначально думал, что контейнеры данных глупы, когда можно просто привязать том к хосту (как предлагается несколькими другими ответами), но теперь понимает, что на самом деле контейнеры только для данных довольно аккуратны, я могу предложить свой собственный блог по этой теме: Почему Контейнеры Данных Docker (Тома!) хороши
Читайте также: мой ответ на вопрос "каков (лучший) способ управления разрешениями для общих томов Docker? " для примера того, как использовать контейнеры данных, чтобы избежать таких проблем, как разрешения и сопоставление uid/gid с хостом.
чтобы решить одну из первоначальных проблем OP: что контейнер данных не должен быть удален. Даже если контейнер данных будет удален, сами данные не будут потеряны, пока любой контейнер имеет ссылку на этот том, т. е. любой контейнер, который смонтировал громкость через
--volumes-from. Поэтому, если все связанные контейнеры не будут остановлены и удалены (можно было бы считать это эквивалентом случайногоrm -fr /) данные в безопасности. Вы всегда можете воссоздать контейнер данных, выполнив--volumes-fromлюбой контейнер, который имеет ссылку на этот объем.как всегда, Сделайте резервные копии, хотя!
UPDATE: Docker теперь имеет Тома, которыми можно управлять независимо от контейнеров, что еще больше упрощает управление.
Если вы хотите переместить ваши Тома вокруг вы также должны смотреть на Flocker.
из README:
Flocker-это диспетчер томов данных и инструмент управления кластером докеров с несколькими хостами. С его помощью вы можете управлять своими данными, используя те же инструменты, которые вы используете для своих приложений без состояния, используя мощь ZFS на Linux.
Это означает, что вы можете запускать свои базы данных, очереди и хранилища значений ключей в Docker и перемещать их так же легко, как и остальные приложения.
существует несколько уровней управления постоянными данными, в зависимости от ваших потребностей:
- храните его на вашем хосте
- использовать флаг
-v host-path:container-pathдля сохранения данных-контейнер для размещения каталога.- резервное копирование / восстановление происходит путем запуска контейнера резервного копирования/восстановления (например, tutumcloud/dockup), подключенного к тому же каталогу.
- создайте контейнер данных и смонтируйте его Тома контейнер приложения
- создайте контейнер, который экспортирует объем данных, используйте
--volumes-fromдля подключения этих данных в контейнер приложения.- резервное копирование / восстановление то же самое, что и выше решение.
- используйте плагин Docker volume, который поддерживает внешнюю / стороннюю службу
- Плагины Docker volume позволяют вашему источнику данных поступать из любого места-NFS, AWS (S3, EFS и EBS)
- в зависимости от плагин / сервис, вы можете прикрепить один или несколько контейнеров к одному тому.
- в зависимости от службы, резервное копирование/восстановление может быть автоматизировано для вас.
- хотя это может быть затруднительно делать вручную, некоторые решения оркестровки, такие как фермер - он запекается и прост в использовании.
- автоколонны это самое простое решение для этого вручную.
Это зависит от вашего сценария (это действительно не подходит для производственной среды), но вот один из способов:
создание контейнера MySQL Docker
эта суть заключается в использовании каталога на вашем хосте для сохранения данных.
недавно я писал о потенциальном решении и приложении, демонстрирующем технику. Я считаю, что это довольно эффективно во время разработки и в производстве. Надеюсь, это поможет или искры некоторые идеи.
РЕПО: https://github.com/LevInteractive/docker-nodejs-example
Article: http://lev-interactive.com/2015/03/30/docker-load-balanced-mongodb-persistence/
Я просто использую предопределенный каталог на хосте для сохранения данных для PostgreSQL. Кроме того, таким образом можно легко перенести существующие установки PostgreSQL в контейнеры Docker:https://crondev.com/persistent-postgresql-inside-docker/
мое решение-использовать новый
docker cp, который теперь может копировать данные из контейнеров, независимо от того, работает он или нет, и совместно использовать том хоста в том же месте, где приложение базы данных создает свои файлы базы данных внутри контейнера. Это двойное решение работает без контейнера только для данных, прямо из исходного контейнера базы данных.Итак, мой сценарий инициализации systemd выполняет задание резервного копирования базы данных в архив на хосте. Я поместил метку времени в имя файла, чтобы никогда не переписывать файл.
Он делает это на ExecStartPre:
ExecStartPre=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql ExecStartPre=-/bin/bash -c '/usr/bin/tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStartPre.tar.gz /home/core/sql/mysql --remove-files'и он делает то же самое на ExecStopPost тоже:
ExecStopPost=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql ExecStopPost=-/bin/bash -c 'tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStopPost.tar.gz /home/core/sql/mysql --remove-files'плюс я выставил папку с хоста в качестве Тома в том же месте, где хранится база данных:
mariadb: build: ./mariadb volumes: - $HOME/server/mysql/:/var/lib/mysql/:rwон отлично работает на моей виртуальной машине (я строю стек LEMP для себя):https://github.com/DJviolin/LEMP
но я просто не знаю, является ли это" пуленепробиваемым " решением, когда ваша жизнь зависит от него на самом деле (например, интернет-магазин с транзакциями в любые возможные миллисекунды)?
в 20 минут 20 секунд от этого официального видео Docker keynote, ведущий делает то же самое с базой данных:
" для базы данных у нас есть Том, так что мы можем убедиться, что, как база данных идет вверх и вниз, мы не теряем данные, когда контейнер базы данных остановился."
используйте постоянное утверждение Тома (PVC) от Kubernetes, которое является инструментом управления и планирования контейнеров Docker:
преимущества использования Kubernetes для этой цели заключаются в следующем:
- вы можете использовать любое хранилище, такое как NFS или другое хранилище, и даже когда узел не работает, хранилище не должно быть.
- кроме того, данные в таких томах могут быть настроены для сохранения даже после сам контейнер разрушается - так что он может быть возвращен, если это необходимо, другим контейнером.
Comments