Теория
docker — ПО для автоматизации развертывания и управления приложениями в средах с поддержкой контейнеризации.
Архитектура
docker — клиент-серверное приложение.
Термины
- Docker engine — daemon, отвечающий за всё взаимодействие с контейнерами через свой REST API.
- Container — развернутая из образа и работающая слабоизолированная среда. Являются stateless unit-ами.
- Docker Registry — репозиторий с docker образами, расширениями и плагинами.
- Dockerfile — файл с инструкцией для сборки образов.
Setup
Соус: docs.docker.com/engine/install/debian
Post-install
Разрешение использования docker от имени $USER
:
Remove
Cleanup
docker stop
and docker rm
all containers:
docker rmi
all images:
docker rm
all volumes:
docker rm
all networks:
docker prune
(Remove) unused data:
In one command:
Check
Вывод следующих команд должен быть пустым:
A эта должна вывести only default networks (bridge
, host
, none
):
Networking
Network drivers
Сетевая подсистема docker является pluggable (подключаемой/модульной) и использует драйверы.
Driver | Description |
---|---|
bridge | Default network driver. Используется, если контейнеру нужно общаться с другими контейнерами на одном хосте. См. Bridge network driver |
host | Убирает сетевую изоляцию между контейнером и хостом docker, используя сетевые возможности хоста напрямую. См. Host network driver |
none | Fully изолирует контейнер от хоста, других контейнеров. См. None network driver |
overlay | Оверлейные сети соединяют несколько демонов docker вместе, что, кстати, избавляет от необходимости маршрутизации на уровне ОС. См. Overlay network driver |
macvlan | Сети macvlan позволяют назначить MAC-адрес контейнеру, чтобы он выглядел как физическое устройство внутри сети. Docker daemon направляет трафик к контейнерам по их MAC-адресам. Используется для работы с устаревшими приложениями или для миграции с виртуальных машин. См. Macvlan network driver |
ipvlan | Сети IPvlan предоставляют юзерам total control над адресацией IPv4 и IPv6. Короче, см. IPvlan network driver |
Network plugins | В docker можно ставить и юзать third-party network plugins. |
curl and wget in docker
Images
Save and load images from tarballs
docker save
examples:
docker load
examples:
Untagged images
После
docker load
образы будут untagged (безREPOSITORY
иTAG
).
Нужно просто проставить им теги, знаяIMAGE ID
:
Dockerfile
Layers
About minimizing the number of layers
Слои создают только следующие инструкции:
RUN
COPY
ADD
Другие инструкции создают временные промежуточные образы, не увеличивая размер сборки.
Эффективнее следовать правилу Use multi-stage builds, что также позволит включать инструменты и debug-операции в промежуточные этапы сборки, не влияя на конечный образ.
Best practices
Create ephemeral containers
Нужно писать максимально эфемерные контейнеры. Подразумевается возможность остановки, уничтожения контейнера, его последующей перестройки и замены с минимальными настройками.
Don’t use docker commit
on a running container
Не создавай образы из запущенных контейнеров — применяй docker commit
только к остановленному контейнеру, иначе получившийся (некорректный) образ не будет воспроизводимым.
Don’t COPY
symlinks
Симлинки не резолвятся в Dockerfile. Не пытайся в Dockerfile
передать симлинки через инструкцию COPY
— that’s not gon work.
Decouple applications
Я это правило объединил со схожим: “Don’t run more than one process in a container”
Придерживайся (UNIX-way) идеи “Один контейнер — один процесс”. Пусть лучше будет несколько общающихся между собой контейнеров, что сохранит преимущества контейнеров (согласно философии контейнеров) и:
- упростит поддерживаемость
- более управляемая утилизация ресурсов
- упростит горизонтальное масштабирование
- возможность повторного использования контейнеров
Поэтому держи контейнеры чистыми и модульными.
Understand build context
При запуске docker build
текущая директория называется build context. По умолчанию предполагается, что Dockerfile
находится в текущей директории, но через -f/--file
можно указать другое местоположение. Независимо от того, где находится указанный Dockerfile
, всё рекурсивное содержимое текущей директории передастся docker daemon-у в качестве контекста сборки.
Build context example
Теперь раскинь
Dockerfile
иhello
по разным директориям:Собери вторую версию образа (не полагаясь на кэш последней сборки):
В итоге включение ненужных файлов для создания (второй версии) образа приведет к увеличению:
- контекста сборки
- размера образа
- времени сборки образа
- времени его извлечения и перемещения
- размера среды выполнения контейнера
Exclude with .dockerignore
Используй .dockerignore
для исключения файлов, не относящихся к сборке — не нужно менять структуру репозитория с помощью .gitignore
.
Шаблоны исключения .dockerignore
аналогичны .gitignore
.
Use multi-stage builds
Многоступенчатые сборки позволяют уменьшить размер конечного образа.
Подели Dockerfile
на отдельные этапы так, что итоговый результат (конечный образ) содержит только необходимые для работы приложения файлы.
Example
Don’t install unnecessary packages
Даже пакеты, которые “могут быть полезны” (свой любимый helix), не надо устанавливать.
Не надо обновлять пакеты системы.
Sort multi-line arguments
Пример: блок кода в главе “apt-get”
Сортировка многострочных аргументов:
- поможет избежать дублирования пакетов
- упростит обновление списка
- упрощает review
Leverage build cache
Использование build cache, очевидно, ускоряет сборку образа.
Для каждой инструкции docker проверяет возможность использования инструкции из кэша сборки.
docker аннулирует кэш для измененных слоев. Например, изменение файла, который тянется в образ с помощьюADD
илиCOPY
заставит docker аннулировать кэш для этого слоя и запуститьADD
илиCOPY
заново. И если слой изменился, это затронет и все следующие слои — все последующие слои также будут запущены заново (даже если последующие слои не будут собираться по-другому, их все равно нужно запустить заново).
Build images with BuildKit
Buildkit — встроенный улучшенный сборщик образов.
Он имеет автоматический сборщик мусора, механизмы параллелизма, кэширования и т.д.
Чтобы он собирал образы при запуске команды docker build
, нужно включить его переменным окружения:
или глобально в файле конфигурации docker daemon:
и
Create reusable stages
Если несколько образов юзают общие компоненты — создай reusable stage и основывай уже на нем уникальные стадии, чтобы docker-у нужно было собрать общую стадию только один раз. Это сделает производные образы эффективнее в утилизации памяти и быстрее при загрузке — в общем, те же code reuse pros.
Rebuild your images often
Почаще пересобирай образы, дабы держать их в актуальном и безопасном состоянии, ибо само состояние образа иммутабельны (неизменяемы).
Чтобы быть уверенным в получении последних версий зависимостей при сборке, юзай --no-cache
:
apt-get
Всегда используй вместе apt-get update
и apt-get install
, чтобы избежать проблем с кэшированием:
Если разделить эти команды на разные RUN
инструкции, то в будущем при добавлении, например, новых пакетов для установки docker build
может не запустить apt-get update
, а использовать кэшированный слой для этой инструкции, что приведет к тому, что пакеты не установятся или установятся их неактуальные версии.
ADD or COPY
Юзай COPY
для базового копирования файлов в контейнер, из контекста сборки или из этапа многоэтапной сборки.
Юзай RUN --mount=type=bind
для временного добавления файлов, которым не место в конечном образе:
Юзай ADD
для загрузки удаленных артефактов как частей сборки.
Осторожнее с ADD
Существуют некоторые проблемы с безопасностью при использовании
ADD
для загрузки удаленных артефактов.
Alpine is not always the best choice
Alpine and Python Docker
Учти, что, например, с python могут возникнуть проблемы при использовании alpine.