【问题标题】:Reverse-proxy microservices with Docker and Traefik使用 Docker 和 Traefik 的反向代理微服务
【发布时间】:2018-06-15 11:28:01
【问题描述】:

我的微服务很少,我们称之为food-msreceipt-msingredients-msfrontend,React App 使用这些微服务。 他们每个人都在/api/[methods]公开API。

我想使用 Docker 和带有下一个属性的 docker-compose 创建生产和开发环境:

  • 应用程序应该在单个主机上可用。例如,在生产主机中应该是http://food-app.test,对于开发它应该是(理想情况下)本地主机

  • 每个微服务和前端都应位于单个主机上,但路径不同。例如,food-ms API 应位于 localhost/food/apireceipt-ms API 应位于 localhost/receipt/api 等。前端应位于 localhost root / 路径。

  • 理想情况下,我希望能够在外部容器中运行一些服务以便于调试,但仍可通过localhost/{service}/api 进行反向代理。

我找到了一个traefik 反向代理,并对其进行了一些试验,但遇到了问题:

  1. 如何使应用程序在某些可预测的域中可用,例如 localhost。目前,我可以通过在 Host 标头(如 <container-name>.<network-name>.docker.localhost)中指定一个奇怪的主机来将请求代理到特定后端 似乎traefik.toml 中描述的前端没有效果。
  2. 如何根据路径将请求从一个前端路由到不同的后端?
  3. 如何将请求路由到外部 IP 和端口(我想用它在容器外运行服务以进行调试)?我应该在 docker 中使用 host 网络吗?

提前致谢。

这是我的traefik.toml

defaultEntryPoints = ["http"]

[entryPoints]
    [entryPoints.http]
    address = ":80"

[file]

[frontends]
    [frontends.food]
    entrypoints = ["http"]
    backend="food"

    [frontends.receipts]
    entrypoints = ["http"]
    backend="receipts"

那些前端似乎没有得到应用,因​​为如果我推荐它们,仪表板不会改变。

【问题讨论】:

  • 对不起,我不知道traefik,但建议你可以使用广泛使用的nginx反向代理作为反向代理服务器。

标签: docker docker-compose traefik


【解决方案1】:

花了一些时间后,我的问题得到了一些成功。

首先,尝试将 traefik 作为本地应用程序而不是 docker 容器运行要容易得多。

所以我在本地安装了 traefik (brew install traefik) 并使用下一个命令行运行它:

traefik --web --configfile=./docker/traefik-local.toml --logLevel=INFO

有一个已弃用但有效的参数 --web 同时可以省略。

然后我创建了一个带有配置的 TOML 文件

defaultEntryPoints = ["http"]
[entryPoints]
    [entryPoints.http]
    address = ":80"

[file]

[frontends]
    [frontends.fin]
        entrypoints = ["http"]
        backend="fin"
        [frontends.fin.routes.matchUrl]
            rule="PathPrefixStrip:/api/fin"
        [frontends.fin.routes.rewriteUrl]
            rule = "AddPrefix: /api"

    [frontends.proj]
    entrypoints = ["http"]
    backend="proj"
        [frontends.proj.routes.matchUrl]
            rule="PathPrefixStrip: /api/proj"
        [frontends.proj.routes.rewriteUrl]
            rule = "AddPrefix: /api"


[backends]
    [backends.fin]
        #
        [backends.fin.servers.main]
        url = "http://localhost:81"
    [backends.proj]
        #
        [backends.proj.servers.main]
        url = "http://localhost:82"

服务名称与最初的答案不同,但思路应该很清楚。

