← Все темы

Docker/Docker Compose

Вопросов: 34

Docker – это платформа для контейнеризации, позволяющая упаковать приложение вместе со всеми его зависимостями в единый переносимый контейнер, который может быть запущен на любой машине с установленным Docker.

Основные компоненты:
- Docker Daemon – фоновый процесс, отвечающий за сборку, запуск и мониторинг контейнеров.
- Docker Client – интерфейс командной строки для взаимодействия с демоном.
- Docker Images – шаблоны для создания контейнеров; содержат готовую конфигурацию приложения и его окружения.
- Docker Containers – изолированные запущенные экземпляры, созданные по образам.
- Registry – репозиторий для хранения и обмена Docker-образами, например, Docker Hub.

Ключевые преимущества Docker:
- Портативность: контейнеры гарантируют однообразное поведение приложения в любых средах – от разработки до продакшена.
- Лёгкость и скорость развертывания: запуск и масштабирование контейнеров происходят практически мгновенно, что ускоряет процессы CI/CD.
- Изоляция: приложения работают в изолированных контейнерах, что снижает риски конфликтов между компонентами системы.
- Эффективное использование ресурсов: контейнеризация обеспечивает меньшую нагрузку на систему по сравнению с виртуальными машинами, позволяя запускать больше приложений на одном сервере.
- Управляемость микросервисами: удобное разделение и масштабирование компонентов приложения упрощает архитектурное проектирование и поддержку сложных систем.

Главное различие между Docker и традиционной виртуализацией заключается в уровне изоляции и использовании ресурсов.

Docker (контейнеризация):
- Изоляция на уровне процессов: контейнеры используют ядро хост-ОС и изолируют приложения в рамках отдельных процессов.
- Легковесность: запускаются существенно быстрее и с меньшими затратами ресурсов, поскольку не требуют отдельной операционной системы.
- Единообразие окружения: позволяют легко переносить приложения между различными системами.

Традиционная виртуализация:
- Полная изоляция через гипервизор: каждая виртуальная машина включает собственную ОС, что обеспечивает более глубокую изоляцию.
- Больший overhead: требует больше ресурсов и времени для запуска из-за эмуляции полного аппаратного обеспечения.
- Гибкость ОС: позволяет запускать разные операционные системы на одном хосте.

Итог: Docker обеспечивает более быстрый и эффективный способ развертывания изолированных приложений, в то время как виртуализация предоставляет полную изоляцию за счет запуска отдельных операционных систем.

Docker позволяет контейнерам использовать общую инфраструктуру ядра операционной системы посредством следующих технологий:

1. Пространства имен (Namespaces): Это изолирует ресурсы, такие как процессы, сеть и файловую систему, предоставляя каждому контейнеру его собственную среду.

2. Управление группами (Control Groups или cgroups): Это контролирует использование ресурсов контейнером, таких как CPU, память и диск, обеспечивая распределение и ограничение ресурсов.

3. Взаимодействие с ядром: Docker контейнеры используют API и возможности ядра, такие как сетевые стеки и файловые системы, напрямую, что позволяет общую инфраструктуру ядра, поддерживая изоляцию и эффективность.

Контейнерэто легковесная, изолированная среда выполнения приложений, использующая возможности операционной системы для изоляции процессов.

Основные состояния контейнера:
- Created: Контейнер создан, но ещё не запущен.
- Running: Контейнер активно выполняется.
- Paused: Выполнение контейнера приостановлено, процессы заморожены.
- Stopped/Exited: Контейнер завершил работу или был остановлен.

Образ Docker — это неизменяемый шаблон, содержащий снимок файловой системы, библиотеки, зависимости и переменные окружения, необходимые для работы приложения в контейнере.

Для чего он нужен: образы Docker позволяют упаковать приложение со всеми его зависимостями, что обеспечивает стандартизованный, изолированный и воспроизводимый запуск в любом окружении. Это упрощает развертывание, масштабирование и обновление приложений.

