Пошук уроків, статей та іншого контенту
Організуйте довготривале збереження даних, резервування та перенесення Docker-томів між середовищами.
Файлова система контейнера є тимчасовою. Якщо контейнер видалити, дані, записані всередину його файлової системи, зазвичай також втрачаються:
docker rm appДля довготривалого збереження даних використовують Docker volumes. Том живе окремо від контейнера та може бути підключений до нового контейнера.
Життєвий цикл даних і контейнера в такому випадку розділяється:
контейнер можна видалити або замінити;
том продовжує існувати;
інший контейнер може підключити той самий том;
дані можна окремо резервувати та переносити.
Створимо іменований том:
docker volume create app-dataПереглянути список томів:
docker volume lsОтримати інформацію про конкретний том:
docker volume inspect app-dataПідключимо том до тимчасового контейнера Alpine і створимо файл:
docker run --rm \
-v app-data:/data \
alpine \
sh -c 'echo "Важливі дані" > /data/example.txt'Тепер контейнер видалено, але том залишився. Перевіримо його з іншого контейнера:
docker run --rm \
-v app-data:/data \
alpine \
cat /data/example.txtРезультат:
Важливі даніПрапорець --rm видаляє тимчасовий контейнер після завершення команди, але не видаляє том.
Том можна видалити окремо:
docker volume rm app-dataПісля цього дані в ньому буде втрачено. Docker не створює резервну копію автоматично.
Команда:
docker volume pruneвидаляє невикористовувані томи. Використовуйте її обережно: том може не бути підключений до контейнера зараз, але містити потрібні дані.
Зазвичай том підключають до директорії, де програма зберігає свої дані:
docker run -d \
--name app \
-v app-data:/var/lib/app \
my-app:latestУ цьому прикладі:
app-data — ім’я Docker-тому;
/var/lib/app — шлях усередині контейнера;
файли програми в /var/lib/app зберігаються в томі;
після видалення контейнера том залишається.
Той самий том можна підключити до нового контейнера:
docker rm -f app
docker run -d \
--name app \
-v app-data:/var/lib/app \
my-app:latestНовий контейнер побачить дані, які залишив попередній.
За замовчуванням том монтується для читання та запису:
docker run --rm \
-v app-data:/data \
alpine \
sh -c 'echo "новий рядок" >> /data/example.txt'Для монтування лише для читання використовуйте суфікс :ro:
docker run --rm \
-v app-data:/data:ro \
alpine \
cat /data/example.txtКонтейнер з таким монтуванням не повинен змінювати файли в томі. Режим :ro корисний, коли контейнеру потрібно лише читати конфігурацію або дані.
Docker volume не є резервною копією. Щоб створити backup, дані можна запакувати в архів через тимчасовий контейнер.
Підготуємо директорію для локальних резервних копій:
mkdir -p backupsСтворимо backup тому app-data:
docker run --rm \
-v app-data:/data:ro \
-v "$PWD/backups":/backup \
alpine \
tar czf /backup/app-data.tar.gz -C /data .Тут підключено два сховища:
app-data:/data:ro — том із даними, лише для читання;
"$PWD/backups":/backup — локальна директорія з файлами backup.
Архів буде створено на машині Docker у файлі:
backups/app-data.tar.gzПеревірити його наявність:
ls -lh backups/app-data.tar.gzДля статичних файлів такого backup зазвичай достатньо. Для активної бази даних просте копіювання файлів тому може створити неповну або пошкоджену копію, якщо база паралельно записує дані.
Перед резервуванням даних потрібно забезпечити узгоджений стан програми:
зупинити контейнер, який записує дані;
створити архів;
запустити контейнер знову.
Наприклад:
docker stop app
docker run --rm \
-v app-data:/data:ro \
-v "$PWD/backups":/backup \
alpine \
tar czf /backup/app-data.tar.gz -C /data .
docker start appЯкщо конкретна система зберігання має власний механізм експорту або backup, для робочих даних краще використовувати його. Важливо копіювати логічно узгоджений стан, а не просто набір файлів у довільний момент.
Спочатку створимо окремий том для відновлених даних:
docker volume create app-data-restoredРозпакуємо архів у нього:
docker run --rm \
-v app-data-restored:/data \
-v "$PWD/backups":/backup:ro \
alpine \
tar xzf /backup/app-data.tar.gz -C /dataПеревіримо відновлені файли:
docker run --rm \
-v app-data-restored:/data:ro \
alpine \
find /data -maxdepth 2 -type f -printПісля перевірки можна підключити відновлений том до програми:
docker run -d \
--name app-restored \
-v app-data-restored:/var/lib/app \
my-app:latestВідновлення в новий том безпечніше, ніж негайне перезаписування робочого. Так можна перевірити результат і зберегти старий том до завершення перевірки.
Docker volume належить конкретному Docker Engine. Сам по собі том не стає доступним на іншій машині або в іншому середовищі.
Загальна схема перенесення:
створити архів у першому середовищі;
передати архів у друге середовище;
створити новий том;
розпакувати архів у новий том;
підключити його до контейнера.
mkdir -p backups
docker run --rm \
-v app-data:/data:ro \
-v "$PWD/backups":/backup \
alpine \
tar czf /backup/app-data.tar.gz -C /data .Файл backups/app-data.tar.gz потрібно передати в друге середовище будь-яким доступним способом. Наприклад, він може бути завантажений у сховище артефактів або скопійований на іншу машину.
На другій машині створюємо том:
docker volume create app-dataПісля цього розпаковуємо архів:
docker run --rm \
-v app-data:/data \
-v "$PWD/backups":/backup:ro \
alpine \
tar xzf /backup/app-data.tar.gz -C /dataТепер контейнер у другому середовищі може використовувати перенесені дані:
docker run -d \
--name app \
-v app-data:/var/lib/app \
my-app:latestІмена тому в різних середовищах можуть відрізнятися. Важливо, щоб під час відновлення архів було розпаковано саме в той том, який підключається до програми.
Backup не можна вважати надійним, доки не перевірено відновлення.
Мінімальна перевірка складається з таких кроків:
переконатися, що архів існує;
перевірити розмір архіву;
створити тимчасовий том;
розпакувати архів у тимчасовий том;
перевірити важливі файли;
за потреби запустити програму з відновленими даними.
Для перевірки списку файлів в архіві:
tar tzf backups/app-data.tar.gzПриклад повної локальної перевірки:
docker volume create app-data-test
docker run --rm \
-v app-data-test:/data \
-v "$PWD/backups":/backup:ro \
alpine \
tar xzf /backup/app-data.tar.gz -C /data
docker run --rm \
-v app-data-test:/data:ro \
alpine \
cat /data/example.txt
docker volume rm app-data-testНе слід видаляти оригінальний том одразу після створення backup. Спочатку перевірте, що дані дійсно можна відновити.
Для довготривалих даних Docker-застосунків зазвичай використовують іменовані volumes:
docker run -v app-data:/var/lib/app my-app:latestBind mount підключає конкретну директорію хост-системи:
docker run -v "$PWD/app-data":/var/lib/app my-app:latestОсновна відмінність:
volume керується Docker і має власний життєвий цикл;
bind mount безпосередньо використовує шлях на хості.
Для backup named volume зручний тим, що його можна підключити до тимчасового контейнера без знання внутрішнього шляху на хості. Для обох варіантів важливо окремо організувати резервування.
Файли в томі належать користувачу, від імені якого вони були створені. Якщо основний контейнер працює не від імені root, він може не мати доступу до файлів, відновлених контейнером backup.
Наприклад, backup-контейнер може розпакувати файли з власником root, а програма очікує, що файли належать користувачу з іншим UID.
Тому після відновлення потрібно перевірити:
власника файлів;
групу файлів;
права читання та запису;
UID користувача, від якого працює програма.
Перевірити права можна так:
docker run --rm \
-v app-data:/data:ro \
alpine \
ls -ln /dataПрапорець -n показує числові UID і GID, що допомагає порівняти їх із користувачем у робочому контейнері.
Команда:
docker rm -v appможе видалити анонімні томи, підключені до контейнера. Іменовані томи зазвичай потрібно видаляти окремою командою, але не варто покладатися на це без перевірки конфігурації.
Перед видаленням переконайтеся, де саме зберігаються важливі дані.
Монтування без явного імені тому може створити анонімний том:
docker run -v /var/lib/app my-app:latestДля даних, які потрібно знаходити, резервувати та переносити, краще використовувати явне ім’я:
docker run -v app-data:/var/lib/app my-app:latestКопіювання файлів тому під час запису бази може призвести до неузгодженої копії. Перед backup зупиніть застосунок або використайте механізм backup, передбачений самою системою.
Відновлення безпосередньо в робочий том може знищити поточні дані або ускладнити повернення до попереднього стану.
Безпечніший порядок:
створити окремий том;
відновити дані в нього;
перевірити результат;
підключити його до програми після перевірки.
Volume захищає дані від видалення контейнера, але не від:
помилкового видалення тому;
пошкодження файлової системи;
помилки в програмі;
втрати Docker-хоста;
неправильного оновлення даних.
Для цього потрібні окремі резервні копії та регулярна перевірка відновлення.
Для критичних даних корисно дотримуватися такого процесу:
Створити іменований том.
Підключити його до контейнера програми.
Перед backup зупинити запис або забезпечити узгоджений стан.
Створити архів у зовнішній директорії.
Зберігати кілька резервних копій, а не лише останню.
Перевіряти можливість відновлення в окремий том.
Для перенесення передати архів у нове середовище.
Відновити його в новий том і перевірити права доступу.
Лише після перевірки підключити том до робочого контейнера.
Файлова система контейнера не призначена для довготривалого збереження важливих даних.
Docker volume існує окремо від контейнера та переживає його видалення.
Іменовані томи зручно підключати до нових контейнерів, резервувати та переносити.
Backup тому можна створити через тимчасовий контейнер і архів tar.
Відновлення варто виконувати в новий том із подальшою перевіркою.
Для перенесення між середовищами потрібно передати архів і розпакувати його в том на іншому Docker Engine.
Під час backup активних даних потрібно забезпечити узгоджений стан програми.
Резервну копію необхідно не лише створити, а й перевірити відновлення.