Docker Compose - контейнер A «не смог разрешить хост» контейнера B

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

docker-compose.yml

services:
  db:
    build: webSQL
    ports:
      - "3000:3000"
  client-test:
    build: clientTest

веб-SQL/Dockerfile

FROM ubuntu

RUN apt update

RUN apt install netcat-traditional

RUN nc -l 3000

клиентТест/Докерфайл

FROM ubuntu

RUN apt update

RUN apt install curl -y

RUN curl -X "hello" http://db:3000

Когда я запускаю docker-compose up в каталоге, содержащем файл docker-compose.yml, я получаю следующий результат:

[+] Building 4.1s (11/11) FINISHED                                                                       docker:default
 => [client-test internal] load build definition from Dockerfile                                                   0.0s
 => => transferring dockerfile: 131B                                                                               0.0s
 => [db internal] load metadata for docker.io/library/ubuntu:latest                                                0.0s
 => [client-test internal] load .dockerignore                                                                      0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [db internal] load build definition from Dockerfile                                                            0.0s
 => => transferring dockerfile: 122B                                                                               0.0s
 => [db 1/4] FROM docker.io/library/ubuntu:latest                                                                  0.0s
 => CACHED [db 2/4] RUN apt update                                                                                 0.0s
 => CACHED [client-test 3/4] RUN apt install curl -y                                                               0.0s
 => ERROR [client-test 4/4] RUN curl -X "hello" http://db:3000                                                     4.0s
 => [db internal] load .dockerignore                                                                               0.0s
 => => transferring context: 2B                                                                                    0.0s
 => CACHED [db 3/4] RUN apt install netcat-traditional                                                             0.0s
 => CANCELED [db 4/4] RUN nc -l 3000                                                                               4.0s
------
 > [client-test 4/4] RUN curl -X "hello" http://db:3000:
0.641   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
0.641                                  Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:02 --:--:--     0curl: (6) Could not resolve host: db
------
failed to solve: process "/bin/sh -c curl -X \"hello\" http://db:3000" did not complete successfully: exit code: 6

Насколько я понимаю Docker Compose, каждый контейнер может автоматически отправлять запросы ко всем остальным контейнерам в одном и том же файле Docker Compose. (Предполагая, что вы не указываете разные сети для запуска контейнеров) Что я делаю неправильно?

Возможно, при запуске хост базы данных еще не запущен, поэтому его также невозможно разрешить. Я думаю, если вы запустите их отдельно с достаточным временем между ними, сначала db, а затем клиентский тест, это сработает. Объявите зависимости и надлежащую проверку работоспособности, чтобы сделать это более надежным.

Ulrich Eckhardt 26.05.2024 11:05
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
1
1
110
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Если вы измените их на CMD

CMD nc -l 3000
CMD curl -X "hello" http://db:3000

тогда они будут выполняться как основные команды контейнера, когда Compose запускает контейнеры. В этот момент они будут подключены к общей сети, и эта настройка должна работать (до того момента, пока вы не сможете ввести HTTP-ответ в nc).

В примере вы назвали серверный контейнер db. Наиболее распространенным следствием такой настройки является то, что вы не можете выполнять миграцию базы данных или начальные данные во время сборки образа. В типичных установках используется сценарий-оболочка точки входа для запуска миграции при каждом запуске или вручную docker-compose run миграции. Как вы выполняете миграцию базы данных Django при использовании Docker-Compose? есть примеры обеих техник.

Ответ принят как подходящий

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

Сеть Docker настраивается во время выполнения, и именно в этот момент контейнеры могут подключаться друг к другу.

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

Если у вас есть контейнеры, которые зависят от других контейнеров, вы можете указать эту связь в операторах depends_on в файле Docker Compose. Обратите внимание, что depends_on ждет только запуска контейнеров. Не для того, чтобы контейнеры были готовы к подключениям. Часто контейнеры, такие как базы данных, выполняют некоторую работу при запуске и не сразу доступны для подключений.

Чтобы исправить ваши настройки, мы можем добавить depends_on в ваш файл компоновки.

services:

  db:
    build: webSQL
    ports:
      - "3000:3000"
  client-test:
    build: clientTest
    depends_on:
      - db

И ваш Dockerfile базы данных

FROM ubuntu

RUN apt update

RUN apt install netcat-traditional

CMD nc -l 3000

И ваш клиентTest Dockerfile

FROM ubuntu

RUN apt update

RUN apt install curl -y

CMD curl -X "hello" http://db:3000

Для меня это имеет большой смысл. Однако попробовали ли вы предложенное исправление? Я попробовал, и он все еще не работает, хотя, по крайней мере, он выходит из строя с другой ошибкой. Теперь я получаю «client-test-1 | curl: (7) Не удалось подключиться к порту базы данных 3000 через 1 мс: не удалось подключиться к серверу. Client-test-1 завершился с кодом 7»

Skater901 27.05.2024 13:09

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

Hans Kilian 27.05.2024 14:15

Но как бы то ни было, ваша команда nc кажется неправильной. Я получил это для работы nc -l -p 3000. Без -p он жалуется, что не понимает 3000 и вместо этого слушает случайный порт. Я также изменил -X на -d в команде завитка.

Hans Kilian 27.05.2024 14:30

Другие вопросы по теме