Подключение сети докеризованных приложений для вызова API - PullRequest
3 голосов
/ 06 октября 2019

У меня есть небольшая проблема с подключением точек.

Мне удалось докернизировать наше устаревшее приложение и наше новое приложение, но теперь мне нужно настроить их на talk друг с другом через вызов API.

Проекты:

  • Project1 = использование project1_appnet (драйвер моста)
  • Project2 = использование project2_appnet (драйвер моста)
  • Project3 = использование project3_appnet (драйвер моста)

На моем локальном компьютере эти 3 проекта находятся в 3 отдельных папках. Каждый проект будет иметь свои собственные сервисы app, db и cache.

Это docker-compose.yml для одного из проектов. (У них почти все одинаковые docker-compose.yml только с другим изображением и путем к объему)

version: '3'
services:
  app:
    build: ./docker/app
    image: 'cms/app:latest'
    networks:
      - appnet
    volumes:
      - './:/var/www/html:cached'
    ports:
      - '${APP_PORT}:80'
    working_dir: /var/www/html
  cache:
    image: 'redis:alpine'
    networks:
      - appnet
    volumes:
      - 'cachedata:/data'
  db:
    image: 'mysql:5.7'
    environment:
      MYSQL_ROOT_PASSWORD: '${DB_ROOT_PASSWORD}'
      MYSQL_DATABASE: '${DB_DATABASE}'
      MYSQL_USER: '${DB_USER}'
      MYSQL_PASSWORD: '${DB_PASSWORD}'
    ports:
      - '${DB_PORT}:3306'
    networks:
      - appnet
    volumes:
      - 'dbdata:/var/lib/mysql'
networks:
  appnet:
    driver: bridge
volumes:
  dbdata:
    driver: local
  cachedata:
    driver: local

Вопрос:

  • Как я могу заставить их разговариватьдруг друга через вызов API? (На моем локальном компьютере для разработки и для среды prod)
  • На производстве настройки будут немного отличаться, они будут на разных машинах, но все же в одном VPC или даже через общедоступную сеть. Какая настройка для этого?

Примечание:

  • Я искал link, но, видимо, он устарел для v3 или не очень рекомендуется
  • Пробовал curl из контейнера project1 в контейнер project2, выполнив:
root@bc3afb31a5f1:/var/www/html# curl localhost:8050/login
curl: (7) Failed to connect to localhost port 8050: Connection refused

Ответы [ 4 ]

2 голосов
/ 06 октября 2019

Если вы окончательно настроитесь на то, что каждый сервис будет работать в физически другой системе, то на самом деле вариантов нет. Одна система не может получить прямой доступ к сети Docker в другой системе;единственный способ, которым служба 1 сможет связаться со службой 2, - это DNS-имя своего хоста (или IP-адрес) и опубликованный порт. Поскольку в разных средах это будет по-разному, я бы рекомендовал сделать это значение настраиваемой переменной среды.

environment:
  SERVICE_2_URL: 'http://service-2-host.example.com/' # default port 80

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

environment:
  SERVICE_2_URL: 'http://host.docker.internal:8082/'

(Если вы используете Linux на рабочем столевам нужно знать некоторый IP-адрес для хоста, а не localhost, потому что это означает «этот контейнер», а не адрес интерфейса docker0, потому что он будет в конкретной сети, а что-то вроде eth0 адреса хоста.)

Другой вариант - заимствовать другую сеть Docker Compose как внешнюю сеть. Есть некоторая хитрость, если все ваши настройки Docker Compose имеют одинаковые имена;из некоторых экспериментов кажется, что внутренний DNS Docker всегда будет сначала преобразовываться в ваш собственный файл Docker Compose, и вам нужно знать что-то вроде имени контейнера, назначенного Compose (которое не сложно восстановить и является стабильным), чтобы достичьдругие службы.

version: '3'
networks:
  app2:
    external:
      name: app2_appnet
services:
  app:
    networks:
      - appnet
      - app2_appnet
    environment:
      SERVICE_2_URL: 'http://app2_app_1/' # using the service-internal port
      MYSQL_HOST: db # in this docker-compose.yml

(я бы предложил использовать Docker Compose default сеть вместо объявления своей собственной; это в основном позволит вам удалить все блоки networks: вфайл без какого-либо вредного воздействия, но в этом конкретном случае вам нужно будет объявить networks: [default, app2_default] для подключения к обоим.)

Вы также можете рассмотреть решение для размещения нескольких хостов, когда вы начинаете смотреть на это,Kubernetes довольно тяжеловесен, но он будет запускать контейнеры на любом узле кластера (вам не нужно особо беспокоиться о размещении), и он предоставляет вам как пространства имен, так и автоматическое разрешение DNS;вы можете просто установить SERVICE_2_URL: 'http://app.app2/', чтобы он указывал на другое пространство имен, не беспокоясь об этих сетевых деталях.

0 голосов
/ 06 октября 2019

Учитывая, что вы используете разные машины для разных развертываний докеров, вы должны поместить их за обычный веб-сервер (Apache2, Nginx), а затем перенаправить трафик с определенного домена на $APP_PORT с помощью простого vhost. Я предпочитаю делать это вместо того, чтобы напрямую выставлять контейнер в сеть. Таким образом, вы также сможете разместить несколько приложений на одном компьютере (, если хотите ). Поэтому я предлагаю вам не пытаться подключать докерские сети, а " обычные ".

0 голосов
/ 06 октября 2019

Игрался с осматривать и cURL. Я думаю, что нашел решение.

Локально:

  • В своем местном я проверил контейнер и посмотрел NetworkSettings.Network.<network name>.Gateway, который 172.25.0.1
  • ЗатемЯ получаю незащищенный порт, который 8050
  • Затем я свернулся внутри контейнера app1 curl 172.25.0.1:8050/login, чтобы проверить, может ли app1 выполнить http-запрос к контейнеру app2. ИЛИ docker exec -it project1_app_1 curl 172.25.0.1:8050/login
  • И наоборот, я сделал curl 172.25.0.1:80 для app2 -> app 1 ИЛИ docker exec -it project2_app_1 curl 172.25.0.1:80

Единственная проблема заключается в том, что значение Gateway изменяется при перезапускечерез docker-compose up -d

Производство также:

Я не профессионал с сетями и прочим. Моя оценка производства:

Do curl app2-domain.com, которая указывается веб-сервером для приложения, так как они находятся на собственной машине (даже с балансировщиком нагрузки).

0 голосов
/ 06 октября 2019

Если вы запустите этот докер, создайте его локально;данное приложение и база данных находятся в одной сети - appnet - приложение должно иметь возможность общаться с db , используя localhost: $ {DB_PORT}.

Если в работе, еслиapp и db находятся на разных машинах;Приложение, вероятно, должно будет общаться с базой данных, используя IP или доменное имя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...