Сегодняшняя статья будет посвящена Docker Compose. При работе с контейнерами Docker рано или поздно наступает момент, когда наше приложение превращается в несколько распределенных сервисов, которым необходимо взаимодействие друг с другом. В таком случае для автоматизации управления компонентами такого распределенного приложения нам потребуется Docker Compose. В качестве примера такого приложения можно привести веб ресурс, взаимодействующий с базой данных или служба, использующая дополнительные компоненты, такие как кэш Redis.

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

По сути, Docker Compose это тот же Docker, но позволяющий автоматизировать работу с более сложными приложениями. Кроме того, для сценариев с одним контейнером использование Docker Compose обеспечивает независимую от инструмента конфигурацию таким образом, чего не делает отдельный файл Dockerfile. Параметры конфигурации, такие как подключение тома для контейнера, сопоставления портов и переменные среды, могут быть объявлены в файлах docker-compose YML.

Работа с docker compose

Для работы с Docker Compose на текущий момент есть два приложения:

docker-compose

Это изначальное автономное приложение для оркестрации Docker. И второй вариант:

docker compose

Отличие между этими двумя командами естественно не ограничивается только наличием пробела. Второй вариант  это более новый проект, который позволяет использовать compose совместно с основным проектом docker. По сути это ветвь v2 репозитория docker/compose. Примечательно, что впервые данная ветвь была представлена пользователям Docker Desktop, поэтому пользователи docker в Linux не видели эту команду.

На данный момент оригинальный проект python, называемый docker-compose, akav1 из репозитория docker/compose, считается устаревшим, и разработка перенесена на версию v2.

Установка

Перейдем к установке. Как можно было понять из предыдущего описания, возможны несколько вариантов использования Docker Compose. Прежде всего, можно установить docker compose версии v2 в качестве плагина CLI в Linux. Например:

apt-get install docker-compose-plugin

Но если у вас, как и в моем примере с Ubuntu используется чистый Linux, то здесь для установки потребуется несколько иной набор действий.

Для начала выполним предварительные настройки: установим Gnome Terminal (предполагается, что у нас он не установлен).

sudo apt install gnome-terminal

Далее необходимо создать каталог для установки плагина Compose

mkdir -p ~/.docker/cli-plugins/  

На следующем шаге выгружаем docker compose из репозитория с помощью curl:

curl -SL https://github.com/docker/compose/releases/download/версия/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose

После этого необходимо выставить нужные права на каталог в который мы разместили docker compose:

chmod +x ~/.docker/cli-plugins/docker-compose 

Проверим версию:

docker compose version

Теперь самое время проверить наш развернутый docker-compose в работе. Для этого создадим демо каталог, в котором будет создан файл docker-compose.yml с необходимыми данными:

mkdir ~/demo

cd ~/demo

nano docker-compose.yml

Вот содержимое этого файла, а котором мы запускаем контейнер с Redis:

version: '3.9'

services:
  redis:
    image: redis:6.2-alpine
    ports:
      - 6379:6379
    command: redis-server --save 60 1 --requirepass MDNcVb924a --loglevel warni>

Запустим контейнер и посмотрим какие образы он использует.

docker compose up -d

docker compose ps

Мы установили и запустили docker compose, теперь самое время разобраться как с ним работать. Прежде всего необходимо подготовить файл docker-compose.yml. Файл Compose имеет структуру YAML, и определяет: версию, службы, сети, тома, конфигурации и секреты. Путь по умолчанию для файла Compose - в рабочем каталоге. Реализации Compose также должны поддерживать docker-compose.yaml и docker-compose.yml для обратной совместимости.  Поскольку некоторые элементы файла Compose могут быть представлены как в виде отдельных строк, так и в виде сложных объектов, слияния применяются к развернутой форме.

Профили

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

Элемент верхнего уровня Services поддерживает атрибут profiles для определения списка именованных профилей. Службы без набора атрибутов profiles всегда должны быть включены.

Ссылки на другие сервисы (посредством ссылок, расширений или синтаксиса общего ресурса service:xxx) не должны автоматически включать компонент, который в противном случае был бы проигнорирован активными профилями.

Для лучшего понимания работы сервисов с профилями рассмотрим пример структуры файла:

services:
  foo:
    image: foo
  bar:
    image: bar
    profiles:
      - test
  baz:
    image: baz
    depends_on:
      - bar
    profiles:
      - test
  zot:
    image: zot
    depends_on:
      - bar
    profiles:
      - debug

В этом демо примере если нет включенного профиля, то будет использоваться только служба foo. Если включена проверка профиля test, модель содержит службы bar и baz, которые включены этим профилем, и service foo, который всегда включен. Если включена отладка профиля (debug), модель содержит как foo, так и zot-сервисы, но не bar и baz, и поэтому модель недействительна в отношении ограничения depends_on zot. И если включены профили debug и test, модель содержит все службы: foo, bar, baz и zot.

Пример реального файла

Здесь мы разворачиваем стек elasticsearch-logstash-kibana. В приведенном ниже листинге можно посмотреть, как в реальности построено взаимодействие между сервисами в yaml файлах.

services:
  elasticsearch:
    image: elasticsearch:7.16.1
    container_name: es
    environment:
      discovery.type: single-node
      ES_JAVA_OPTS: "-Xms512m -Xmx512m"
    ports:
      - "9200:9200"
      - "9300:9300"
    healthcheck:
      test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
      interval: 10s
      timeout: 10s
      retries: 3
    networks:
      - elastic
  logstash:
    image: logstash:7.16.1
    container_name: log
    environment:
      discovery.seed_hosts: logstash
      LS_JAVA_OPTS: "-Xms512m -Xmx512m"
    volumes:
      - ./logstash/pipeline/logstash-nginx.config:/usr/share/logstash/pipeline/logstash-nginx.config
      - ./logstash/nginx.log:/home/nginx.log
    ports:
      - "5000:5000/tcp"
      - "5000:5000/udp"
      - "5044:5044"
      - "9600:9600"
    depends_on:
      - elasticsearch
    networks:
      - elastic
    command: logstash -f /usr/share/logstash/pipeline/logstash-nginx.config
  kibana:
    image: kibana:7.16.1
    container_name: kib
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch
    networks:
      - elastic
networks:
  elastic:
    driver: bridge

Давайте сохраним этот файл в новом каталоге и запустим на выполнение:

mkdir elk

docker compose up -d

Смотрим результат:

docker compose ps

 Как видно, у нас успешно запустились три контейнера.

Заключение

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

А сейчас хочу пригласить вас на бесплатный вебинар, где рассмотрим основы инструмента Terraform и практику построения облачной инфраструктуры с применением подхода IaC

Комментарии (2)