DevOps в серии буткемпов K8s
Примечание: полная ментальная карта DevOps в K8s доступна по адресу: «DevOps в ментальной карте K8s».
В своих предыдущих статьях — DevOps в K8s — эффективно записывайте Dockerfile — я упоминал, что по умолчанию все файлы, созданные внутри контейнера, хранятся на доступном для записи уровне контейнера. Это означает следующие три вещи:
- Непостоянное хранилище. Данные, которые вы храните в контейнере, не сохраняются.
- Тесно связанные отношения: поскольку доступный для записи уровень тесно связан с хостом, перемещать данные непросто.
- Сниженная производительность записи: драйвер хранилища (объединенная файловая система) требуется для записи в доступный для записи слой контейнера, эта дополнительная абстракция снижает производительность по сравнению с использованием томов данных.
Однако Docker предоставляет следующие два варианта контейнеров для постоянного хранения файлов на хосте: Volume
и Bind mount
. Если контейнер вашего приложения должен хранить файлы в памяти на хосте, вы можете использовать другой вариант, который называется tmpfs
mount (в Linux). Разницу можно представить на следующей диаграмме:
Из приведенной выше диаграммы мы видим, что:
- Том: часть файловой системы хоста (
/var/lib/docker/volumes/
), которой управляет Docker. Обычно это лучший способ сохранить данные в Docker. - Привязать монтирование: просто каталог в файловой системе хоста, который монтируется в контейнер. Данные могут храниться в любом месте хост-системы.
- tmpfs: хранятся только в памяти хост-системы и никогда не записываются в файловую систему хост-системы.
Объемы контейнеров
Если вы хотите хранить постоянные данные, Volumes
предпочтительнее. Он имеет следующие преимущества:
- Легче выполнить резервное копирование или миграцию
- Можно управлять с помощью Docker CLI/API
- Может быть более безопасно разделен между несколькими контейнерами
- Может храниться на удаленных хостах с шифрованием
Общие операции с томами
Создать том
$ docker volume create test-vpl test-vpl $ docker volume ls DRIVER VOLUME NAME local test-vpl
Проверить том
$ docker volume inspect test-vol [ { "CreatedAt": "2023-02-09T09:50:13-05:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/test-vol/_data", "Name": "test-vol", "Options": {}, "Scope": "local" } ]
Удалить том
$ docker volume rm test-vol
Смонтировать том в контейнер
$ docker run -d --name devtest --mount source=test-vol,target=/app nginx:latest d5e994f2c1c6ba3af5c013a4bc290bac8dabb0e583d6392cc1a3b0192760b936 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d5e994f2c1c6 nginx:latest "/docker-entrypoint.…" 9 seconds ago Up 4 seconds 80/tcp devtest $ docker exec -it d5e994f2c1c6 ls /app $ docker inspect devtest | jq .[0]."Mounts" [ { "Type": "volume", "Name": "test-vol", "Source": "/var/lib/docker/volumes/test-vol/_data", "Destination": "/app", "Driver": "local", "Mode": "z", "RW": true, "Propagation": "" } ]
Примеры использования томов
Вот несколько распространенных вариантов использования Volume:
- Совместное использование данных между несколькими запущенными контейнерами
- Храните данные вашего контейнера на удаленном хосте или у облачного провайдера.
- Резервное копирование, восстановление или перенос данных с одного хоста Docker на другой.
- hHgh-производительный ввод-вывод, поскольку тома хранятся на виртуальной машине Linux, а не на хосте, а это означает, что операции чтения и записи имеют гораздо меньшую задержку и более высокую пропускную способность.
Крепления для контейнеров
С помощью Bind mounts
файл или каталог на хосте монтируется (с указанием абсолютного пути) в контейнер. Bind mounts
очень производительны, но они полагаются на файловую систему хост-компьютера, имеющую определенную доступную структуру каталогов.
Чтобы использовать Bind mounts
, вам просто нужно ввести следующую команду:
$ docker run -d -it --name devtest --mount type=bind,source=/tmp/target,target=/app nginx:latest 64fd8bbb4aa805a9c7bd01a1d4f75167d745be57f1875aa5764947b204de3749 $ docker inspect devtest | jq .[0]."Mounts" [ { "Type": "bind", "Source": "/tmp/target", "Destination": "/app", "Mode": "", "RW": true, "Propagation": "rprivate" } ]
Обратите внимание: если вы монтируете каталог в непустой каталог в контейнере, существующее содержимое каталога скрыто монтированием привязки.
Сценарии использования Bind Mount
Ниже приведены некоторые распространенные варианты использования Bind Mounts
:
- Совместное использование файлов конфигурации между контейнерами на одном хосте (как Docker по умолчанию обеспечивает разрешение DNS для контейнеров)
- Совместное использование исходного кода или артефактов сборки между средой разработки на хосте и контейнером.
- Когда структура файлов или каталогов хоста Docker гарантированно соответствует монтированию привязки, которое требуется контейнерам.
tmpfs контейнера
Крепление tmpfs
является временным и сохраняется только в памяти хоста. Когда контейнер останавливается, монтирование tmpfs удаляется, и файлы, записанные там, не сохраняются.
Чтобы использовать tmpfs
в вашем контейнере:
$ docker run -d -it --name tmptest --mount type=tmpfs,destination=/app nginx:latest 9ad60f229f31d24e495da60288035f72a7bad2d17b636bb464456cfa20023a45 $ docker inspect tmptest | jq .[0]."Mounts" [ { "Type": "tmpfs", "Source": "", "Destination": "/app", "Mode": "", "RW": true, "Propagation": "" } ]
tmpfs
монтирования лучше всего использовать в тех случаях, когда вы не хотите, чтобы данные сохранялись ни на хост-компьютере, ни внутри контейнера.