Traefik ›Плохой шлюз (ошибка 502) для некоторых контейнеров

У меня возникают проблемы при использовании traefik с докером, и я не знаю почему.

С некоторыми контейнерами это работает как шарм, а с другими у меня возникает ошибка при попытке доступа к этим: Плохой шлюз (ошибка 502).

Вот мой traefik.toml:

# Service logs (here debug mode)
debug = true
logLevel = "DEBUG"

defaultEntryPoints = ["http", "https"]

# Access log
filePath = "/var/log/traefik/access.log"
format = "common"

################################################################
# Web configuration backend
################################################################
[web]
address = ":8080"

################################################################
# Entry-points configuration
################################################################
[entryPoints]
  [entryPoints.http]
    address = ":80"
    [entryPoints.http.redirect]
      entryPoint = "https"
  [entryPoints.https]
    address = ":443"
    [entryPoints.https.tls]

################################################################
# Docker configuration backend
################################################################
[docker]
domain = "domain.tld"
watch = true
exposedbydefault = false
endpoint = "unix:///var/run/docker.sock"

################################################################
# Let's encrypt
################################################################
[acme]
email = "[email protected]"
storageFile = "acme.json"
onDemand = false
onHostRule = true
entryPoint = "https"

[acme.httpChallenge]
  entryPoint = "http"

[[acme.domains]]
  main = "domain.tld"
  sans = ["docker.domain.tld", "traefik.domain.tld", "phpmyadmin.domain.tld", "perso.domain.tld", "muximux.domain.tld", "wekan.domain.tld", "wiki.domain.tld", "cloud.domain.tld", "email.domain.tld"]

Вот мой docker-compose.yml (для portainer, который является контейнером, который работает):

version: '2'

services:
  portainer:
    restart: always
    image: portainer/portainer:latest
    container_name: "portainer"
#Automatically choose 'Manage the Docker instance where Portainer is running' by adding <--host=unix:///var/run/docker.sock> to the command
    ports:
      - "9000:9000"
    networks:
      - traefik-network
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ../portainer:/data
    labels:
      - traefik.enable=true
      - traefik.backend=portainer
      - traefik.frontend.rule=Host:docker.domain.tld
      - traefik.docker.network=traefik-network
      - traefik.port=9000
      - traefik.default.protocol=http

networks:
  traefik-network:
    external : true

Если я перейду на docker.domain.tld, он заработает! а в https с помощью valide зашифруем сертификат :)

Вот мой docker-compose.yml (для dokuwiki, который является контейнером, который не работает):

version: '2'

services:
  dokuwiki:
    container_name: "dokuwiki"
    image: bitnami/dokuwiki:latest
    restart: always
    volumes:
      - ../dokuwiki/data:/bitnami
    ports:
      - "8085:80"
      - "7443:443"
    networks:
      - traefik-network
    labels:
      - traefik.backend=dokuwiki
      - traefik.docker.network=traefik-network
      - traefik.frontend.rule=Host:wiki.domain.tld
      - traefik.enable=true
      - traefik.port=8085
      - traefik.default.protocol=http

networks:
  traefik-network:
    external: true

Если я захожу на wiki.domain.tld, он не работает! У меня плохая ошибка шлюза в браузере. Я попытался изменить traefik.port на 7443 и traefik.default.protocol на https, но у меня та же ошибка. Конечно, это работает, когда я пытаюсь получить доступ к вики с IP и портом (в http / https). У меня плохой шлюз, только когда я набираю wiki.domain.tld.

Итак, я не понимаю, почему это работает для одних контейнеров, а не для других с таким же объявлением.


person Alextoch    schedule 21.03.2018    source источник


Ответы (3)


Порт traefik должен быть http-портом контейнера, а не опубликованным портом на хосте. Он обменивается данными через сеть докеров, поэтому публикация порта не требуется и противоречит целям публикации только одного порта с обратным прокси-сервером для доступа ко всем контейнерам.

Вкратце, вам нужно:

traefik.port=80

Поскольку этот вопрос получил много просмотров, другая причина, по которой многие люди видят 502 из traefik, - это размещение контейнеров в сети докеров, отличной от экземпляра traefik, или наличие контейнера в нескольких сетях и не указание traefik, какую сеть использовать. Это не применимо в вашем случае, поскольку в вашем файле compose есть следующие строки, которые соответствуют сети службы traefik:

