简体   繁体   English

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

[英]Traefik docker config path-based routing with rewriting

2-day-old newbie to traefik, needing help with what istm is a basic first docker provider config in traefik v2... traefik 的 2 天大新手,需要帮助了解 istm 是 traefik v2 中基本的第一个 docker 提供程序配置...

I've tried searching through the docs, but just can't figure out how to do what I'm after.我试过搜索文档,但就是不知道该怎么做。

I'd like to have docker containers like我想要 docker 容器,例如

  • app1应用程序1
  • app2应用程序2
  • app3应用程序3

And have these accessed through traefik via the urls并通过 traefik 通过 url 访问这些

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

However the apps themselves don't like these extra paths, so I'd like strip the prefix from the access paths so the apps don't see them.但是应用程序本身不喜欢这些额外的路径,所以我想从访问路径中去掉前缀,这样应用程序就看不到它们了。

If I access http://app.mydomain.com/app2/foo I'd like container app2 to get the request http://{container.ip.addr}}/foo如果我访问http://app.mydomain.com/app2/foo我希望容器app2获取请求http://{container.ip.addr}}/foo

As a repro, the config I do know partially works is having the following in my traefik docker-compose.yml :作为重现,我知道部分有效的配置在我的 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

Having added 127.0.0.1 app.mydomain.com to \etc\hosts , doing a curl to http://app.mydomain.com/app{1,2,3}/foo this routes to the correct service, but the request path they receive is /app1/foo , /app2/foo , /app3/foo whereas I'd like them all to get /foo . Having added 127.0.0.1 app.mydomain.com to \etc\hosts , doing a curl to http://app.mydomain.com/app{1,2,3}/foo this routes to the correct service, but the request他们收到的路径是/app1/foo/app2/foo/app3/foo而我希望他们都得到/foo

I feel like I'd like to be able to add the following to the command line params in the docker-compose:我觉得我希望能够将以下内容添加到 docker-compose 的命令行参数中:

--providers.docker.middleware.default-stripprefix.stripprefix.prefixes=`/{{ index .Labels "com.docker.compose.service" }}`

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

I can't find any docs that indicate what the correct commandline param(s) might be.我找不到任何说明正确命令行参数可能是什么的文档。

I'm thinking it might need to be in a dynamic config file (I've seen that too messing with tls config, but want to keep all that out of the repro at this stage.) but again can't seem to find what the correct config would be for a default middleware.我在想它可能需要在一个动态配置文件中(我已经看到这太弄乱了 tls 配置,但想在这个阶段把所有这些都排除在复制之外。)但似乎又找不到什么正确的配置将用于默认中间件。

I can find lots of refs (and get it working) where I have to specify it in labels on each container, but I'd prefer just to default this out with one-time entries in the traefik config itself.我可以找到很多引用(并让它工作),我必须在每个容器的标签中指定它,但我更愿意在 traefik 配置本身中使用一次性条目默认它。

I've been bashing my head against this for 2 days now. 2天来,我一直在为此痛心疾首。 I've tried searching the docs site, this community and the googleverse but without luck.我试过搜索文档站点、这个社区和 googleverse,但没有运气。 It seems like such a "101" config to me: :-)对我来说,这似乎是一个“101”配置::-)

Please would someone help me not only solve my issue but optionally teach me how I could have found the solution myself in the docs site.请有人帮助我不仅解决我的问题,还可以选择教我如何在文档站点中自己找到解决方案。 I've seen plenty of mentions of the doc site being good, but they seem quite sparse to me for v2.我已经看到很多关于 doc 网站的提及,但对于 v2.0 来说,它们对我来说似乎很少。

Ok, so I'll post the answer I went with in case anyone finds this and wants to know.好的,所以我会发布我的答案,以防有人发现并想知道。

The middleware needs to be defined in a Traefik dynamic config file.中间件需要在 Traefik动态配置文件中定义。

This can then be referred to in the endpoint specification in the static configuration file.这可以在static配置文件的端点规范中引用。

Once I needed a separate file for dynamic config, I decided to also use a file for the static config rather than command line args.一旦我需要一个单独的文件进行动态配置,我决定也使用 static 配置文件而不是命令行参数。

So the 3-file solution is:所以3文件解决方案是:

docker-compose.yml 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

traefik.yml 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

dynamic.yml动态的.yml

http:
  middlewares:
    root-stripprefix:
      stripPrefixRegex:
        regex:
          - "/[^/]+"

The dynamic configuration specifies a StripPrefix middleware - I've actually used StripPrefixRegex to grab whatever is in the first part of the path without having to specify it.动态配置指定了一个 StripPrefix 中间件——我实际上使用了 StripPrefixRegex 来抓取路径第一部分中的任何内容,而无需指定它。

This middleware is then associated with the web endpoint so it applies to everything using it.然后,此中间件与 web 端点相关联,因此它适用于所有使用它的东西。

This solves the issue fairly simply but it was quite a journey of understanding the Traefik docs and config system before being able to get there.这相当简单地解决了这个问题,但在能够到达那里之前,这是一个了解 Traefik 文档和配置系统的过程。 I've written up the journey in more detail in this post should more detail be wanted.如果需要更多详细信息,我已经在这篇文章中更详细地写了旅程。

An extra note on real-world inter-container connectivity...关于现实世界的容器间连接的额外说明......

Also note that in a more real-world example with separate docker-compose files, it's necessary to allow the traefik and app containers to communicate by connecting to the same network by appending details to each docker-compose file such as:另请注意,在具有单独 docker-compose 文件的更真实示例中,有必要通过将详细信息附加到每个 docker-compose 文件来允许 traefik 和应用程序容器通过连接到同一网络进行通信,例如:

service:
  app1:
...
    networks:
      - proxy
networks:
  proxy:
    external: true
    name: proxy

After first creating the network with the one-time command docker network create proxy .首先使用一次性命令docker network create proxy后。

Again I've written the thinking on this up in more detail - see this post .我再次更详细地写了关于这个的想法 - 请参阅这篇文章

Hope this helps someone save at least some of the days I've spent on this.希望这可以帮助某人至少节省一些我在这方面花费的时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM