Несколько разных Docker-Compose проектов в одной сети

Docker

Последнее время часто сталкиваюсь с задачами, когда нужно объединить несколько проектов, каждый со своим docker-compose.yml, в одну общую сеть. За частую это связанно с тем, что микро сервисы разрабатывают разные команды, но они должны обменивать между собой и базой информацией. При этом сами проекты, за частую не настолько объемные, что бы держать всё это дело в Kubernetes.

Первый раз при реализации — пришлось погуглить, но как оказалось — внятных статей на эту тему не описано. Потому решил написать свою.
В целом задача не сложная и реализовать её можно по разному, в т.ч. сильно зависит от версии docker-compose которую вы используете. В статье рассмотрю работу на примере docker-compose v3.5

Дано:
— Два проекта со своими docker-compose.yml:
— В первом СУБД Postgress и самописный сервис, который обращается к базе
— Во втором просто сервис, который так же должен обращаться к базе выше

В версии 3.5 появилась удобная фишка network name
При указании имени сети — docker, при развертывании, попробует добавить контейнер в сеть с этим именем, а если такой сети нет — создаст.

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

Пример первого docker-compose.yml

## Версия 3.5
version: "3.5"
services:
  ## Стандартный шаблон сервиса Postgres
  postgres:
    image: postgres:12
    command: postgres -c 'max_connections=400'
    volumes:
      - /srv/services/postgres/data:/var/lib/postgresql/data
    expose:
      - "5432"
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_PASSWORD=****
      - POSTGRES_USER=postgres
      - POSTGRES_DB=database_name
    ## Указываем алиас по которому контейнер будет виден в общей сети
    networks:
      - postgress

  ## Описываем сферического коня в вакууме (самописный сервис)
  service_1:
    image: service1_img:latest
    ports:
      - 1961:1961
      - 8444:8444
  ## Конкретно он пусть зависит от запуска базы
    depends_on:
      - postgres
  ## Передаем параметры подключения к базе
    environment:
      - DB_URL=jdbc:postgresql://postgres:5432/database_name
      - DB_LOGIN=postgres
      - DB_PASSWORD=****
  ## Указываем алиас по которому контейнер будет виден в общей сети
    networks:
      - service_1
## Описываем сети, каждому алиасу присваиваем одно имя сети
networks:
  postgress:
    name: network_name
  service_1:
    name: network_name
first_project_docker-compose.yml

А теперь опишем docker-compose.yml для второго сервиса, который так же должен попадать в сеть с именем network_name

## Версия 3.5
version: "3.5"
services:
  ## Описываем второй сервис
  service_2:
    image: service2_img:latest
    volumes:
      - /some/volume:/mount/somewhere
    ports:
      - 1962:1962
  ## Передаем параметры подключения к базе, как у сервиса_1
    environment:
      - DB_URL=jdbc:postgresql://postgres:5432/database_name
      - DB_LOGIN=postgres
      - DB_PASSWORD=****
  ## Указываем алиас по которому контейнер будет виден в общей сети
    networks:
      - service_2
## Присваиваем имя сети, как в соседнем файле.
networks:
  service_2:
    name: network_name
second_project_docker-compose.yml

На этом всё. Файлы можно запускать в разнобой с помощью docker-compose up -d
При запуске любого из них — будет создана сеть с именем «network_name», а второй подключиться в неё.

Дополнительно:
Если потребуется просто добавить контейнер в эту-же сетку, но без docker-compse — это можно выполнить с помощью команды:

docker run --network=network_name imagename:imageversion

Небольшая ремарка. Данная функция реализована в рамках одного хоста. Если вам требуется объединить контейнеры, которые крутятся на разных хостах — вам нужен docker swarm или kubernetes или любой другой аналогичный метод.

Полезные материалы по теме:
Официальная документация:
https://docs.docker.com/compose/compose-file/compose-file-v3/

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

  1. примеров использования, хотя бы curl’ом, не хватает, а то сделал как указано здесь, а все равно не могу достучаться до соседнего контейнера

    • Спасибо за комментарий, доработаю этот момент в ближайшее время.
      По вашей проблеме — проверьте что в имени контейнера нет запрещенных для http знаков, например «_», это не очевидно, но если контейнер называется app_1 то при выполнении http запроса по имени http://app_1 curl не будет достукиваться, даже не смотря на то что контейнер отвечает соседу по остальным протоколам.

      Так же рекомендую проверить корректность написания yaml, и проверить доступность по имени другими средствами например icmp или telnet

1 уведомление

  1. Установка Docker в Linux - Sysadmin talks

Отправить ответ

Ваш e-mail не будет опубликован.


*