首页 文章

使用Docker和Traefik反向代理微服务

提问于
浏览
1

我有几个微服务,我们称它为 food-msreceipt-msingredients-msfrontend ,React App消耗这些微服务 . 他们每个人都在 /api/[methods] 公开API .

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

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

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

  • 理想情况下,我希望能够运行一些服务 outside 容器以便于调试,但仍然可以通过 localhost/{service}/api 进行反向代理和提供 .

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

  • 如何在某个可预测的域中提供应用程序,例如 localhost . 目前我能够通过在 Host 标头中指定一个奇怪的主机来代理特定后端的请求,如 <container-name>.<network-name>.docker.localhost 似乎 traefik.toml 中描述的前端没有效果 .

  • 如何根据路径将请求从一个前端路由到不同的后端?

  • 如何将请求路由到外部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"

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

3 回答

  • 1

    花了一些时间后,我的问题取得了一些成功 .

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

    所以我在本地安装了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] 指令 . 没有它它不起作用,arghh :(

    服务在docker容器中运行,并为 fin 公开端口81,为 proj 公开82 . 从现在开始,traefik在docker isolated网络之外工作,它支持在容器中本机运行应用程序和应用程序 .

    然后描述了两个前端 . 最初我也遇到了规则问题: PathPrefixStrip 是Matcher,但它也通过删除路径前缀来修改路径 .

    所以现在它可以按照我想要的本地运行方式工作,并且它应该更容易让它在Docker中运行 .

  • 0

    好吧,关于在Docker中运行所有内容的更多信息 .

    首先, traefik 有一个配置提供的概念,它可以获得有关后端,前端,规则,映射等的所有信息 .

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

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

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

    Remember if you use Windows and docker-toolbox you need to add shared folder in Virtual Box and add mapping relative to that folder, that's a pain, yes.

    在那之后,另一件事很容易 .

    要解决traefik config的 [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反向代理它 .

  • 0

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

    • 在主机上运行服务

    • 在Docker 18.3中使用特殊域 host.docker.internal 并且不要忘记指定协议和端口 .

    在早期的Docker中可能需要使用 host 网络模式 . 这将涉及额外配置服务,以便更改配置以在容器外运行服务 .

    • 运行docker-compose,无需调试服务:

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

    • 享受

    Don't forget to remove [file] section from traefik.toml if you use configuration in separated file provided by --file.filename, seems [file] section takes precedences.

相关问题