使用 Traefik 的路由路径
Routing paths with Traefik
目前我正在尝试使用 Traefik 为一些 docker 容器设置一个 loadbalancer/reverse 代理。我在配置 Treafik 以使用某些前缀路径使我的应用程序可用时遇到问题。我能够使用 Docker 和 Docker 组合获得基本的 Traefik 配置 运行,基于 this example。问题是我能够让 'whoamI' 容器在路径上可访问,但我的应用程序和其他容器不能访问。
例如,我创建了一个 docker-compose 文件(见下文)来启动 whoamI 容器和五个 Portainer 容器(以便人们可以重新创建场景)。我希望 woamI 在 /wai
可用,Portainer 在 /portainer1
.
相反,我可以访问 whoamI 网络服务器(通过 /wai
)而不是 Portainer(通过 /portainer1
)。但是,我可以在 /portainer2
联系到 Portainer。这两者在 Traefik 配置上的唯一区别是使用 'PathStrip' 而不是 'Path'。然而,令人讨厌的是,当我导航到 /portainer2
时,我只能获得一个白页;仅加载页面标题和一些 html。我还启动了一个暴露给主机的 Portainer 容器,以验证预期的行为(一个普通的 Portainer 页面)。另请参阅下面的附图。
编辑:
有趣的是,我还能够在 /portainer4/
(但不是 /portainer4
)到达 Portainer,结果是相同的白页。导航到 /portainer2/
和 /portainer4/
的区别在于我注意到 Traefik 中有一些额外的日志记录(见下文)。通过 /portainer4/
导航到 Portainer 时,日志中会显示三行额外的行,指示 400 状态。经过一番调查,我发现这是由于我的浏览器试图加载其他文件(即 javascript 文件、网站图标和样式表)所致。因此,当在 /portainer4/
访问 Portainer 时,我的浏览器知道它需要获取那些额外的文件并尝试这样做(导航到 /portainer2
时不会发生这种情况)。当尝试自己访问文件时,例如,导航到 /portainer4/ico/favicon.ico
,我得到 400 Bad Request
。最后,当导航到 /portainer2/ico/favicon.ico
时看到 404 page not found
.
根据这些结果,我想知道:
- 为什么我无法通过 /portainer1 联系到 Portainer,而是通过
/portainer2?
- 为什么我导航到 时看不到完整的 Portainer 页面
/portainer2?
- 为什么
/portainer2/
和 /portainer4/
之间访问文件(例如网站图标)的行为存在差异
- 400 Bad Request 的实际含义以及 if/how 这个问题可以解决
非常感谢一些正确方向的指示
部分截图:
docker-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/
和 /portainer4/
后生成的额外 Traefik 日志记录:
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"
今天早上我找到了解决方案。在这种情况下,正确的方法应该是使用 PathPrefixStrip 规则。但是,作为 mentioned here,在规则末尾放置 /
会破坏设置。我通过删除 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/
时,我看到了 portainer 页面。但是,当我导航到 <myIP>/portainer
.
时,我仍然会看到前面提到的白页
对于未来的 googler
没有斜杠就不能工作的原因是一个存在的问题
https://github.com/containous/traefik/issues/563
对于 v2 docker 标签
- "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=/$"
- "traefik.http.middlewares.portainer-redirectregex.redirectregex.regex=^(.*)/portainer$$"
- "traefik.http.middlewares.portainer-redirectregex.redirectregex.replacement=$/portainer/"
目前我正在尝试使用 Traefik 为一些 docker 容器设置一个 loadbalancer/reverse 代理。我在配置 Treafik 以使用某些前缀路径使我的应用程序可用时遇到问题。我能够使用 Docker 和 Docker 组合获得基本的 Traefik 配置 运行,基于 this example。问题是我能够让 'whoamI' 容器在路径上可访问,但我的应用程序和其他容器不能访问。
例如,我创建了一个 docker-compose 文件(见下文)来启动 whoamI 容器和五个 Portainer 容器(以便人们可以重新创建场景)。我希望 woamI 在 /wai
可用,Portainer 在 /portainer1
.
相反,我可以访问 whoamI 网络服务器(通过 /wai
)而不是 Portainer(通过 /portainer1
)。但是,我可以在 /portainer2
联系到 Portainer。这两者在 Traefik 配置上的唯一区别是使用 'PathStrip' 而不是 'Path'。然而,令人讨厌的是,当我导航到 /portainer2
时,我只能获得一个白页;仅加载页面标题和一些 html。我还启动了一个暴露给主机的 Portainer 容器,以验证预期的行为(一个普通的 Portainer 页面)。另请参阅下面的附图。
编辑:
有趣的是,我还能够在 /portainer4/
(但不是 /portainer4
)到达 Portainer,结果是相同的白页。导航到 /portainer2/
和 /portainer4/
的区别在于我注意到 Traefik 中有一些额外的日志记录(见下文)。通过 /portainer4/
导航到 Portainer 时,日志中会显示三行额外的行,指示 400 状态。经过一番调查,我发现这是由于我的浏览器试图加载其他文件(即 javascript 文件、网站图标和样式表)所致。因此,当在 /portainer4/
访问 Portainer 时,我的浏览器知道它需要获取那些额外的文件并尝试这样做(导航到 /portainer2
时不会发生这种情况)。当尝试自己访问文件时,例如,导航到 /portainer4/ico/favicon.ico
,我得到 400 Bad Request
。最后,当导航到 /portainer2/ico/favicon.ico
时看到 404 page not found
.
根据这些结果,我想知道:
- 为什么我无法通过 /portainer1 联系到 Portainer,而是通过 /portainer2?
- 为什么我导航到 时看不到完整的 Portainer 页面 /portainer2?
- 为什么
/portainer2/
和/portainer4/
之间访问文件(例如网站图标)的行为存在差异
- 400 Bad Request 的实际含义以及 if/how 这个问题可以解决
非常感谢一些正确方向的指示
部分截图:
docker-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/
和 /portainer4/
后生成的额外 Traefik 日志记录:
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"
今天早上我找到了解决方案。在这种情况下,正确的方法应该是使用 PathPrefixStrip 规则。但是,作为 mentioned here,在规则末尾放置 /
会破坏设置。我通过删除 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/
时,我看到了 portainer 页面。但是,当我导航到 <myIP>/portainer
.
对于未来的 googler
没有斜杠就不能工作的原因是一个存在的问题
https://github.com/containous/traefik/issues/563
对于 v2 docker 标签
- "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=/$"
- "traefik.http.middlewares.portainer-redirectregex.redirectregex.regex=^(.*)/portainer$$"
- "traefik.http.middlewares.portainer-redirectregex.redirectregex.replacement=$/portainer/"