История проблемы переноса docker storage (docker root)
Не далее, чем пару дней назад было решено на одном из серверов вынести docker storage (каталог, где докер хранит все файлы контейнеров, образов) на отдельный раздел, который
обладал большей емкостью. Задача, казалось бы, тривиальная и не предвещала беды…
Приступаем:
1. Останавливаем и убиваем все контейнеры нашего приложения:
docker-compose down
если контейнеров много, и они в разных compose, можно так:
docker rm -f $(docker ps -q)
2. Останавливаем докер демон:
systemctl stop docker
3. Переносим каталог в нужное место:
cp -r /var/lib/docker /docker/data/storage
4. Сообщаем докер демону, чтобы смотрел в новую директорию. Тут несколько вариантов: либо через флаг -g указать демону на новый путь, либо конфиги systemd, которые мы и использовали. Ну или симлинк. Сильно расписывать это не стану, в интернете полно мануалов о переносе docker root в новое место.
5. Стартуем демон докера, и наблюдаем, чтобы он смотрел куда надо:
systemctl status docker
В одной из строк вывода мы должны увидеть:
├─19493 /usr/bin/dockerd --data-root=/docker/data/storage
6. Стартуем наше приложение:
docker-compose up -d
7. Проверяем
И вот тут начинается самое интересное, СУБД, MQ, все хорошо! База цела, все работает… кроме nginx. У нас своя сборка nginx с керберос и куртизанками. И просмотр логов контейнера указал на то, что он не может писать в /var/tmp — Permission denied. Разминаю пальцами виски и пытаюсь анализировать ситуацию… Как так-то? Докер образ же не менялся. Мы же просто перенесли директорию. Всегда работало, и тут на тебе… Ради эксперимента зашел ручками в контейнер и изменил права на данный каталог, были root, root 755, дал root, root 777. И все завелось… В голове зазвучала мысль — бред какой-то… Думал, ну может я чего-то не учел…
Решил, что мы пролюбили права доступа на файлы при переносе. Остановили приложение, докер демон, удалили новую директорию и произвели копирование директории /var/lib/docker уже используя rsync -a
.
Думаю, теперь точно все хорошо, поднимаем докер, приложение.
Иии… проблема осталась… У меня задергался глаз. Я метнулся к консоли своей виртуалки, где гоняю разнообразные тесты, у меня был этот образ nginx, и я залез внутрь контейнера, и тут на каталог /var/tmp права стоят root, root 777. То есть такие же, какие мне пришлось выставлять руками. Но ведь образы идентичны!
Я сравнил через команду
docker inspect my-nginx:12345
Все хеши идентичны, все один в один. Как на сервере, так и на моей виртуалке. Я удалил локальный образ nginx и спуллил заново с registry, который по ряду причин стоит на этой же машине. И проблема та же… Теперь у меня задергался второй глаз.
Я уже не помню, какие мысли были в моей голове, помимо криков «ААААААА» и прочего. На улице 4-ый час ночи, в ход пошли исходники докера с целью понять принцип хеширования слоев образа. Открыл третью банку энергетика. И в итоге до меня дошло, что хеширование учитывает только файл, его содержимое, но НЕ ПРАВА ДОСТУПА! То есть, каким-то загадочным образом у нас побились права, причем selinux отключен, acl не используются, sticky bit нету.
Я удалил локальный образ, так-же удалил образ из docker registry и запушил заново. И все заработало. Получается, что при переносе права побились, как внутри локального образа, так и внутри образа лежащего в registry. Как я уже говорил, по ряду причин он располагался на этой же тачке. И как следствие в одном каталоге /var/lib/docker.
И предвкушая вопрос, не пробовали ли вернуть взор докера на старый каталог — нет, не пробовали, увы, обстоятельства не позволяли. Да и сильно хотелось разобраться.
После написания данной статьи, мне решение проблемы кажется очевидным, но на момент разбора таковым не казалось. Честно гуглил, и не нашел схожих ситуаций.
Итог: проблему решил, причину так и не понял =(
Если кто-то знает\догадывается\было видение о возможных причинах данной проблемы — буду крайне рад вам в комментариях!