Traefik>某些容器的“错误网关”(错误502)

时间:2018-03-21 23:00:51

标签: docker traefik bad-gateway

我使用带有docker的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 = "admin@domain.tld"
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和端口访问wiki时(当然,它在http /中) HTTPS)。只有在输入wiki.domain.tld时才会出现网关错误。

所以,我不明白为什么它适用于某些容器而不适用于具有相同声明的其他容器。

你可以帮帮我吗?你有什么主意吗 ?

非常感谢! :)

3 个答案:

答案 0 :(得分:18)

traefik端口应该是容器的http端口,而不是主机上的已发布端口。它通过docker网络进行通信,因此发布端口是不必要的,并且只针对仅使用反向代理发布单个端口来访问所有容器的目标。

简而言之,您需要:

traefik.port=80

由于这个问题得到了很多观点,很多人看到来自traefik的502的另一个原因是将容器放在与traefik实例不同的docker网络上,或者在多个网络上有一个容器而没有告诉traefik哪个网络使用。这不适用于您的情况,因为您的撰写文件中的以下行与traefik服务的网络匹配:

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

即使您只为单个网络分配服务,某些操作(如发布端口)也会导致您的服务连接到两个不同的网络(入口网络是第二个)。标签中的网络名称必须是外部名称,在您的情况下是相同的,但对于未将其网络指定为外部的其他名称,它可能具有前缀的项目或堆栈名称,您可以在{{ 1}}输出。

答案 1 :(得分:0)

traefik.docker.network也必须是标准网络名称。可以在外部定义,也可以使用堆栈名称作为前缀。

您也可以使用docker.network=traefik-network定义默认网络,这意味着您不必将标签添加到每个容器中。

答案 2 :(得分:0)

验证申请:

firewall-cmd --add-masquerade --permanent

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

伪装是Source NAT的一个幻想术语。

在这种情况下,

firewall-cmd将添加一个iptables规则, 特别是nat表中的POSTROUTING链。

您可以通过运行iptables -t nat -nvL来查看其实际作用 发布。手动创建伪装规则的典型命令 将是iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE,其中 转换为“对于已经离开接口eth0的数据包 路由,将其源地址更改为eth0的接口地址。

这会自动添加一个连接跟踪条目,以便数据包 对于以这种方式伪装的连接,具有其原始的 通过返回时恢复的地址和端口信息 系统。

这些都不会使您的Linux系统成为路由器。那是分开的 通过执行sysctl -w启用(针对IPv4)的行为 net.ipv4.ip_forward = 1或echo 1> / proc / sys / net / ipv4 / ip_forward。

路由只是意味着系统将愚蠢地接收到流量 根据该交通的目的地; iptables NAT东西 允许您更改路由后发出的数据包 发生。

这是一个非常简单的概述,而且复杂得多 以及通过不同方式进行配置的可能性。