Где они хранятся: образы могут сохраняться локально на машине, а также размещаться в реестрах, таких как Docker Hub или приватные реестры, для централизованного управления, распространения и совместного использования.

Dockerfile — это текстовый документ, содержащий набор инструкций для автоматизированной сборки Docker-образа.

Назначение Dockerfile:
- Автоматизация сборки: позволяет создавать образы шаг за шагом, описывая базовый образ, устанавливая зависимости, копируя файлы и настраивая окружение.
- Консистентность: обеспечивает одинаковую среду для разработки, тестирования и продакшена.
- Документированность: служит документацией для будущего воспроизводимого развертывания приложения.


# Пример простейшего Dockerfile:
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y python3
COPY . /app
WORKDIR /app
CMD ["python3", "app.py"]

Реестр образов – это централизованное хранилище контейнерных образов, например, для Docker.

Для чего он нужен:
- Хранение и распространение готовых к использованию образов контейнеров.
- Управление версиями образов для организации процессов CI/CD.
- Обеспечение доступа разработчиков и систем развертывания к необходимым образам.

Где находится:
- Может находиться в публичных сервисах, таких как Docker Hub, Google Container Registry, или в частных (самостоятельно развёрнутых) решениях на корпоративных серверах или в облаке.

Docker Compose — это инструмент для работы с многоконтейнерными приложениями в Docker.

Назначение: он позволяет описывать инфраструктуру приложения с помощью файла docker-compose.yml, где задаются все необходимые контейнеры, их конфигурации, зависимости и сетевые настройки.

Когда использовать: Docker Compose применяется при разработке, тестировании и локальном развертывании приложений, состоящих из нескольких сервисов (например, веб-сервер, база данных, кеш), а также для автоматизации CI/CD процессов.

Управление Docker контейнерами осуществляется следующими способами:

- Docker CLI: основной инструмент для создания, запуска, остановки, удаления и мониторинга контейнеров. Команды включают docker run, docker stop, docker rm, docker ps и другие.
- Docker API: предоставляет возможность программного управления контейнерами.
- Инструменты оркестрации: для работы с мультиконтейнерными приложениями и кластеризацией используются Docker Compose для локальной среды и Docker Swarm или Kubernetes для масштабируемых кластеров.

Таким образом, управление контейнерами строится вокруг CLI, API и инфраструктур оркестрации.

Контейнер теряет данные, если они хранятся в его файловой системе и не синхронизированы с внешними томами.
- Удаление контейнера удаляет все данные
- Перезапуск, аварийное завершение или обновление контейнера может привести к потере несохранённых данных
- Тестовые и временные контейнеры, предназначенные для одноразовых операций, не гарантируют сохранность данных

Вывод:
Надёжное хранение данных требует внешних томов или систем, обеспечивающих персистентность вне контейнера.

Основные команды Docker для работы с образами:

- docker pull – загрузка образа из удалённого реестра (например, Docker Hub).
- docker build – сборка нового образа из исходного кода с использованием Dockerfile.
- docker push – отправка образа в удалённый реестр.
- docker images – вывод списка доступных локально образов.
- docker rmi – удаление одного или нескольких образов.
- docker tag – присвоение нового тега существующему образу.
- docker save – сохранение образа в tar-архив для переноса или резервного копирования.
- docker load – загрузка образа из tar-архива.

Эти команды являются базовыми для эффективного управления Docker-образами.

Volume — это механизм для хранения данных вне контейнера в Docker.

Для чего используется volume?
- Постоянное хранение данных: данные остаются независимо от жизненного цикла контейнера (например, базы данных, файлы, логи).
- Общий том: обмен данными между несколькими контейнерами.
- Изоляция данных: отделение состояния приложения от контейнера для обеспечения гибкости и удобства обновлений.

