Traefik v2反向代理无需Docker

huangapple go评论136阅读模式
英文:

Traefik v2 reverse proxy without Docker

问题

我有一个非常简单的 Golang 微服务(没有 Docker,只是一个简单的二进制文件),它在 GET 请求上返回简单的消息。

  1. curl -XGET 'http://localhost:36001/api/operability/list'

> {"message": "ping 123"}

现在我想通过 Traefik-v2 进行反向代理,所以我创建了配置文件 "traefik.toml":

  1. [global]
  2. checkNewVersion = false
  3. sendAnonymousUsage = false
  4. [entryPoints]
  5. [entryPoints.web]
  6. address = ":8090"
  7. [entryPoints.traefik]
  8. address = ":8091"
  9. [log]
  10. level = "DEBUG"
  11. filePath = "logs/traefik.log"
  12. [accessLog]
  13. filePath = "logs/access.log"
  14. [api]
  15. insecure = true
  16. dashboard = true
  17. [providers]
  18. [providers.file]
  19. filename = "traefik.toml"
  20. # dynamic conf
  21. [http]
  22. [http.routers]
  23. [http.routers.my-router]
  24. rule = "Path(`/proxy`)"
  25. service = "my-service"
  26. entryPoints = ["web"]
  27. [http.services]
  28. [http.services.my-service.loadBalancer]
  29. [[http.services.my-service.loadBalancer.servers]]
  30. url = "http://localhost:36001"

启动 Traefik(我使用的是二进制发行版):

  1. traefik --configFile=traefik.toml

现在端口 8091 上的仪表板正常工作,但我在反向代理请求方面遇到了困难。根据我的配置文件,我认为请求应该是这样的:

  1. curl -XGET 'http://localhost:8090/proxy/api/operability/list'

但是我得到的只是:

> 404 页面未找到

问题是:配置文件中是否有任何错误,还是只是请求的拼写错误?

编辑:
我的配置文件基于以下问题的答案:

  1. https://stackoverflow.com/questions/60227270/simple-reverse-proxy-example-with-traefik
  2. https://stackoverflow.com/questions/58496270/traefik-v2-as-a-reverse-proxy-without-docker

编辑 #2:
Traefik 版本信息:

  1. traefik version
  2. Version: 2.4.9
  3. Codename: livarot
  4. Go version: go1.16.5
  5. Built: 2021-06-21T16:17:58Z
  6. OS/Arch: windows/amd64
英文:

I have a dead simple Golang microservice (no Docker, just simple binary file) which returns simple message on GET-request.

  1. curl -XGET 'http://localhost:36001/api/operability/list'

> {"message": "ping 123"}

Now I want to do reverse proxy via Traefik-v2, so I've made configuration file "traefik.toml":

  1. [global]
  2. checkNewVersion = false
  3. sendAnonymousUsage = false
  4. [entryPoints]
  5. [entryPoints.web]
  6. address = ":8090"
  7. [entryPoints.traefik]
  8. address = ":8091"
  9. [log]
  10. level = "DEBUG"
  11. filePath = "logs/traefik.log"
  12. [accessLog]
  13. filePath = "logs/access.log"
  14. [api]
  15. insecure = true
  16. dashboard = true
  17. [providers]
  18. [providers.file]
  19. filename = "traefik.toml"
  20. # dynamic conf
  21. [http]
  22. [http.routers]
  23. [http.routers.my-router]
  24. rule = "Path(`/proxy`)"
  25. service = "my-service"
  26. entryPoints = ["web"]
  27. [http.services]
  28. [http.services.my-service.loadBalancer]
  29. [[http.services.my-service.loadBalancer.servers]]
  30. url = "http://localhost:36001"

