22

我在使用 traefik 和 docker 时遇到了一些问题,我不知道为什么。

对于某些容器,它就像一个魅力,而对于其他容器,当我尝试访问这些容器时出现错误:网关错误(错误 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 (对于搬运工,这是一个可以工作的容器):

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 时,它会起作用。仅当我键入 wiki.domain.tld 时,我的网关才错误。

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

4

3 回答 3

47

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

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

于 2018-03-21T23:30:37.897 回答
2

traefik.docker.network还必须是完全限定的网络名称。外部定义或以堆栈名称为前缀。

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

于 2019-02-05T04:35:54.913 回答
0

验证申请:

firewall-cmd --add-masquerade --permanent

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

伪装是源 NAT 的一个奇特术语。

在这种情况下,firewall-cmd 将添加一个 iptables 规则,特别是在 nat 表中的 POSTROUTING 链中。

您可以通过运行 iptables -t nat -nvL POSTROUTING 来查看它实际完成的工作。手动创建伪装规则的典型命令是 iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE,其翻译为“对于在路由后离开接口 eth0 的数据包,将其源地址更改为 eth0 的接口地址”。

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

这些都不能让你的 Linux 系统变成路由器。这是通过执行 sysctl -w net.ipv4.ip_forward=1 或 echo 1 > /proc/sys/net/ipv4/ip_forward 启用的单独行为(对于 IPv4)。

路由只是意味着系统将根据该流量的目的地对它接收到的流量进行愚蠢的处理;iptables NAT 的东西允许你改变路由发生后发出的数据包。

这是一个非常简单的概述,通过以不同的方式配置它可以获得更多的复杂性和可能性。

于 2020-09-14T00:48:10.550 回答