Когда применять volume?
- При необходимости сохранить данные вне контейнера.
- Для интеграции между контейнерами.
- При планировании обновлений или масштабирования приложений без потери данных.

Чтобы установить связь между Docker-хостом и Linux-хостом, можно использовать следующие подходы:

- Порт-маппинг: При запуске контейнера с помощью опции -p или -P маппятся порты контейнера на порты хоста, что позволяет доступ к сервисам контейнера через Linux-хост.

- Host-сеть: Запуская контейнер с опцией --network host, контейнер использует сетевой стек Linux-хоста напрямую, что полезно для приложений с высокими требованиями к производительности сети или специфической конфигурации.

Зачем это нужно:

- Для обеспечения обмена данными между сервисами, запущенными в контейнерах, и приложениями непосредственно на Linux-хосте.
- Для удобства отладки, мониторинга и интеграции сервисов.
- Для улучшения производительности и снижения сетевых задержек в случаях, когда контейнеры должны работать максимально близко к хост-среде.


# Пример запуска контейнера с порт-маппингом:
docker run -d -p 8080:80 my_image

# Пример запуска контейнера с использованием host-сети:
docker run -d --network host my_image

Docker volumes по умолчанию хранятся на хост-системе, а именно в каталоге /var/lib/docker/volumes/ на Linux.
Важно:
- На Windows и macOS используется виртуальная машина, поэтому физическое расположение может отличаться.
- Местоположение volumes можно изменить через конфигурацию демона Docker.

FROMБазовый образ, на основе которого строится новый образ.
RUNВыполнение команд во время сборки образа (установка пакетов, компиляция и т.п.).
CMDЗадание команды, которая выполняется при запуске контейнера. Может быть переопределена в командной строке.
LABELДобавление метаданных к образу (например, автор, версия, описание).
EXPOSEИнформирование о портах, которые контейнер слушает во время выполнения.
ENVУстановка переменных окружения, доступных во время сборки и выполнения контейнера.
ADDКопирование файлов и директорий в образ с возможностью извлечения архивов и работы с URL.
COPYПростое копирование файлов и директорий в образ. Предпочтительна для избежания неожиданных преобразований.
ENTRYPOINTЗадание неизменного поведения контейнера, позволяющее фиксировать команду, которая всегда будет выполняться.
VOLUMEОбъявление точек монтирования для хранения данных вне контейнера.
USERОпределение пользователя, от которого будут выполняться команды внутри контейнера.
WORKDIRУстановка рабочей директории для последующих инструкций RUN, CMD и т.п.
ARGОпределение переменных сборки, которые можно передавать как аргументы при сборке образа.
ONBUILDУказание инструкций, выполняемых при использовании данного образа как базового для другого образа.
HEALTHCHECKНастройка проверки состояния контейнера, определение команд для мониторинга его работоспособности.
STOPSIGNALОпределение сигнала, который будет отправляться для корректной остановки контейнера.

Что такое Layer?
Layer в современном Docker – это неизменяемый слой файловой системы, созданный в результате выполнения конкретной инструкции в Dockerfile.

Для чего он нужен?
- Кэширование: Слои позволяют повторно использовать результаты сборки, ускоряя процесс создания образов.
- Оптимизация: Они минимизируют использование дискового пространства за счёт разделения образа на независимые, переиспользуемые части.
- Управление изменениями: Каждая модификация образа сохраняется в виде отдельного слоя, что облегчает отслеживание истории изменений.

Как определить слой?
- Каждый слой соответствует отдельной инструкции в Dockerfile.
- Определить и просмотреть слои можно с помощью команды docker history [image], которая выводит информацию о каждом слое образа.

CMD определяет значения по умолчанию для команды, которые могут быть переопределены при запуске контейнера.
ENTRYPOINT задаёт основную команду, которую сложно изменить, обеспечивая неизменное поведение контейнера.

