Зачем мне нужна сеть докеров по умолчанию, чтобы запустить общую сеть докеров для двух проектов создания докеров?

У меня есть два проекта (a и b), в каждом из которых есть файл docker-compose.yml. Теперь я хочу, чтобы один из проектов мог вызывать службу другого проекта, и, насколько мне известно, для этого мне нужно создать общую сеть докеров. Итак, чтобы создать минимальный пример, я создал две папки (a/ и b/), каждая из которых содержит файл docker-compose.yml.

Это в папке a/:

version: '3'

services:
  common_server:
    image: ubuntu
    ports:
      - 4444:4444
    command: >
      bash -c '
      apt update && apt install netcat -y && 
      while true; do echo -e "HTTP/1.1 200 OK\n\npong" | nc -k -l -p 4444 -q 1; done'
#    networks:
#      - my_network

  project_a:
    image: ubuntu
    depends_on: 
      - common_server
#    networks:
#      - my_network
    command: >
      bash -c '
      apt update && apt install curl -y && 
      while true; do echo "Calling the container";  echo "AAAAAAAA"; curl common_server:4444; sleep 10; done'

#networks:
#  my_network:
#    driver: bridge

Это устанавливает две вещи:

  • common_server: простой сервер ping/pong, который отвечает "pong" на каждый полученный запрос.
  • project_a: простой клиент, который вызывает common_server каждые 10 секунд.

Это прекрасно работает. Я быстро проверил сети докеров, используя:

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
5ac503033848        a_default           bridge              local  <== THIS NETWORK WAS CREATED
1f65f9c91441        bridge              bridge              local
72fcb38f2060        host                host                local
b76cd7ef1ac9        none                null                local

У меня есть второй файл docker-compose.yml в папке b/, из которого я также хочу вызвать common_server, определенный в файле выше. Поэтому я раскомментировал строки с сетью в файле выше, чтобы включить my_network. Бег тоже отлично работает.

Когда я снова проверяю docker network ls, я также вижу вторую сеть, которую он создал:

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
5ac503033848        a_default           bridge              local  <== CREATED BY THE FIRST RUN
f0a42e17007b        a_my_network        bridge              local  <== CREATED BY THE SECOND RUN
1f65f9c91441        bridge              bridge              local
72fcb38f2060        host                host                local
b76cd7ef1ac9        none                null                local

Затем я запустил второй файл docker-compose:

version: '3'

services:
  project_b:
    image: ubuntu
    command: >
      bash -c '
      apt update && apt install curl -y && 
      while true; do echo "Calling the container";  echo "BBBBBBB"; curl common_server:4444; sleep 10; done'
    networks:
     - a_my_network
networks:
  a_my_network:
    external: true

Это также работает. Он может вызывать common_server из первого файла docker-compose.

Первый вопрос: хотя я определяю сеть как my_network в первом файле, docker называет ее a_my_network. Есть ли способ определить сеть, чтобы я мог называть ее одинаково в обоих файлах docker-compose?

Затем я решил удалить эти две сети с помощью docker network prune и начать заново. К сожалению, когда я снова запускаю первый файл, я получаю следующую ошибку:

$ docker-compose up
Creating network "a_my_network" with driver "bridge"
Starting a_common_server_1 ... error

ERROR: for a_common_server_1  Cannot start service common_server: network f0a42e17007bc0f352042f5394aef65be18bb12c7836e8864ecb734f83a421d7 not found

ERROR: for common_server  Cannot start service common_server: network f0a42e17007bc0f352042f5394aef65be18bb12c7836e8864ecb734f83a421d7 not found
ERROR: Encountered errors while bringing up the project.

Итак, мой второй вопрос: почему я могу запустить только первый файл docker-compose, если я сначала создаю сеть a_default, не определяя сеть явно?


person kramer65    schedule 19.02.2020    source источник


Ответы (2)


Когда вы объявляете сеть во втором файле, вы можете явно указать ее name:.

version: '3.7'  # minimum of 3.5
networks:
  my_network:
    external: true
    name: a_my_network

Однако, как вы заметили в начале, Compose создает для вас default сеть, и если вы явно не объявляете networks: для контейнера, который он будет присоединять к default. Вы можете перенастроить default сеть по своему усмотрению. .

Так что, вероятно, я бы вообще не объявлял networks: в первом файле docker-compose.yml. Во втором я бы сделал точку сети default в сети default первого файла, а также не настраивал бы networks: для контейнеров.

networks:
  default:
    external: true
    name: a_default

Compose отслеживает, что происходит, прежде всего, используя метки на объектах. Как правило, они скрыты от вас, но они включены в очень подробный вывод docker inspect. В вашем последнем примере, если вы вручную docker network prune сеть из-под Compose, она начинает путаться. С другой стороны, если вы просто закомментируете созданную вручную сеть и повторно запустите docker-compose up, Compose должен заметить, что он создал сеть, которая больше не нужна, и очистит ее для вас.

person David Maze    schedule 20.02.2020
comment
Хорошо, мне потребовалось некоторое время, чтобы заставить это работать, потому что я упустил из виду вашу похвалу о том, что минимальная версия должна быть 3.5, но теперь это работает, так что большое спасибо за это! Хотя мне интересно; так как я не могу контролировать папки, в которые другие люди клонируют проекты, мне интересно, могу ли я сделать эту работу независимой от меток докера, чтобы мне не нужно было помещать большой жирный NOTE в ридми о сохранении папки проекта назвать по умолчанию? Любые идеи по этому поводу? Или это просто невозможно? - person kramer65; 22.02.2020
comment
Вы также можете вручную указать name: сети по умолчанию в первом docker-compose.yml. Это ограничит вашу способность запускать этот набор файлов Compose несколько раз параллельно, но кроме этого нет особых недостатков. - person David Maze; 22.02.2020

Вы можете изменить имя сети с помощью флагов -p или --project-name или переменной среды COMPOSE_PROJECT_NAME.

И, возможно, посмотрите здесь: https://docs.docker.com/compose/networking/#use-a-pre-existing-network

person Thomas Brüggemann    schedule 19.02.2020
comment
Спасибо за предложение. К сожалению, это изменяет только имя проекта, которое изменяет только префикс, а не само полное сетевое имя. Таким образом, -p my_project сделает сетевое имя my_project_my_network. Таким образом, я все еще не могу иметь одно и то же сетевое имя в обоих файлах докеров. - person kramer65; 19.02.2020