首先,在描述前端和后端之前,有一个强制性的[file] 指令。没有它就不行,啊 :(

服务在 docker 容器中运行,并为fin 公开端口 81,为proj 公开端口 82。由于现在 traefik 工作在 docker 隔离网络之外,它支持原生运行的应用程序和容器中的应用程序。

然后描述了两个前端。最初我也遇到了规则问题:PathPrefixStripMatcher 但它也通过删除路径前缀修改路径。

所以现在它可以在本地运行时按我的意愿运行,并且应该更容易让它在 Docker 中运行。

【讨论】:

    【解决方案2】:

    嗯,关于在 Docker 中运行所有这些东西的更多信息。

    首先,traefik 有一个配置提供的概念,它可以在其中获取有关后端、前端、规则、映射等的所有信息。

    对于 Docker,至少有两种方法:在 docker-compose.yml 中的服务上使用标签或使用 file 配置提供程序。

    这里我会考虑使用文件配置提供程序。 要使用它,您需要将[file] 部分和下面的配置添加到 traefik 配置或使用单独的文件。

    我使用了分隔文件,启用并通过添加--file --file.filename=/etc/traefik/traefik.file.toml 命令行参数来指向它。

    请记住,如果您使用 Windows 和 docker-toolbox,您需要在 Virtual Box 中添加共享文件夹并添加相对于该文件夹的映射,这很痛苦,是的。

    之后,其他事情就简单了。

    要在 traefik 配置的 [backends] 部分中寻址服务,请使用来自 docker-compose.yml 的服务名称。要公开代理,请使用端口映射。

    这是我的docker-compose.yaml

    version: "3"
    services:     
    
      financial-service:
        build:
          context: .
          dockerfile: ./docker/financial.Dockerfile
    
      project-service:
        build:
          context: .
          dockerfile: ./docker/project.Dockerfile
    
      traefik:
        image: traefik
        command: --web --docker --file --file.filename=/etc/traefik/traefik.file.toml --docker.domain=docker.localhost --logLevel=INFO --configFile=/etc/traefik/traefik.toml
        ports:
          - "80:80"
          - "8088:8080"
          # - "44:443"
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          # On Windows with docker-toolbox:
          #    this should be mounted as a shared folder in VirtualBox.
          # Mount via VB UI, don't forget to restart docker machine.
    
          # - /rd-erp/docker:/etc/traefik/
          # On normal OS
          - ./docker:/etc/traefik/
        depends_on:
          - project-service
          - financial-service
    

    这里是 Docker 的 traefik.file.toml

    [frontends]
        [frontends.fin]
            entrypoints = ["http"]
            backend="fin"
            [frontends.fin.routes.matchUrl]
                rule="PathPrefixStrip:/api/fin"
            [frontends.fin.routes.rewriteUrl]
                rule = "AddPrefix: /api"
    
        [frontends.proj]
        entrypoints = ["http"]
        backend="proj"
            [frontends.proj.routes.matchUrl]
                rule="PathPrefixStrip: /api/proj"
            [frontends.proj.routes.rewriteUrl]
                rule = "AddPrefix: /api"
    
    
    [backends]
        [backends.fin]
            #
            [backends.fin.servers.main]
            url = "http://financial-service"
        [backends.proj]
            #
            [backends.proj.servers.main]
            url = "http://project-service"
    

    下一步是在容器外运行一些服务,并且仍然能够从 localhost 反向代理它。

    【讨论】:

      【解决方案3】:

      可能是最后一部分:从 Docker 连接到在主机上运行的服务,在我们的例子中,从 traefik 容器连接。

      1. 在主机上运行服务
      2. 在 Docker 18.3+ 中使用特殊域 host.docker.internal 并且不要忘记指定协议和端口。

        在早期的 Docker 中可能需要使用host 网络模式。这将涉及额外的服务配置以不与繁忙的端口重叠,但可能不需要更改在容器外运行服务的配置。

      3. 在没有您要调试的服务的情况下运行 docker-compose:

        docker-compose up --no-deps traefik financial-service

      4. 享受

      如果您使用--file.filename 提供的分隔文件中的配置,不要忘记从traefik.toml 中删除[file] 部分,似乎[file] 部分优先。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-14
        • 1970-01-01
        • 2018-07-29
        • 1970-01-01
        • 1970-01-01
        • 2021-09-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多