Кратко:
- CMD: значения по умолчанию; заменяемы.
- ENTRYPOINT: обязательная команда; используется для стабильного исполнения.

ENTRYPOINT можно комбинировать с CMD, передавая последние как аргументы к ENTRYPOINT.

COPY используется для простого копирования файлов и директорий из контекста сборки в образ Docker без дополнительной обработки.
ADD поддерживает расширенную функциональность: он может извлекать содержимое архивов (например, .tar) и загружать файлы по URL.
Рекомендация: применять COPY, если не требуется дополнительная функциональность ADD, чтобы избежать неожиданных эффектов.

Основные компоненты сети в Docker:

- Мостовая сеть (bridge): по умолчанию Docker создаёт виртуальный мост, к которому подключаются контейнеры посредством пар виртуальных Ethernet-устройств (veth). Этот мост обеспечивает изоляцию и возможность взаимодействия контейнеров в одном хосте.
- NAT и iptables: для контейнеров на мостовой сети Docker настраивает правила iptables для трансляции адресов, что позволяет контейнерам свободно выходить в интернет.
- Режим host: контейнер использует сетевой стек хоста без дополнительной изоляции, что устраняет накладные расходы на виртуализацию, но снижает безопасность.
- Overlay-сети: используются для объединения контейнеров, расположенных на разных хостах, посредством создания туннелей, реализованных через технологии VXLAN.
- Другие драйверы: например, macvlan позволяют напрямую назначать физические сетевые интерфейсы контейнерам.

Как это работает:
- При запуске контейнера Docker создаёт для него отдельное пространство имён сети (network namespace).
- Контейнер получает виртуальный интерфейс, подключённый к выбранной сети.
- Docker управляет маршрутизацией и правилами NAT, что позволяет контейнерам обмениваться данными как между собой, так и с внешним миром.

Таким образом, архитектура сети в Docker основана на комбинации изоляции посредством пространств имён, виртуализации сетевых интерфейсов и гибкого управления через драйверы сетей.

Подводные камни использования Docker:

- Производительность: Контейнеры могут иметь накладные расходы, особенно при интенсивном вводе-выводе или работе с сетью.
- Безопасность: Неправильная настройка может привести к эскалации привилегий. Использование образов из ненадёжных источников повышает риск.
- Изоляция ресурсов: Ограничения по CPU, памяти и сети требуют внимательной настройки для избежания конфликтов между контейнерами.
- Персистентное хранилище: Управление данными требует тщательной работы с томами и бэкапами, так как данные внутри контейнеров теряются при их удалении.
- Сетевая конфигурация: Правильная настройка сети и взаимодействия контейнеров может быть сложной задачей, особенно в масштабируемых кластерах.
- Отладка и мониторинг: Стандартные инструменты могут быть недостаточны, требуя внедрения специализированных решений для логгирования и наблюдения.
- Обновления и миграции: Изменения в контейнеризованной среде (rollback, миграция данных) могут быть сложными при отсутствии автоматизированных процессов.

Важно: Планирование архитектуры и аудита безопасности образов, а также грамотное управление ресурсами существенно снижают риски при работе с Docker.

Базовый образ – это исходный контейнер, который служит фундаментом для создания других Docker-образов.
Зачем он нужен:
- Он обеспечивает стандартную, оптимизированную и проверенную среду с минимальным набором компонентов, необходимых для запуска приложений.
- С его помощью достигается консистентность среды между разработкой и продакшеном, а также сокращается время сборки образа за счёт переиспользования готовых слоёв.

Как он работает:
- В файле Dockerfile инструкция FROM указывает, на каком базовом образе строится новый образ.
- Новый образ расширяет базовый, добавляя дополнительные слои с установками и конфигурациями.
- При запуске контейнера Docker объединяет все слои в единое файловое пространство, обеспечивая работу приложения в согласованной среде.

Топ 10 команд Docker CLI:

