13

目前我正在尝试使用 Traefik 为一些 docker 容器设置负载均衡器/反向代理。我在配置 Treafik 以使用某些前缀路径使我的应用程序可用时遇到问题。基于这个示例,我能够使用 Docker 和 Docker compose 运行基本的 Traefik 配置。问题是我能够在路径上访问“whoamI”容器,但不能访问我的应用程序和其他容器。

例如,我创建了一个 docker-compose 文件(见下文)来启动 whoami 容器,以及五个 Portainer 容器(以便人们可以重新创建场景)。我希望 woamI/wai和 Portainer 可以在/portainer1.

相反,我可以访问 whoami 网络服务器(通过/wai)而不是 Portainer(通过/portainer1)。但是,我可以在/portainer2. 这两者之间的 Traefik 配置的唯一区别是使用“PathStrip”而不是“Path”。然而,令人讨厌的是,我只能在导航到时获得一个白页/portainer2;只有页面标题和一些 html 被加载。我还启动了一个暴露给主机的 Portainer 容器,以验证预期的行为(一个正常的 Portainer 页面)。另请参阅下面的附图。

编辑:

有趣的是,我也能够在/portainer4/(但不是/portainer4)到达 Portainer,从而得到相同的白页。/portainer2/导航到和之间的区别在于/portainer4/我注意到 Traefik 中有一些额外的日志记录(见下文)。通过 导航到 Portainer 时/portainer4/,日志中会显示三行额外的行,指示 400 状态。经过一番调查,我发现这是因为我的浏览器试图加载其他文件(即一个 javascript 文件、一个网站图标和一个样式表)。因此,当在我的浏览器上访问 Portainer 时,/portainer4/它知道它需要获取那些额外的文件并尝试这样做(导航到 时不会发生这种情况/portainer2)。当尝试自己访问文件时,例如,导航到/portainer4/ico/favicon.ico,我得到一个400 Bad Request. 最后,当导航到/portainer2/ico/favicon.ico是看到一个404 page not found

基于这些结果,我想知道:

  • 为什么我无法在 /portainer1 上访问 Portainer,而是在 /portainer2 上?
  • 为什么导航到 /portainer2 时看不到完整的 Portainer 页面?
  • 为什么在访问文件(例如网站图标)/portainer2//portainer4/
  • 400 Bad Request 的实际含义以及是否/如何解决此问题

我真的很感激一些正确方向的指示

一些截图: 不同的 Treafik 路径

码头工人-compose.yml:

version: '2'

services:   
  traefik:
    container_name: traefik
    image: traefik
    command: --web --docker --docker.domain=docker.localhost --logLevel=DEBUG
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /dev/null:/traefik.toml
    labels:
        - "traefik.enable=false"      
  whoami:
    image: emilevauge/whoami
    labels:
      - "traefik.backend=whoami"
      - "traefik.frontend.rule=Path: /wai/"   
  portainer1:
    image: portainer/portainer
    labels:
      - "traefik.backend=portainer1"
      - "traefik.frontend.rule=Path: /portainer1/"   
  portainer2:
    image: portainer/portainer
    labels:
      - "traefik.backend=portainer2"
      - "traefik.frontend.rule=PathStrip: /portainer2/"      
  portainer:
    image: portainer/portainer
    ports:
      - "9000:9000"
    labels:
        - "traefik.enable=false"

/wai分别在访问、/portainer1/<myIP>/portainer2//portainer3/后生成的额外 Traefik 日志记录/portainer4/

time="2017-01-13T14:33:16Z" level=debug msg="Round trip: http://172.19.0.2:80, code: 200, duration: 1.000627ms"
time="2017-01-13T14:33:22Z" level=debug msg="Round trip: http://172.19.0.7:9000, code: 404, duration: 1.006089ms"
time="2017-01-13T14:33:24Z" level=debug msg="Round trip: http://172.19.0.3:9000, code: 200, duration: 1.160158ms"
time="2017-01-13T14:33:26Z" level=debug msg="Round trip: http://172.20.0.5:9000, code: 404, duration: 1.291309ms"
time="2017-01-13T14:33:29Z" level=debug msg="Round trip: http://172.20.0.4:9000, code: 200, duration: 2.788462ms"
time="2017-01-13T14:33:29Z" level=debug msg="Round trip: http://172.20.0.4:9000, code: 400, duration: 777.073µs"
time="2017-01-13T14:33:30Z" level=debug msg="Round trip: http://172.20.0.4:9000, code: 400, duration: 1.780621ms"
time="2017-01-13T14:33:30Z" level=debug msg="Round trip: http://172.20.0.4:9000, code: 400, duration: 1.780341ms"
4

2 回答 2

13

今天早上我找到了解决方案。在这种情况下,正确的方法应该是使用 PathPrefixStrip 规则。但是,正如这里所提到/的,在规则末尾添加 a 会破坏设置。我通过在规则/末尾删除来创建一个工作配置。PathPrefixStrip: /portainer4/所以这个 docker-compose 配置对我有用:

version: '2'

services:
  traefik:
    container_name: traefik2
    image: traefik
    command: --web --docker --docker.domain=docker.localhost --logLevel=DEBUG
    ports:
      - "80:80"
      - "8081:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /dev/null:/traefik.toml
    labels:
        - "traefik.enable=false"
  portainer:
    image: portainer/portainer
    labels:
      - "traefik.backend=portainer"
      - "traefik.frontend.rule=PathPrefixStrip: /portainer"

现在,当我导航到时,<myIP>/portainer/我看到了搬运工页面。但是,当我导航到<myIP>/portainer.

于 2017-01-16T19:46:54.917 回答
7

为未来的谷歌人

没有斜线它不起作用的原因是一个现有的问题

https://github.com/containous/traefik/issues/563

对于 v2 泊坞窗标签

      - "traefik.http.routers.portainer-secure.rule=Host(`your-domain.com`) && PathPrefix(`/portainer`)"

      - "traefik.http.routers.portainer-secure.middlewares=portainer-redirectregex, portainer-replacepathregex"

      - "traefik.http.middlewares.portainer-replacepathregex.replacepathregex.regex=^/portainer/(.*)"
      - "traefik.http.middlewares.portainer-replacepathregex.replacepathregex.replacement=/$$1"
      - "traefik.http.middlewares.portainer-redirectregex.redirectregex.regex=^(.*)/portainer$$"
      - "traefik.http.middlewares.portainer-redirectregex.redirectregex.replacement=$$1/portainer/"

于 2020-05-23T18:41:50.807 回答