
Долгое время пользователи Mac страдали от низкой производительности в контейнерах докера, где использовались тома. К примеру, если вы монтируете ваше приложение в виде тома в папку /app, то получите деградацию производительности по операциям I/O в контейнере. Дело тут в использовании qcow формата (реализация copy-on-write механизма) внутри образа виртуальной машины докера для Mac OS и использовании виртуальной машины самим докером.
Низкая производительность.
Многие, наверно, натыкались на различные обсуждения (статьи), при поиске решения данной проблемы.
Способ, который мне реально помог в свое время заключается в следующем
cd ~/Library/Containers/com.docker.docker/Data/database/
git reset --hard
# HEAD is now at cafabd0 Docker started 1475137831
cat com.docker.driver.amd64-linux/disk/full-sync-on-flush
# true
echo false > com.docker.driver.amd64-linux/disk/full-sync-on-flush
git commit -s -m "Disable flushing"
# [master dc32fcc] Disable flushing
# 1 file changed, 1 insertion(+), 1 deletion(-)
Т.е. мы просто сбросили sync при flush’е. Скорость работы с диском увеличилась в несколько раз, но все равно оставалась недостаточной.
Для примера приведу сравнения.
Проверяем скорость внутри докер контейнера
time dd if=/dev/zero of=file.img bs=1024 count=100000
102400000 bytes (102 MB) copied, 15.9318 s, 6.4 MB/s
real 0m15.934s
user 0m0.130s
На MacBook
# 102400000 bytes transferred in 0.905395 secs (113099833 bytes/sec)
dd if=/dev/zero of=file.img bs=1024 count=100000
# 0,02s user 0,87s system 97% cpu 0,914 total
Видно, что скорость записи медленнее в 16 раз.
Другой популярный способ борьбы с проблемой – это, наверное, docker sync. Желающие могут почитать подробнее на страничке проекта.
Docker 17.12.
С выходом версии 17.12, судя по документации, ситуация поменялось. Теперь можно изменять размер образа VM в настройках.
Docker теперь использует linuxkit https://github.com/linuxkit/linuxkit.
Дефолтный формат образа теперь «raw» формат. Напомню, что раньше это был «qcow» формат. Прежние образы сохранят этот формат при обновлении. Переконвертировать их не получится, придется все удалить и создать заново.
Если перейти в папку ~/Library/Containers/com.docker.docker/Data, можно увидеть папку com.docker.driver.amd64-linux. Теперь вместо этой папки будет папка vm, в которой будет содержаться «raw» формат образа (это если верить документации, однако по факту у меня папка com.docker.driver.amd64-linux осталась на месте). Сначала может показаться, что «raw» образы занимают очень много места. Дело тут в поддержке разреженных файлов (sparse files) файловой системой Apple. Логический размер файла может быть больше физического.
Прочитать об этом можно по ссылке.
Просто посмотрите на образ, используя ключ -ks у команды ls
ls -klsh Docker.raw
Напомню, что у qcow формата дефолтный максимальный размер равен 64 Gb.
В версии docker 1.13 появится поддержка «TRIM», которая поможет освободить место на хост машине.
Размер Docker.qcow2 файла не будет изменен мгновенно. Каждые 15 минут будет запускаться задача cron для этого дела. Однако этот процесс можно ускорить. Для этого необходимо запустить контейнер
docker run--rm-it--privileged--pid=host walkerlee/nsenter-t1-m-u-i-nfstrim /var
После этого требуется сделать restart.
Можно почистить место при помощи команды (появится в 1.13).
docker system prune
Подробнее о различии форматов можно почитать тут https://docs.docker.com/docker-for-mac/faqs/#disk-usage
Отступление:
Еще одно нововведение это днс имя docker.for.mac.host.internal. Оно теперь должна использоваться вместо
docker.for.mac.host.localhost (все еще валидная настройка). Это позволит сделать правильный резолвинг хостов внутри контейнеров, подробнее о проблеме ниже по ссылке
Полный список изменений
Сравнение скорости при использовании томов в новой версии docker.
Возвращаясь к томам в докере, рекомендую сначала сделать бэкапы ваших данных.
Удалите перед этим неиспользуемые образы
docker rmi $(docker images -f dangling=true -q)
Сделайте бэкап необходимых данных.
Потом можно удалить файл Docker.qcow2. Перезапустите докер.
Либо же можно зайти в настройки, как указано на скриншоте и удалить данные, либо сбросить настройки на дефолтные.

После этого можете пользоваться «raw» форматом для образа.
Вот скриншот после проделанных изменений

Еще проверить размер файла можно при помощи команды du

Теперь у нас файл Docker.raw. Проверим скорость внутри контейнеров.
# [email protected]:/app
time dd if=/dev/zero of=file.img bs=1024 count=100000
# 100000+0 records in
# 100000+0 records out
# 102400000 bytes (102 MB) copied, 14.4795 s, 7.1 MB/s
# real 0m14.484s
# user 0m0.180s
# sys 0m1.700s
В моем случае скорость не изменилась.
Для docker machine ситуация получше выглядит
# [email protected]:/app
time dd if=/dev/zero of=file.img bs=1024 count=100000
# 100000+0 records in
# 100000+0 records out
# 102400000 bytes (102 MB) copied, 6.28926 s, 16.3 MB/s
# real 0m6.300s
# user 0m0.000s
# sys 0m2.890s
Я пока что продолжаю пользоваться настройками cached и delegated для томов
volumes:
- ./:/app:delegated
и docker sync.
P.S.
У кого скорость осталась прежней, сначала проверьте, что у вас используется APFS, а не старая HFS+.
Для преобразования можно использовать Дисковую Утилиту.
Зайдите в раздел Правка -> Преобразовать в APFS.
Update.
Raw формат играет роль только при операциях внутри файловой системы контейнера. Ни raw, ни qcow не влияют на производительность при использовании томов. Обещают улучшить в следующих релизах.
Leave a Reply