是否可以将Traefik限制为当前(docker-compose)堆栈?

时间:2017-10-04 23:58:02

标签: docker docker-compose rancher traefik

目的

我有一台运行Rancher(Docker)的服务器。在那个服务器中,我有几个不相关的堆栈。

我想让Traefik成为该堆栈的主要交互点。并根据路径对不同容器的请求进行负载均衡/代理。

我想让它将/api的流量发送到后端server服务。并将/的流量发送到frontend服务。

当前状态

这是我docker-compose.yml的精简版,仅显示相关服务:

version: '2'
services:
  server:
    image: server
    labels:
      - "traefik.frontend.rule=PathPrefix:/api"
      - "traefik.enable=true"
      - "traefik.port=80"
  frontend:
    image: frontend
    labels:
      - "traefik.frontend.rule=PathPrefix:/"
      - "traefik.enable=true"
      - "traefik.port=80"
  proxy:
    image: traefik:v1.4
    command: --web --accessLog --rancher --rancher.exposedbydefault=false --rancher.metadata=true
    volumes:
      - /dev/null:/traefik.toml

然后使用侦听公共端口的Rancher负载均衡器,我将请求重定向到app1.example.com到我的proxy服务。然后它接收请求并根据路径将流量重定向到两个容器中的每一个。

我还将流量重定向到traefik.app1.example.com到同一proxy服务,重定向到端口8080以访问网络用户界面。

如果我只有一个堆栈,它就可以工作。

问题

如果我添加另一个堆栈(或者如果我复制该堆栈)并且使用Traefik标签提供更多服务,proxy中的app1将会读取app2中服务的标签,宣告Traefik标签的任何其他堆栈。

然后,在proxy中的app1的Web UI中,我可以看到来自所有不同堆栈的所有后端。但是前端规则被覆盖了。

问题

到目前为止,我已经看到了大多数关于如何将Traefik用作独特的全局负载均衡器/代理的示例。我刚刚意识到我假设我还可以为每个堆栈或Traefik负载均衡器的层次结构创建隔离的Traefik实例。

在我看来,我似乎缺少一些配置或误解了一些东西。

但是,我还是要问,是否可以在每个堆栈中使用不同的隔离Traefik实例并使它们只监听并使用自己堆栈中的服务?

Rancher有可能吗?是否可以与任何其他Docker堆栈协调器(例如Swarm)?

如果可能,我缺少什么?

2 个答案:

答案 0 :(得分:4)

我想我找到了解决方法。

似乎我无法让Traefik直接在他自己的堆栈中使用服务。但似乎我可以使用Traefik constraints和标签来实现几乎相同。

这是我更新的docker-compose.yml使用约束和标记:

version: '2'
services:
  server:
    image: server
    labels:
      - "traefik.frontend.rule=PathPrefix:/api"
      - "traefik.enable=true"
      - "traefik.port=80"
      - "traefik.tags=app1.example.com"
  frontend:
    image: frontend
    labels:
      - "traefik.frontend.rule=PathPrefix:/"
      - "traefik.enable=true"
      - "traefik.port=80"
      - "traefik.tags=app1.example.com"
  proxy:
    image: traefik:v1.4
    command: --web --accessLog --constraints=tag==app1.example.com --rancher --rancher.exposedbydefault=false --rancher.metadata=true
    volumes:
      - /dev/null:/traefik.toml

它仅匹配具有Traefik标记app1.example.com的服务。这些标签可以是任何字符串,但由于我想要按特定域过滤,我只是使用我想过滤的域作为要使用的标签。

另请注意,标签是在带有标签traefik.tag的服务中设置的。

答案 1 :(得分:1)

如果您对此 Traefik v2 解决方案感兴趣,您可以使用 --providers.docker.constraints 选项来实现相同的结果。 因此,基本示例可能是:

services:
  traefik:
    image: traefik:v2.3
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.constraints=Label(`custom.label`,`custom-value`)"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  custom_service:
    image: ...
    labels:
      - "traefik.enable=true"
      - "custom.label=custom-value"

Docs