Traefik v2反向代理无需Docker

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

Traefik v2 reverse proxy without Docker

问题

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

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

> {"message": "ping 123"}

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

[global]
  checkNewVersion = false
  sendAnonymousUsage = false

[entryPoints]
	[entryPoints.web]
	address = ":8090"

	[entryPoints.traefik]
	address = ":8091"

[log]
	level = "DEBUG"
	filePath = "logs/traefik.log"
[accessLog]
	filePath = "logs/access.log"

[api]
	insecure = true
	dashboard = true

[providers]
  [providers.file]
    filename = "traefik.toml"

# dynamic conf
[http]
	[http.routers]
		[http.routers.my-router]
			rule = "Path(`/proxy`)"
			service = "my-service"
			entryPoints = ["web"]
    [http.services]
		[http.services.my-service.loadBalancer]
			[[http.services.my-service.loadBalancer.servers]]
				url = "http://localhost:36001"

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

traefik --configFile=traefik.toml

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

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 版本信息:

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

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

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":

[global]
  checkNewVersion = false
  sendAnonymousUsage = false

[entryPoints]
	[entryPoints.web]
	address = ":8090"

	[entryPoints.traefik]
	address = ":8091"

[log]
	level = "DEBUG"
	filePath = "logs/traefik.log"
[accessLog]
	filePath = "logs/access.log"

[api]
	insecure = true
	dashboard = true

[providers]
  [providers.file]
    filename = "traefik.toml"

# dynamic conf
[http]
	[http.routers]
		[http.routers.my-router]
			rule = "Path(`/proxy`)"
			service = "my-service"
			entryPoints = ["web"]
    [http.services]
		[http.services.my-service.loadBalancer]
			[[http.services.my-service.loadBalancer.servers]]
				url = "http://localhost:36001"

Starting Traefik (I'm using binary distribution):

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):

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:

traefik version
Version:      2.4.9
Codename:     livarot
Go version:   go1.16.5
Built:        2021-06-21T16:17:58Z
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文件中的微服务代码:

package main

import (
	"fmt"
	"log"
	"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, `{"message": "ping 123"}`)
}

func main() {
	http.HandleFunc("/operability/list", handler)
	log.Fatal(http.ListenAndServe(":36001", nil))
}

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

[global]
  checkNewVersion = false
  sendAnonymousUsage = false

[entryPoints]
	[entryPoints.web]
	address = ":36000"

	[entryPoints.traefik]
	address = ":8091"

[log]
	level = "DEBUG"
	filePath = "logs/traefik.log"
[accessLog]
	filePath = "logs/access.log"

[api]
	insecure = true
	dashboard = true

[providers]
  [providers.file]
  	debugLogGeneratedTemplate = true
    # Point this same file for dynamic configuration
    filename = "config.toml"
	watch = true

[http]
    [http.middlewares]
        [http.middlewares.test-replacepathregex.replacePathRegex]
			# We need middleware to replace all "/proxy/" with "/api/"
			regex = "(?:^|\W)proxy(?:$|\W)"
			replacement = "/api/"

	[http.routers]
		[http.routers.my-router]
		    # We need to handle all request with pathes defined as "/proxy/*"
			rule = "PathPrefix(`/proxy/`)"
			service = "my-service"
			entryPoints = ["web"]
			# Use of defined middleware for path replacement
            middlewares = ["test-replacepathregex"]

    [http.services]
		[http.services.my-service.loadBalancer]
			[[http.services.my-service.loadBalancer.servers]]
				url = "http://localhost:36001/"

启动微服务:

go run main.go

启动Traefik:

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

package main

import (
	"fmt"
	"log"
	"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "{\"message\": \"ping 123\"}")
}

func main() {
	http.HandleFunc("/operability/list", handler)
	log.Fatal(http.ListenAndServe(":36001", nil))
}

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

[global]
  checkNewVersion = false
  sendAnonymousUsage = false

[entryPoints]
	[entryPoints.web]
	address = ":36000"

	[entryPoints.traefik]
	address = ":8091"

[log]
	level = "DEBUG"
	filePath = "logs/traefik.log"
[accessLog]
	filePath = "logs/access.log"

[api]
	insecure = true
	dashboard = true

[providers]
  [providers.file]
  	debugLogGeneratedTemplate = true
    # Point this same file for dynamic configuration
    filename = "config.toml"
	watch = true

[http]
    [http.middlewares]
        [http.middlewares.test-replacepathregex.replacePathRegex]
			# We need middleware to replace all "/proxy/" with "/api/"
			regex = "(?:^|\\W)proxy(?:$|\\W)"
			replacement = "/api/"

	[http.routers]
		[http.routers.my-router]
		    # We need to handle all request with pathes defined as "/proxy/*"
			rule = "PathPrefix(`/proxy/`)"
			service = "my-service"
			entryPoints = ["web"]
			# Use of defined middleware for path replacement
            middlewares = ["test-replacepathregex"]

    [http.services]
		[http.services.my-service.loadBalancer]
			[[http.services.my-service.loadBalancer.servers]]
				url = "http://localhost:36001/"

Start microservice:

go run main.go

Start traefik:

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:

确定