- docker runЗапускает контейнер из образа. Пример: docker run -d -p 80:80 nginx
- docker psОтображает список запущенных контейнеров. Пример: docker ps
- docker imagesПоказывает список локальных образов. Пример: docker images
- docker buildСоздает образ по Dockerfile. Пример: docker build -t myapp .
- docker pullЗагружает образ из репозитория. Пример: docker pull redis
- docker pushОтправляет образ в репозиторий. Пример: docker push myrepo/myapp
- docker execВыполняет команду в работающем контейнере. Пример: docker exec -it container_name bash
- docker logsПросмотр логов контейнера. Пример: docker logs container_name
- docker stopОстанавливает запущенный контейнер. Пример: docker stop container_name
- docker rmУдаляет остановленный контейнер. Пример: docker rm container_name

Общий подход:
- Используйте stdout/stderr: направляйте логи приложения в стандартные потоки, чтобы Docker-лог-драйвер смог их собирать без дополнительных настроек.
- Централизованное логирование: отправляйте логи на внешний агрегатор (например, ELK или EFK стек) для хранения и анализа, что упрощает мониторинг и отладку распределённых систем.
- Структурированное логирование: записывайте логи в формате JSON или другом структурированном виде, чтобы обеспечить удобство поиска и фильтрации.
- Настройка лог драйверов: определите подходящий драйвер (json-file, syslog, journald и т.д.) с учётом требований по производительности и надёжности.
- Управление ротацией и объёмом логов: используйте механизмы ротации для предотвращения переполнения диска и обеспечения устойчивости системы.

Вывод: Логирование в контейнерах должно быть централизованным, стандартизированным и масштабируемым, с использованием stdout/stderr, внешних агрегаторов и структурированного формата логов.

Docker Compose — это инструмент для определения и управления мульти-контейнерными Docker-приложениями.

Основные моменты:
- Конфигурация: Использует YAML-файл (docker-compose.yml) для описания сервисов, сетей и томов.
- Управление: Позволяет запускать, останавливать и обновлять всю инфраструктуру одним набором команд, например, docker-compose up.

Для чего нужен:
- Автоматизация развертывания сложных приложений, состоящих из нескольких сервисов.
- Упрощение разработки и тестирования, позволяя быстро поднять полный стек приложений.

Когда используется:
- В проектах с несколькими зависимыми сервисами, когда требуется согласованное окружение для разработки, тестирования или CI/CD.

Docker Compose – это инструмент для управления многоконтейнерными приложениями. В то время как Docker позволяет запускать и управлять отдельными контейнерами, Compose объединяет несколько контейнеров в единую систему с помощью одного файла конфигурации (docker-compose.yml).

Главные преимущества:

Декларативность: Определяйте всю инфраструктуру приложения в одном файле.
Автоматизация: Запуск, остановка и масштабирование всех компонентов одним обзорным действием.
Управление зависимостями: Настройка взаимодействия между сервисами (сети, тома, переменные окружения).

Таким образом, если приложение состоит из нескольких микросервисов, Docker Compose упрощает их координацию и эксплуатацию.

Основные команды CLI Docker Compose:

- docker-compose up – запускает сервисы, создавая и поднимая контейнеры.
- docker-compose down – останавливает и удаляет запущенные контейнеры, сети, тома, и образы, созданные командой up.
- docker-compose build – собирает образы для сервисов на основе инструкций из Dockerfile.
- docker-compose start – запускает уже созданные контейнеры.
- docker-compose stop – останавливает работающие контейнеры.
- docker-compose restart – перезапускает сервисы.
- docker-compose logs – выводит логи работы контейнеров.
- docker-compose ps – отображает список запущенных контейнеров.
- docker-compose exec – выполняет команду в запущенном контейнере.

Примечание: Эти команды позволяют эффективно управлять жизненным циклом многоконтейнерных приложений с использованием Docker.

Сервис в Docker Compose – это описание конфигурации для одного контейнера или группы связанных контейнеров.
- Определяет, какой образ использовать, команды запуска, порты, переменные окружения, тома и зависимости.
- Позволяет централизованно управлять множеством контейнеров в рамках одного приложения.
- Используется в файле docker-compose.yml для упрощения развертывания и масштабирования многоконтейнерных приложений.

Команда up
- Создаёт новые контейнеры на основе описания в docker-compose.yml, автоматически выполняет сборку образов, настраивает сеть и запускает контейнеры.
- Пересоздаёт контейнеры при изменениях в конфигурации.

Команда start
- Запускает только уже созданные ранее контейнеры, которые были остановлены.
- Не выполняет сборку образов и не создаёт новые контейнеры, если их ещё нет.

Команда run
- Создаёт новый одноразовый контейнер для выполнения заданной команды (например, для отладки или миграций).
- Не влияет на общий цикл работы сервисов: контейнер не добавляется в основной набор, определённый в docker-compose.yml.

Переменные среды – это набор пар ключ-значение, определяющих конфигурацию программного окружения.

- Они используются для передачи настроек и параметров (например, адрес базы данных, порты, пути к ресурсам) без изменения исходного кода приложения.

- В Docker переменные среды помогают настраивать контейнеры, делая их более гибкими и переносимыми между различными средами.

Пример использования:

export DB_HOST=localhost
export DB_PORT=3306

Итог: переменные среды упрощают управление конфигурацией, повышают гибкость и безопасность приложений, позволяя динамически изменять их поведение в зависимости от окружения.

Основная структура Docker Compose файла


version: "3" # Версия синтаксиса Docker Compose
services:
имя_сервиса: # Определение сервиса (контейнера)
image: имя_образа # Образ для запуска контейнера
ports:
- "80:80" # Проброс портов
environment:
- ПЕРЕМЕННАЯ=значение # Переменные окружения (опционально)
volumes:
- ./data:/data # Монтирование томов (опционально)

volumes: # Определение именованных томов (опционально)
имя_тома: {}

networks: # Определение сетей (опционально)
имя_сети: {}


Ключевые моменты:
- version: указывает версию синтаксиса.
- services: содержит конфигурацию контейнеров.
- volumes и networks: определяют дополнительные ресурсы, используемые сервисами.

Основные подходы к управлению конфигурациями в разных средах:

- Переменные окружения: управление настройками через системные переменные, применимо к контейнерам и облачным средам.
- Конфигурационные файлы: использование отдельных файлов для каждой среды с загрузкой соответствующих настроек.
- Инструменты для управления конфигурациями: системы вроде Ansible, Chef или Puppet позволяют централизованно управлять конфигурациями.
- Секреты и менеджеры конфигураций: применение HashiCorp Vault, AWS Secrets Manager или Kubernetes ConfigMaps для безопасного хранения чувствительных данных.
- CI/CD интеграция: автоматизация процесса деплоя и переключения конфигураций через пайплайны.

Выбор подхода зависит от специфики проекта, инфраструктуры и требований безопасности.

docker compose build выполняет сборку Docker-образов для сервисов, определённых в файле docker-compose.yml.
- Она читает инструкции сборки из указанного Dockerfile или непосредственно из раздела build.
- Результатом становится подготовленный образ, который затем можно использовать для запуска контейнеров с помощью команды docker compose up.

docker compose stop – останавливает запущенные контейнеры, сохраняя их состояние. Контейнеры остаются на диске, и их можно перезапустить командой docker compose start.

docker compose down – останавливает контейнеры и удаляет созданные ресурсы: контейнеры, сети, а при указании флагов – и тома, и образы. Это обеспечивает полное удаление сервисов, что полезно для очистки окружения.

Когда использовать:
- stop – если планируется временная остановка с последующим быстрым возобновлением работы.
- down – если требуется полное завершение работы и очистка всех ресурсов, созданных docker compose.