翻译:The basics of Traefik
概念
我们再次从概述中举一个例子:
假设你已经在你的基础服务中部署了一系列的微服务。你可能用了一个服务注册器(如:etcd或consul)或者一个编排器(swarm,Mesos/Marathon)来管理这些服务。如果你希望你的用户从internet访问你的微服务,你就必须使用一个反向代理并用虚拟hosts或前缀路径来配置它:
- 域名 api.domain.com 将会指向你私人网路中的微服务api
- 路径 domain.com/web 将会指向你私人网路中的微服务
- 域名 backoffice.domain.com 将会指向你私人网路中的微服务后台,在你的多个微服务之间进行负载均衡
让我们放大Traefik,并对其内部架构进行概述:
- 进来的请求在entrypoints结束,顾名思义,他们是进入Traefik的网路入口(监听的端口,SSL,流量重定向)
- 然后流量被转发到所匹配的前端。前端定义从入口点到后端的路由。路由是根据请求字段创建的(Host,Path,Headers…)并可以匹配或不匹配请求。
- 然后前端将发生请求到后端。后端可以由一个或多个服务及一条负载均衡策略组成。
- 最后,服务将会被转发到私人网络中相应的微服务。
入口点
入口点是进入Traefik的网络入口,它们可以通过下面的形式定义:
- 一个端口(80,443…)
- SSL(证书,**,通过受信CA签名的客户端证书来进行身份验证…)
- 重定向到其他的入口点(重定向HTTP到HTTPS)
这是一个入口点定义的例子:
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
certFile = "tests/traefik.crt"
keyFile = "tests/traefik.key"
- 两个入口点是定义http和https
- HTTP监听端口80,HTTPS监听端口443
- 通过给出一个证书或**来启用SSL到https
- 我们也可以重定向所有的流量从入口点http到https
这是另一个使用客户端证书进行身份验证的例子:
[entryPoints]
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[entryPoints.https.tls.ClientCA]
files = ["tests/clientca1.crt", "tests/clientca2.crt"]
optional = false
[[entryPoints.https.tls.certificates]]
certFile = "tests/traefik.crt"
keyFile = "tests/traefik.key"
- 通过给出证书来启用https的SSL
- 添加一个或多个包含PEM格式证书颁发机构的文件
- 可以将多个CA:s包存在同一个文件中,也可以将他们保存在单独的文件。
前端
前端由一组策略组成,这些策略定义了进来的请求要怎样从入口点被转发到后端。
策略可以分为两组:修改组和匹配组
修改组
修改组的策略只修改请求。他们对正在运行的策略没有任何影响。
下面是一列现有的修改组策略:
-
AddPrefix: /products
:将请求转发到后端之前,将前缀路径添加到现有的请求路径中 -
ReplacePath: /serverless-path
:替换路径并将旧的路径添加到X-Replaced-Path的请求头。对于映射AWS Lambda或Google Cloud Functions非常有帮助。 -
ReplacePathRegex: ^/api/v2/(.*) /api/$1
:用正则表达式来替换路径并添加旧的路径到X-Replaced-Path请求头。用一个空格来分离正则表达式和
替换空间。
匹配组
匹配路径确定某个特定的请求是否该向后端转发。
下面是一些关联性策略:
-
,
是OR
执行者(仅在匹配组里有效,如:Host:foo.com,bar.com
)- 即,任何一条策略匹配就转发请求
- 对
Headers
和HeadersRegexp
无效
-
;
是AND
执行者(只在匹配组之间生效,如:Host:foo.com;Path:/bar
)- 即,所有策略都匹配上才转发请求
下面是一列现有的匹配组策略以及示例:
匹配组 | 描述 |
---|---|
Headers: Content-Type, application/json |
匹配HTTP头。它接受逗号分隔的键值对,且键值都必须是文本 |
HeadersRegexp: Content-Type, application/(text/json) |
匹配HTTP头。它接受逗号分隔的键值对,且键必须是文本,值可以是文本或正则表达式 |
Host: traefik.io, www.traefik.io |
匹配请求host。它接受一个由文本和正则表达式组成的序列 |
Method: GET, POST, PUT |
匹配HTTP请求方式.接受一个http方法的序列 |
Path: /products/, /articles/{category}/{id:[0-9]+} |
匹配准确的请求路径。接受一个由正则表达式和文本组成的序列 |
PathStrip: /products/ |
在转发请求到后台之前,精准匹配路径并去掉路径。它接受一系列文本路径。 |
PathStripRegex: /articles/{category}/{id:[0-9]+} |
在转发请求到后台之前,精准匹配路径并去掉路径。它接受一系列文本和正则表达式路径。 |
PathPrefix: /products/, /articles/{category}/{id:[0-9]+} |
匹配请求路径的前缀。它接受一个由文本和正则表达前缀路径组成的序列 |
PathPrefixStrip: /products/ |
在转发请求到后端之前,匹配路径前缀并去掉前缀路径。它接受一个文本前缀路径序列。从Traefik1.3开始,剥离的前缀路径可以在X-Forwarded-Prefix头中使用 |
PathPrefixStripRegex: /articles/{category}/{id:[0-9]+} |
在转发请求到后端之前,匹配路径前缀并去掉前缀路径。它接受一个文本和正则前缀组成的路径序列。从Traefik1.3开始,剥离的前缀路径可以在X-Forwarded-Prefix头中使用 |
Query: foo=bar, bar=baz |
匹配Query字符参数。它接受一个键=值对序列 |
为了将正则表达式和Host及路径匹配器一起使用,你必须声明一个随意命名的变量,后跟冒号分离的正则表达式,所有变量都要用大括号括起来。可以使用go的正则包支持的任何模板(如:/posts/{id:[0-9]+})
Note
变量没有特殊意义.但是,它是嵌入正则表达式和定义语法的gorilla/mux依赖性所必需的。
你可以选择启用passHostHeader
来转发客户端Host头到后端。你也可以选择在特定的header中配置passTLSClientCert
选项来将客户端证书传递给后端。
路径匹配用法指南
本节介绍何时使用各种各样的路径匹配器
如果你的后端只在特定的路径监听,请使用Path。例如,Path:/products 将会匹配 /products 但不匹配 /products/shoes
如果你的后端监听在一个特定的基础路径同时也处理子路径的请求。比如:PathPrefix: /products 即匹配/products也匹配 /products/shoes 和 /products/shirts。因为路径是按原样转发的,所以你的后端预计会监听 /products。
如果你的后端监听在根路径(/),但可以在特定前缀上路由,请使用一个*Strip匹配器。比如:PathPrefixStrip: /products 将匹配/products,也匹配/products/shoes 和 /products/shirts.
因为路径在转发前被剥离了,所以你的后端应监听在’/’。如果你的后端正在为某些资产服务(如,图片或javascript文件),那么很可能它必须返回被恰当构建的相对URLS。
继续这个例子,后端应该返回/products/shoes/image.png (而不是/images.png,Traefik可能无法和同一后端关联 )
X-Forwarded-Prefix 头(Traefik1.3后可以使用)可以被要求动态的构建这样的URLs
除了通过路径来区分你的后端,也可以在组合中增加一个Host匹配器。这样,你后端的命名空间出路径还可以基于基础hosts发生。
例子
这是一个前端定义的例子:
[frontends]
[frontends.frontend1]
backend = "backend2"
[frontends.frontend1.routes.test_1]
rule = "Host:test.localhost,test2.localhost"
[frontends.frontend2]
backend = "backend1"
passHostHeader = true
[frontends.frontend2.passTLSClientCert]
pem = true
priority = 10
entrypoints = ["https"] # overrides defaultEntryPoints
[frontends.frontend2.routes.test_1]
rule = "HostRegexp:localhost,{subdomain:[a-z]+}.localhost"
[frontends.frontend3]
backend = "backend2"
[frontends.frontend3.routes.test_1]
rule = "Host:test3.localhost;Path:/test"
- 定义了3个前端:
frontend1
,frontend2
andfrontend3
- 如果策略
Host:test.localhost,test2.localhost
匹配上了,frontend1
将会把流量转发到backend2
- 如果策略
HostRegexp:localhost,{subdomain:[a-z]+}.localhost
匹配上,frontend2
将把流量转发到backend1
(转发客户端Host
头到后端) - 如果策略
Host:test3.localhost
和 Path:/test 匹配上了,frontend3
将会把流量转发到backend2
下一篇: Traefik-简单成功案例