nginx перед службами docker swarm

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

Допустим, у вас есть сотня веб-приложений, которые приходят и уходят. You want an nginx configuration like that with the example of gitlab:

location / {
  proxy_pass http://gitlab;
}

As gitlab has been created with docker service create, nginx will be able to resolve gitlab by it's swarm-vip fake dns name within your ingress network.

BUT: only if the service container is running. Else, nginx will not start due to [emerg] 1#1: host not found in upstream "gitlab"

Now that's a neckbreaker when you have to run a high availability nginx and it's not your business to ensure that the proxy_pass'ed apps are running.

Everytime you update the nginx service, it will not come up if only one of the hundred other swarm services are not running even for the same second .. wtf?

If that ain't working, why in the world do we need name resolution in swarm? How do you solve this problem?

I thought about consul and dynamic generation of nginx virtual host templates (don't even think about docker-nginx-proxy!), but the apps are very different that you can say each app has its own individual configuration. And all this work not for a special reason, only to solve the resolving problem of nginx?

6
задан 15 August 2017 в 23:11
1 ответ

Я бы порекомендовал заменить статически определенный обратный прокси 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

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

5
ответ дан 3 December 2019 в 00:31

Теги

Похожие вопросы