Traefik docker 配置基于路径的路由重写

Pau*_*ney 1 docker traefik

traefik 的 2 天新手,需要帮助了解 traefik v2 中的 istm 是基本的第一个 docker 提供程序配置...

我尝试搜索文档,但只是不知道如何做我想要的事情。

我想要像这样的 docker 容器

  • 应用程序1
  • 应用程序2
  • 应用程序3

并通过 traefik 通过 url 访问这些内容

  • http://app.mydomain.com/app1
  • http://app.mydomain.com/app2
  • http://app.mydomain.com/app3

但是,应用程序本身不喜欢这些额外的路径,因此我想从访问路径中删除前缀,以便应用程序看不到它们。

如果我访问,http://app.mydomain.com/app2/foo我希望容器app2接收请求http://{container.ip.addr}}/foo

作为重现,我知道部分有效的配置在我的 traefik 中具有以下内容docker-compose.yml

version: "3"
services:
  traefik:
    image: "traefik:v2.5.4"
    command:
      - --entrypoints.web.address=:80
      - --providers.docker=true
      - --api
      - --api.insecure=true
      - --api.dashboard=true
      - --providers.file.directory=/etc/traefik/dynamic
      - --providers.docker.defaultRule=Host(`app.mydomain.com`) && PathPrefix(`/{{ index .Labels "com.docker.compose.service" }}`)
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  app1:
    image: containous/whoami:v1.3.0
  app2:
    image: containous/whoami:v1.3.0
  app3:
    image: containous/whoami:v1.3.0
Run Code Online (Sandbox Code Playgroud)

添加到 后127.0.0.1 app.mydomain.com,对此\etc\hosts进行卷曲以http://app.mydomain.com/app{1,2,3}/foo路由到正确的服务,但它们收到的请求路径是/app1/foo, /app2/foo/app3/foo而我希望它们全部都得到/foo

我觉得我希望能够将以下内容添加到 docker-compose 中的命令行参数中:

--providers.docker.middleware.default-stripprefix.stripprefix.prefixes=`/{{ index .Labels "com.docker.compose.service" }}`
Run Code Online (Sandbox Code Playgroud)

但它不起作用(错误command traefik error: failed to decode configuration from flags: field not found, node: middleware:)

我找不到任何表明正确的命令行参数可能是什么的文档。

我想它可能需要在一个动态配置文件中(我已经看到这与 tls 配置太混乱了,但希望在这个阶段将所有这些都保留在重现之外!)但似乎又找不到什么正确的配置是默认中间件。

我可以找到很多参考(并让它工作),我必须在每个容器的标签中指定它,但我更愿意在 traefik 配置本身中使用一次性条目来默认它。

我已经为此绞尽脑汁两天了。我尝试搜索文档网站、这个社区和 googleverse,但没有运气。对我来说这似乎是一个“101”配置!:-)

请有人帮助我不仅解决我的问题,而且可以选择教我如何自己在文档网站中找到解决方案。我已经看到很多人提到该文档网站很好,但对我来说,对于 v2 来说,它们似乎很少。

Pau*_*ney 5

好的,所以我会发布我的答案,以防有人发现这个并想知道。

中间件需要在 Traefik动态配置文件中定义。

然后可以在静态配置文件的端点规范中引用它。

一旦我需要一个单独的文件进行动态配置,我决定也使用一个文件进行静态配置,而不是命令行参数。

所以 3 文件解决方案是:

docker-compose.yml

version: "3"
services:
  traefik:
    image: "traefik:v2.5.4"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "{path}/traefik.yml:/etc/traefik/traefik.yml:ro"
      - "{path}/dynamic.yml:/etc/traefik/dynamic.yml:ro"

  app1:
    image: containous/whoami:v1.3.0
  app2:
    image: containous/whoami:v1.3.0
  app3:
    image: containous/whoami:v1.3.0
Run Code Online (Sandbox Code Playgroud)

traefik.yml

api:
  insecure: true
  dashboard: true
providers:
  docker:
    defaultRule: "Host(`app.mydomain.com`) && PathPrefix(`/{{ index .Labels \"com.docker.compose.service\" }}`)"
  file:
    filename: "/etc/traefik/dynamic.yml"
entrypoints:
  web:
    address: ":80"
    http:
      middlewares:
        - root-stripprefix@file
Run Code Online (Sandbox Code Playgroud)

动态.yml

http:
  middlewares:
    root-stripprefix:
      stripPrefixRegex:
        regex:
          - "/[^/]+"
Run Code Online (Sandbox Code Playgroud)

动态配置指定了一个 StripPrefix 中间件 - 我实际上使用 StripPrefixRegex 来获取路径第一部分中的任何内容,而无需指定它。

然后,该中间件与 Web 端点相关联,因此它适用于使用它的所有内容。

这相当简单地解决了问题,但在能够到达那里之前,了解 Traefik 文档和配置系统是一个相当长的旅程。如果需要更多细节,我已经在这篇文章中更详细地写了这段旅程。

关于现实世界容器间连接的额外说明...

另请注意,在具有单独 docker-compose 文件的更真实示例中,有必要通过将详细信息附加到每个 docker-compose 文件来允许 traefik 和应用程序容器通过连接到同一网络进行通信,例如:

service:
  app1:
...
    networks:
      - proxy
networks:
  proxy:
    external: true
    name: proxy
Run Code Online (Sandbox Code Playgroud)

第一次使用一次性命令创建网络后docker network create proxy

我再次更详细地写下了对此的想法 - 请参阅这篇文章

希望这可以帮助某人至少节省我在这方面花费的一些时间。