为什么我无法通过 HTTPS 访问我的 traefik 仪表板?

Why can't I reach my traefik dashboard via HTTPS?

我正在尝试 运行 我的 docker swarm 集群上的 traefik 容器。因为我们使用的是 TLS 加密通信,所以我希望 traefik 仪表板可以通过 https 访问。

在我的浏览器中,我尝试通过 https://my.docker.manager 通过 docker swarm 管理器主机名访问 traefik,因此我将我的主机证书和密钥安装到 traefik 服务中。

当我尝试在浏览器中打开 https://my.docker.manager 时,出现超时。

当我尝试直接在主机上 curl https://my.docker.manager (my.docker.manager) 时,我收到 HTTP 代码 403 作为响应

我的 traefik 配置:

debug=true
logLevel = "DEBUG"

defaultEntryPoints = ["http","https"]
[entryPoints]
 [entryPoints.http]
  address = ":80"
  [entryPoints.http.redirect]
   entryPoint = "https"

 [entryPoints.https]
  address = ":443"
  [entryPoints.https.tls]
   [[entryPoints.https.tls.certificates]]
    certFile = "/etc/traefik/certs/my.docker.manager.crt"
    keyFile = "/etc/traefik/certs/my.docker.manager.key"
   [entryPoints.https.tls.defaultCertificate]
    certFile = "/etc/traefik/certs/my.docker.manager.crt"
    keyFile = "/etc/traefik/certs/my.docker.manager.key"

[api]
 address = ":8080"

[docker]
 watch = true
 swarmMode = true

我的 traefik 组合文件:

version: "3.7"

services:
  traefik:
    image: traefik
    ports:
      - 80:80
      - 443:443
    networks:
      - devops-net
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /mnt/docker-data/secrets/certs/:/etc/traefik/certs/
    configs:
      - source: traefik.conf
        target: /etc/traefik/traefik.toml
    deploy:
      placement:
        constraints:
          - node.role == manager
      labels:
        - "traefik.docker.network=devops-net"
        - "traefik.frontend.rule=Host:my.docker.manager"
        - "traefik.port=8080"

networks:
  devops-net:
    driver: overlay
    external: true

configs:
  traefik.conf:
    external: true

如本文 (https://www.digitalocean.com/community/tutorials/how-to-use-traefik-as-a-reverse-proxy-for-docker-containers-on-ubuntu-16-04 中所述,当我调用 https://my.docker.manager 在我的浏览器中。但我只会超时。使用 curl https://my.docker.manager 时,我得到 HTTP 代码 403。我遵循了上述文章,但有两个不同之处: 1)我没有配置凭据 2) 我使用我的主机自己的证书而不是 letsencrypt

与此同时,我找到了问题的原因(不确定什么是最佳解决方案)。如果有人感兴趣,我会尽力解释。

我有一个由三个节点组成的 Swarm,在网络 prod.company.de

我的客户端在另一个网络中intranet.comnpany.de

我的 swarm 管理器的地址是 docker-manager.prod.company.de。在此主机上,我部署了 traefik 服务,我想通过 https://docker-manager.prod.company.de 访问(这是端口 443,因为 traefik 配置转发到容器内 8080 上的 traefik 仪表板)。

如果我跟踪我的网络流量,我可以看到来自客户端浏览器的 https 请求 (https://docker-manager.prod.company.de) 到达服务器,然后流量被转发到 docker_gwbridge 地址 17.18.0.2 .但是由于 docker NAT 配置,答案找不到返回我的客户端的方式。

iptables -t nat -L -v

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    8   504 MASQUERADE  all  --  any    docker_gwbridge  anywhere             anywhere             ADDRTYPE match src-type LOCAL
    0     0 MASQUERADE  all  --  any    !docker0  172.17.0.0/16        anywhere
    0     0 MASQUERADE  all  --  any    !docker_gwbridge  172.18.0.0/16        anywhere

MASQERADE 表示请求的源 IP 应替换为网桥 IP(在我的示例中为 172.18.0.1),以便将答案路由回该 IP。在上面的例子中,规则 8 504 MASQUERADE all -- any docker_gwbridge anywhere anywhere 会这样做,但它仅限于 ADDRTYPE match src-type LOCAL 来自 LOCAL 的请求,这意味着在 docker 主机上使用浏览器是可行的,但是我的来自客户端的连接不起作用,因为答案找不到返回我的客户端地址的方式。

目前,我向我的 iptables 添加了一条 NAT 规则: iptables -t nat -A POSTROUTING -o docker_gwbridge -j MASQUERADE

这导致

1    52 MASQUERADE  all  --  any    docker_gwbridge  anywhere             anywhere

之后,在客户端的浏览器中打开 https://docker-manager.prod.company.de 时,我可以看到 traefik 仪表板。

但我不明白,为什么我必须这样做,因为我在任何文档中都没有发现任何相关内容,而且我认为我的用例并不罕见。这就是为什么我会很高兴,如果有人可以看看这个 post 并可能检查我是否做错了其他事情或向我解释,为什么我必须做这些事情才能使标准用例正常工作。

亲切的问候