Docker nginx-proxy: прокси между контейнерами

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

Это включает, в частности:

Чтобы защитить сервисы через HTTPS и показать их внешнему миру, я установил превосходный контейнер nginx-proxy ( https://github.com/jwilder/nginx-proxy), который позволяет автоматическую настройку прокси-сервера nginx с использованием переменных среды в контейнерах и автоматическое перенаправление HTTP на HTTPS.,

DNS настроен для сопоставления каждого общедоступного URL-адреса докеризованных сервисов с IP-адресом хоста.

Наконец, используя Docker-Compose, мой файл docker-compose.yml выглядит так:

version: '2'
services:
  nginx-proxy:
    image: jwilder/nginx-proxy
    ports:
    - "80:80"
    - "443:443"
    volumes:
    - /var/run/docker.sock:/tmp/docker.sock:ro
    - /var/config/nginx-proxy/certs:/etc/nginx/certs:ro
  postgresql:
    # Configuration of postgresql container ...
  gitlab:
    image: sameersbn/gitlab
    ports:
    - "10022:22"
    volumes:
    - /var/data/gitlab:/home/git/data
    environment:
    # Bunch of environment variables ...
    - VIRTUAL_HOST=gitlab.my-domain.com
    - VIRTUAL_PORT=80
    - CERT_NAME=star.my-domain.com
  archiva:
    image: ninjaben/archiva-docker
    volumes:
    - /var/data/archiva:/var/archiva
    environment:
    - VIRTUAL_HOST=archiva.my-domain.com
    - VIRTUAL_PORT=8080
    - CERT_NAME=star.my-domain.com
  jenkins:
    image: jenkins
    volumes:
    - /var/data/jenkins:/var/jenkins_home
    environment:
    - VIRTUAL_HOST=jenkins.my-domain.com
    - VIRTUAL_PORT=8080
    - CERT_NAME=star.my-domain.com

Для рабочей станции разработчика все работает как положено. Можно получить доступ к услугам разницы через https://gitlab.my-domain.com, https://repo.my-domain.com а также https://jenkins.my-domain.com,

Проблема возникает, когда одна из служб Dockerized получает доступ к другой службе Dockerized. Например, если я пытаюсь получить доступ https://archiva.my-domain.com от Дженкинса Докера, я получу ошибку тайм-аута от прокси.

Кажется, что даже если archiva.my-domain.com разрешается как общедоступный IP-адрес хоста из контейнера Docker,запросы, поступающие от сервисов Dockerized, не передаются через прокси-сервер nginx.

Насколько я понял, docker-nginx обрабатывает запросы, поступающие из хост-сети, но не заботится о запросах, поступающих из внутренней контейнерной сети (_dockerconfig_default_ для стека Docker-Compose).

Вы могли бы сказать, зачем мне использовать прокси из контейнера? Конечно, я мог бы использовать URLhttp://archiva:8080из контейнера Дженкинс, и это будет работать. Но такая конфигурация не масштабируется.

Например, используя сборку Gradle для компиляции одного приложения, build.gradle должен объявить мой частный репозиторий черезhttps://archiva.my-domain.com, Это будет работать, если сборка запускается с рабочей станции разработчика, но не через контейнер jenkins...

Другим примером является аутентификация в Jenkins с помощью службы OAuth GitLab, где один и тот же URL-аутентификация GitLab должна быть доступна как снаружи, так и внутри контейнера Jenkins.

Мой вопрос здесь заключается в следующем: как настроить nginx-proxy для прокси запроса от контейнера к другому контейнеру?

Я не видел ни одной темы, обсуждающей эту проблему, и я недостаточно понимаю проблему, чтобы построить решение на конфигурации nginx.

Любая помощь могла бы быть полезна.

1 ответ

Решение

BMitch, шансы были хорошими, это действительно была проблема с правилами iptables, а не неправильная конфигурация nginx-proxy.

Политика по умолчанию цепочки INPUT для таблицы filter было DROPи не было сделано никаких правил для ACCEPT запросы от IP-адресов контейнера (127.20.XX).

Для справки, я приведу некоторые подробности ситуации, если другие люди столкнутся с той же проблемой.

Чтобы получить доступ к контейнерам из внешнего мира, Docker установил правила для правил PREROUTING и FORWARD, чтобы разрешить DNAT внешних IP-адресов с IP-адреса хоста на IP-адреса контейнера. Эти правила по умолчанию разрешают любые внешние IP-адреса, и поэтому ограничение доступа к контейнерам требует некоторых расширенных настроек iptables.

Смотрите эту ссылку для примера: http://rudijs.github.io/2015-07/docker-restricting-container-access-with-iptables/

Но если вашим контейнерам требуется доступ к ресурсам хоста (сервисы, запущенные на хосте, или, в моем случае, контейнер nginx-прокси, прослушивающий порт хоста HTTP/HTTPS и проксирующий к контейнерам), вам необходимо позаботиться о правилах iptables Входная цепь.

Фактически, запрос, поступающий из контейнера и адресованный хосту, будет перенаправлен в сетевой стек хоста демоном Docker, но затем должен будет пройти цепочку INPUT (как запрос src IP - хост один). Поэтому, если вы хотите защитить ресурсы хоста и позволить контейнерам получать к ним доступ, не забудьте добавить что-то вроде этого:

iptables -A INPUT -s 127.20.X.X/24 -j ACCEPT

Где 127.20.XX/24 - это виртуальная сеть, в которой работают ваши контейнеры.

Большое спасибо за вашу помощь.

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