Docker: резервное копирование и восстановление
Очень частые вопросы, которые возникают в процессе использования Docker.
- Как делать резервное копирование Docker контейнеров?
- Как делать резервное копирование Docker образов?
- Как делать резервное копирование СУБД (MySQL, Redis, MongoDB и т.д.), работающей внутри контейнера?
- Как правильно восстанавливать Docker контейнеры?
- Как правильно восстанавливать Docker образы?
Резервное копирование
Прежде чем переходить непосредственно к резервному копированию, необходимо определиться, что именно необходимо бекапить. На мой взгляд, имеет смысл бекапить:
- образы, если вы не используете какой-либо публичный или приватный Docker репозиторий
- работающие контейнеры, если по каким-либо причинам вы не подключили постоянные диски к директориям, данные которых вы изменяете
- постоянные диски со статичными данными, например, вашим web-приложением (исходный код приложения на python, php, go и т.д.)
Важно: постоянные диски с динамически изменяемыми данными, т.к. файлы СУБД бекапиться не должны. Резервное копирование данных ваших СУБД необходимо выполнять штатными средствами самой СУБД, т.к. при простом копировании данных такого диска очень легко получить их неконсистентность и невозможность восстановить работоспособность и данные СУБД в будущем.
Резервное копирование образов docker
Резервное копирование Docker образов делается при помощи двух команд:
docker save — сохраняет Docker образ в tar-архив с необходимым образом на вашей файловой системе
docker load — загружает Docker образ из tar-архива, делая его доступным в списке ваших локальных образов (команды docker images)
Пример использования
Предположим, что у вас уже есть образ, который необходимо забекапить. Если его еще нет, скачайте любой произвольный образ, например, busybox:
docker pull busybox:latest
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 7968321274dc 7 weeks ago 1.11 MB
Сохранение образа в tar-архив выполняется командой:
docker save -o busybox_latest.tar busybox:latest
Напомню, что :latest — это указание тега вашего образа. Вы можете использовать другой тег с произвольной версией, которым помечен ваш образ, например,
docker save -o busybox_1.26.1.tar busybox:1.26.1
Восстановление образа из tar-архива выполняется командой:
Удалите скачанный образ командой:
docker rmi 7968321274dc
И проверьте, что образ busybox отсутствует в выводе команды docker images.
Теперь можно восстановить образ командой:
docker load -i busybox_latest.tar
Образ busybox появился в выводе команды docker images.
Что делать с полученными tar-архивами
Т.к. хранение резервных копий системы на сервере с самой системой не допустимо, то предлагаю вам следующие варианты сохранения резервных копий:
- на отдельный физический или виртуальный сервер, специально выделенный под эти задачи
- на отдельную систему резервного копирования (например, EMC Avamar)
- на отдельное отказоустойчивое облачное объектное хранилище, т.к. объектное хранилище K2 CLOUD, AWS S3, GoogleDrive, DropBox и т.д.
Резервное копирование в репозиторий
Резервное копирование в удаленный публичный или приватный репозиторий — это наиболее распространенный способ резервного копирования образов контейнеров. Для этого используются команды:
docker login
docker push busybox
Резервное копирование контейнеров
При использовании Docker нужно помнить о двух типах данных, с которыми работают контейнеры, а именно:
- read-write слой, самого контейнера, создаваемый поверх слоев образа, из которого запущен контейнер
- постоянные Docker-диски
Соответственно, при планировании резервного копирования ваших Docker контейнеров необходимо не только учитывать особенности вашего приложения, но и особенности работы контейнеров с вышеуказанными типами данных.
Резервное копирование контейнеров
Под резервным копированием контейнера мы будем понимать резервное копирование именно данных самого контейнера вместе с его read-write слоем. В результате выполнения резервного копирования контейнера вы получаете образ контейнера, содержащий все изменения выполненные на файловой системе контейнера за исключением директорий, в которые смонтированы его постоянные диски.
После резервного копирования контейнера необходимо выполнить резервное копирование его образа (см. описание процесса выше).
Сохранение изменений, выполненных в контейнере
Для того, чтобы выполнить резервное копирование контейнера, необходимо сохранить в нем все изменения, выполненные на момент времени резервного копирования при помощи команды docker commit. Предположим, у вас имеется запущенный контейнер, в котором вы выполнили какие-либо изменения:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
78727078a04b busybox:latest "/bin/bash" 13 seconds ago Up 11 seconds container1
Сохраните изменения, выполненные в контейнере, при помощи команды docker commit:
docker commit -p 78727078a04b container1:0.0.1
e09f9ac65c8b3095927c14ca0594868f73831bde0800ce66415afeb91aea93cf
Данная команда создаст Docker образ с именем container1 и тегом 0.0.1. Проверить это можно командой docker images:
docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
container1 0.0.1 e09f9ac65c8b 39 seconds ago 125.1 MB
Далее образ container1 с тегом 0.0.1 может быть забекаплен одним из вышеперечисленных выше способом.
Резервное копирование постоянных дисков со статическим контентом
Резервное копирование статического контента, находящегося на постоянных диска Docker, может быть выполнено большим количеством разнообразных способов:
- путем создания tar-архива содержимого диска
- путем копирования содержимого диска на удаленный сервер при помощи, например, scp или rsync
- путем копирования содержимого диска на удаленное отказоустойчивое объектное хранилище
Здесь мы рассмотрим процесс создания tar-архива, содержащего данные диска. Остальные способы могут быть реализованы вами самостоятельно по аналогии. Суть метода заключается в том, чтобы запустить отдельный контейнер, подключив к нему диски контейнера, которые необходимо забекапить, и выполнить резервное копирование внутри созданного контейнера туда, куда необходимо.
Запуск контейнера с подключением к нему дисков уже работающего контейнера может быть выполнен командой:
docker run --rm --volumes-from my_backend_container -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /my_app_content
Данная команда запустит новый контейнер на базе ОС Ubuntu, к которому будут подключены все диски с контейнера my_backend_container, и они будут доступны по тем же путям, что и в том контейнере, резервное копирование которого вы производите. ОС не имеет значения, главное, чтобы внутри контейнера были все необходимые утилиты, которые будут выполнять резервное копирование. В директорию /backup будет смонтирован текущая директория вашего интерпретатора. Запускаемый Ubuntu контейнер выполнит команду архивирования директории /my_app_content (предполагается, что данные вашего постоянного диска смонтированы именно туда) в директорию /backup (текущая директория интерпретатора). По завершению данной операции эти данные необходимо скопированы на другой сервер или отказоустойчивое объектное хранилище.
Резервное копирование постоянных дисков с динамическим контентом
Как уже было рассказано выше, динамические данные, находящиеся на постоянных дисках ваших контейнеров, т.к. файлы СУБД MongoDB, MySQL, Postgresql, Redis и т.д. резервному копированию не подлежат. Для резервного копирования баз данных необходимо использовать утилиты mongodump, mysqldump, pg_dump, rdiff-backup и т.д., выполняя резервное копирование стандартными средствами нужной СУБД. Запуск вышеуказанных команд для резервного копирования и восстановления может быть выполнен из заранее созданного образа, содержащего эти утилиты, по аналогии с примером резервного копирования статичного контента постоянного диска.