Starting Traefik (I'm using binary distribution):

  1. traefik --configFile=traefik.toml

Now dashboard on port 8091 works like a charm, but I struggle with reverse proxy request. I suppose it should look like this (based on my configuration file):

  1. curl -XGET 'http://localhost:8090/proxy/api/operability/list'

But all I get it's just:
> 404 page not found

The question is: is there any mistake in configuration file or is it just a request typo?

edit:
My configuration file is based on answers in this questions:

  1. https://stackoverflow.com/questions/60227270/simple-reverse-proxy-example-with-traefik
  2. https://stackoverflow.com/questions/58496270/traefik-v2-as-a-reverse-proxy-without-docker

edit #2:
Traefik version info:

  1. traefik version
  2. Version: 2.4.9
  3. Codename: livarot
  4. Go version: go1.16.5
  5. Built: 2021-06-21T16:17:58Z
  6. OS/Arch: windows/amd64

答案1

得分: 3

我已经找到答案。

  1. 如果我决定使用Traefik将_/proxy_重定向到_/api/*_,那么我并不聪明。官方文档(https://doc.traefik.io/traefik/routing/routers/)中说道(我引用一下):

    如果你的服务只监听特定路径,请使用Path。例如,Path: /products将匹配/products,但不匹配/products/shoes。

    如果你的服务监听特定基础路径,并且还处理子路径的请求,请使用Prefix匹配器。例如,PathPrefix: /products将匹配/products,也将匹配/products/shoes和/products/shirts。由于路径被原样转发,你的服务应该监听/products。

  2. 我没有使用任何中间件来替换路径的子字符串。

现在给出一个示例。

首先,是main.go文件中的微服务代码:

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. )
  7. func handler(w http.ResponseWriter, r *http.Request) {
  8. fmt.Fprintf(w, `{"message": "ping 123"}`)
  9. }
  10. func main() {
  11. http.HandleFunc("/operability/list", handler)
  12. log.Fatal(http.ListenAndServe(":36001", nil))
  13. }

接下来是Traefik v2的配置文件config.toml:

  1. [global]
  2. checkNewVersion = false
  3. sendAnonymousUsage = false
  4. [entryPoints]
  5. [entryPoints.web]
  6. address = ":36000"
  7. [entryPoints.traefik]
  8. address = ":8091"
  9. [log]
  10. level = "DEBUG"
  11. filePath = "logs/traefik.log"
  12. [accessLog]
  13. filePath = "logs/access.log"
  14. [api]
  15. insecure = true
  16. dashboard = true
  17. [providers]
  18. [providers.file]
  19. debugLogGeneratedTemplate = true
  20. # Point this same file for dynamic configuration
  21. filename = "config.toml"
  22. watch = true
  23. [http]
  24. [http.middlewares]
  25. [http.middlewares.test-replacepathregex.replacePathRegex]
  26. # We need middleware to replace all "/proxy/" with "/api/"
  27. regex = "(?:^|\W)proxy(?:$|\W)"
  28. replacement = "/api/"
  29. [http.routers]
  30. [http.routers.my-router]
  31. # We need to handle all request with pathes defined as "/proxy/*"
  32. rule = "PathPrefix(`/proxy/`)"
  33. service = "my-service"
  34. entryPoints = ["web"]
  35. # Use of defined middleware for path replacement
  36. middlewares = ["test-replacepathregex"]
  37. [http.services]
  38. [http.services.my-service.loadBalancer]
  39. [[http.services.my-service.loadBalancer.servers]]
  40. url = "http://localhost:36001/"

启动微服务:

  1. go run main.go

启动Traefik:

  1. traefik --configFile config.toml

现在检查微服务是否正常工作:

curl -XGET 'http://localhost:36001/api/operability/list'

{"message": "ping 123"}

然后检查Traefik v2是否正常工作:

curl -XGET 'http://localhost:36000/proxy/operability/list'

{"message": "ping 123"}

英文:

I've managed to find the answer.

  1. I'm not that smart if I've decided that Traefik would take /proxy and simply redicrect all request to /api/*. The official docs (https://doc.traefik.io/traefik/routing/routers/) says that (I'm quoting):
    >> Use Path if your service listens on the exact path only. For instance, Path: /products would match /products but not /products/shoes.

>> Use a Prefix matcher if your service listens on a particular base path but also serves requests on sub-paths. For instance, PathPrefix: /products would match /products but also /products/shoes and /products/shirts. Since the path is forwarded as-is, your service is expected to listen on /products.

  1. I did not use any middleware for replacing substring of path

Now answer as example.

First at all: code for microservice in main.go file

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. )
  7. func handler(w http.ResponseWriter, r *http.Request) {
  8. fmt.Fprintf(w, "{\"message\": \"ping 123\"}")
  9. }
  10. func main() {
  11. http.HandleFunc("/operability/list", handler)
  12. log.Fatal(http.ListenAndServe(":36001", nil))
  13. }

Now, configuration file for Traefik v2 in config.tom file:

  1. [global]
  2. checkNewVersion = false
  3. sendAnonymousUsage = false
  4. [entryPoints]
  5. [entryPoints.web]
  6. address = ":36000"
  7. [entryPoints.traefik]
  8. address = ":8091"
  9. [log]
  10. level = "DEBUG"
  11. filePath = "logs/traefik.log"
  12. [accessLog]
  13. filePath = "logs/access.log"
  14. [api]
  15. insecure = true
  16. dashboard = true
  17. [providers]
  18. [providers.file]
  19. debugLogGeneratedTemplate = true
  20. # Point this same file for dynamic configuration
  21. filename = "config.toml"
  22. watch = true
  23. [http]
  24. [http.middlewares]
  25. [http.middlewares.test-replacepathregex.replacePathRegex]
  26. # We need middleware to replace all "/proxy/" with "/api/"
  27. regex = "(?:^|\\W)proxy(?:$|\\W)"
  28. replacement = "/api/"
  29. [http.routers]
  30. [http.routers.my-router]
  31. # We need to handle all request with pathes defined as "/proxy/*"
  32. rule = "PathPrefix(`/proxy/`)"
  33. service = "my-service"
  34. entryPoints = ["web"]
  35. # Use of defined middleware for path replacement
  36. middlewares = ["test-replacepathregex"]
  37. [http.services]
  38. [http.services.my-service.loadBalancer]
  39. [[http.services.my-service.loadBalancer.servers]]
  40. url = "http://localhost:36001/"

Start microservice:

  1. go run main.go

Start traefik:

  1. traefik --configFile config.toml

Now check if microservice works correctly:
> curl -XGET 'http://localhost:36001/api/operability/list'
>> {"message": "ping 123"}

And check if Traefik v2 does job well too:
> curl -XGET 'http://localhost:36000/proxy/operability/list'
>> {"message": "ping 123"}

huangapple
  • 本文由 发表于 2021年6月24日 15:53:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/68111670.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定