services:
  dokuwiki:
    networks:
      - traefik-network
    labels:
      - traefik.docker.network=traefik-network
networks:
  traefik-network:
    external : true

Даже если вы назначаете службу только одной сети, некоторые действия, такие как публикация порта, приведут к тому, что ваша служба будет подключена к двум разным сетям (входящая сеть будет второй). Сетевое имя в метке должно быть внешним именем, которое в вашем случае такое же, но для других, которые не указывают свою сеть как внешнюю, у него может быть префикс имени проекта или стека, который вы можете увидеть в выводе docker network ls .

person BMitch    schedule 21.03.2018
comment
Ооо, отличный BMitch, работает! Большое спасибо :) Я неправильно понял эту переменную! - person Alextoch; 22.03.2018
comment
Еще маленький вопрос: если я поставлю http-порт, он работает. Но если я помещаю порт https (443) в traefik.port и https в traefik.default.protocol, я получаю внутреннюю ошибку сервера. Ты знаешь почему ?? - person Alextoch; 22.03.2018
comment
@Alextoch traefik по умолчанию использует http для связи с вашим приложением. Это завершает tls. Чтобы повторно зашифровать запрос, вам нужно установить traefik.protocol=https. docs.traefik.io/configuration/backends/docker - person BMitch; 22.03.2018
comment
Я уже положил traefik.default.protocol=https в контейнер. Я заменил его на traefik.protocol=https. У меня такой же результат: Внутренняя ошибка сервера. Я просмотрел веб-интерфейс traefik, и URL-адрес кажется подходящим для бэкэнда: https: // 172.21.0.7:443 - person Alextoch; 22.03.2018
comment
@Alextoch Вы подтвердили, что внутренняя ошибка сервера исходит от traefik, а не от вашего приложения? Какие журналы вы проверяли? Отладка этого, вероятно, будет другим вопросом. - person BMitch; 22.03.2018
comment
Да, приложение работает, когда я пытаюсь получить к нему доступ через https с IP-адресом моего выделенного сервера. - person Alextoch; 22.03.2018
comment
В некоторых журналах я обнаружил активацию режима отладки: time="2018-03-22T18:12:24Z" level=debug msg="vulcand/oxy/forward/http: Round trip: https://172.21.0.8:443, code: 500, Length: 21, duration: 9.74602ms tls:version: 303, tls:resume:true, tls:csuite:c02f, tls:server:wiki.domain.tld" - person Alextoch; 22.03.2018
comment
Просто для помощи пользователям, которые не добились успеха с этим исправлением в traefik.port: для меня только удаление и создание сети докеров решает проблему. - person Marco Blos; 23.08.2018
comment
Я был во многих местах, но твой простой ответ и простое объяснение помогли мне выбраться - person kakabali; 08.02.2019

traefik.docker.network также должно быть полным именем сети. Либо определяется извне, либо с префиксом имени стека.

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

person Ryan    schedule 05.02.2019

Проверить Применить:

firewall-cmd --add-masquerade --permanent

ОТ: https://www.reddit.com/r/linuxadmin/comments/7iom6e/what_does_firewallcmd_addmasquerade_do/

Маскарадинг - это причудливый термин для Source NAT.

firewall-cmd в этом случае добавит правило iptables, в частности, в цепочку POSTROUTING в таблице nat.

Вы можете увидеть, что он на самом деле сделал, запустив iptables -t nat -nvL POSTROUTING. Типичной командой для создания правила маскарадинга вручную будет iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE, что переводится как «Для пакетов, покидающих интерфейс eth0 после того, как они были маршрутизированы, измените их исходный адрес на адрес интерфейса eth0.

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

Ничто из этого не превращает вашу систему Linux в маршрутизатор; это отдельное поведение, которое включается (для IPv4) при выполнении sysctl -w net.ipv4.ip_forward = 1 или echo 1 ›/ proc / sys / net / ipv4 / ip_forward.

Маршрутизация просто означает, что система будет тупо получать трафик в соответствии с местом назначения этого трафика; Материал iptables NAT позволяет вам изменять пакеты, которые отправляются после того, как происходит маршрутизация.

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

person Agustincl    schedule 14.09.2020