Назад | Перейти на главную страницу

nginx перед сервисами docker swarm

Я уже несколько недель думаю о том, как это должно быть сделано серьезным образом, и еще не пришел к выводу. Может, я думаю не в том направлении.

Допустим, у вас есть сотня веб-приложений, которые приходят и уходят. Вам нужна такая конфигурация nginx на примере gitlab:

location / {
  proxy_pass http://gitlab;
}

Поскольку gitlab был создан с docker service create, nginx сможет разрешить gitlab по поддельному DNS-имени swarm-vip в вашей входящей сети.

НО: только если сервис-контейнер запущен. Иначе nginx не запустится из-за [emerg] 1#1: host not found in upstream "gitlab"

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

Каждый раз, когда вы обновляете службу nginx, она не запускается, если только одна из сотни других служб роя не запускается даже в течение той же секунды .. Какого черта?

Если это не работает, зачем нам разрешение имен в роях? Как решить эту проблему?

Я думал о консуле и динамической генерации шаблонов виртуального хоста nginx (даже не думайте о docker-nginx-proxy!), Но приложения очень разные, так что можно сказать, что каждое приложение имеет свою индивидуальную конфигурацию. И все это работает не по особой причине, а только для решения решающей проблемы nginx?

Я бы рекомендовал заменить статически определенный обратный прокси-сервер nginx на traefik, который знает о роях и может динамически перенастраивать себя по мере развертывания и уничтожения служб.

Вот пример реализации:

  1. создать сеть, в которой traefik будет общаться с контейнерами: docker network create proxy

  2. Сделайте traefik.toml, вот пример:

traefik.toml

accessLogsFile = "/proc/1/fd/1"
defaultEntryPoints = ["http"]
[entryPoints]
  [entryPoints.http]
  address = ":80"
[web]
address = ":8080"
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "localhost"
watch = true
swarmmode = true
constraints = ["tag==frontend"]
  1. Пример файла для traefik:

docker-compose.traefik.yml

version: '3'

networks:
  proxy:
    external:
      name: proxy

services:
  traefik:
    image: traefik:latest
    volumes:
    - ./traefik.toml:/etc/traefik/traefik.toml:ro
    - /var/run/docker.sock:/var/run/docker.sock
    ports:
    - 80:80
    - 8080:8080
    networks:
    - proxy
    restart: unless-stopped
  1. Настройте свое приложение с помощью ярлыков и в одной сети.

docker-compose.app.yml

version: '3'

networks:
  proxy:
    external: true

services:
  webtest:
    image: nginx:latest
    networks:
    - default
    - proxy
    labels:
    - traefik.frontend.rule=PathPrefixStrip:/webtest
    - traefik.port=80
    - traefik.docker.network=proxy
    - traefik.tags=frontend
    restart: unless-stopped

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