TOC
Traefik 是一个开源的反向代理和负载均衡工具,现在官方介绍中将其定位为云原生的边缘路由器,且用了一堆修饰词:简单、自动、高速、全面、开源、产品级、内置监控指标和主流集群技术集成等等。
Traefik 2.0 已经发布几天了,我自己也是在测试环境一顿鼓捣,试用了一段时间,今天在这里和大家谈谈 Traefik 2.0
,总体而言 Traefik 2.0
给我们的惊喜还是挺大的,因为它终于终于支持了 TCP,哈哈。
总结下来 Traefik 2.0 新增了许多新特性:
- 开始使用 CRD 来完成相关任务;
- 支持 SNI 路由和多协议端口的 TCP;
- 使用中间件(Middlewares)自定义路由;
- 提供了一种全新的 dashboard;
- 支持金丝雀发布;
- 流量复制;
- 更加详细的特性解释可以参考CHANGELOG.md
下面是我根据几位博主的文章针对几个比较常用的特性进行简述。
支持 SNI 路由和多协议端口的 TCP
下面是官方博客的一个示例配置,主要用来做下 TCP 的支持:
tcp:
routers:
to-database:
entrypoints:
- database-entrypoint
rule: HostSNI(`*`)
service: database-service
services:
database-service:
loadBalancer:
servers:
- address: xx.xx.xx.xx:xx
上述配置表示每个以 database-entrypoint
结尾的请求都将被路由到 database-service
这个服务上去。同时 Traefik 还支持通过 TLS,Traefik 还可以根据 SNI 来路由 TCP 请求。在下面示例中,Traefik 就将根据 SNI 将请求路由到两个数据库:
tcp:
routers:
to-db-1:
entrypoints:
- web-secure
rule: "HostSNI(`db1.domain`)"
service: "db1"
tls: {}
to-db-2:
entrypoints:
- web-secure
rule: "HostSNI(`db2.domain`)"
service: "db2"
tls: {}
同时 Traefik 还是支持 HTTP 和 TCP 在同一个端口上,如果你希望获得相同的入口的同时获取 HTTP 和 TCP 请求,那么 Traefik 可以很完美的来处理它。
tcp:
routers:
to-db-1:
entrypoints:
- web-secure
rule: "HostSNI(`db1.domain`)"
service: "db-1"
tls: {}
http:
routers:
to-db1-dashboard:
entrypoints:
- web-secure
rule: "Host(`dashboard.db1.domain`)"
service: "db1-dashboard"
tls: {}
上述示例中dashboard.db1.domain
上的 HTTP 请求将路由到数据库的 Dashboard 服务上,而上面的 db1.domain
上的 TCP 请求将路由到数据库上面去
使用中间件(Middlewares)自定义路由
在 Traefik 2.0 中还引入了中间件的功能,通过中间件可以将请求路由到目的地之前或者之后来调整请求。我们可以声明一个中间件,这个中间件可以复用到我们之后定义的路由上,下面是官方文档中中间件的配置方式:
# As YAML Configuration File
http:
routers:
router1:
service: myService
middlewares:
- "foo-add-prefix"
rule: "Host(`example.com`)"
middlewares:
foo-add-prefix:
addPrefix:
prefix: "/foo"
services:
service1:
loadBalancer:
servers:
- url: "http://127.0.0.1:80"
对于 Kubernetes 用户来说,还可以使用 Traefik 的新 CRD 来进行更加清晰明了的配置,而不需要像 nginx-Ingress 定义好多复杂的注解。
# As a Kubernetes Traefik IngressRoute
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
scope: Namespaced
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: stripprefix
spec:
stripPrefix:
prefixes:
- /stripit
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroute
spec:
# more fields...
routes:
# more fields...
middlewares:
- name: stripprefix
例如我们常用的 https
方式就是通过中间件实现的,而且在 Traefik 中内置了许多中间件:路径操作、多种身份验证机制、缓冲、断路器、重试、压缩、错误处理、headers、IP 白名单、限速、重定向等。
Traefik 2.0 提供的全新的 Dashboard
Traefik 2.0 提供了一种全新的 WebUI,我们可以通过 dashboard 查看集群上的相关信息。同时还可以看到服务的比较详细的配置信息,如下图所示:
Traefik 2.0 相关服务的具体信息可以参考下图:
支持金丝雀发布
在 Traefik2.0 中还支持了金丝雀发布,还有 A/B 测试,这些都是 Traefik 通过服务负载均衡的形式实现的。
可以将服务负载均衡器看成负责将请求转发到实际服务的虚拟服务,下面让我们来看一个经典的场景,现在有一个路由到一个 API:
http:
routers:
my-route:
rule: "Host(`my.domain`)"
service: my-api-v1
services:
my-api-v1:
loadBalancer:
servers:
- url: "http://private-ip-server-1/"
如果需要发布一个新版本,并且希望可以实现逐步部署,比如先部署三分之一,这里需要定义一个新的 ID 来部署一个新服务,例如:
http:
services:
my-api-v2:
loadBalancer:
servers:
- url: "http://private-ip-server-2/"
然后再创建一个服务负载均衡器,并设置相应的权重而不是直接指向新的版本:
http:
services:
canary-api:
weighted:
services:
- name: my-api-v1
weight: 3
- name: my-api-v2
weight: 1
最后,将路由指向这个服务:
http:
routers:
my-route:
rule: "Host(`my.domain`)"
service: canary-api
之后,我们不需要重新部署真正的服务就可以更新权重,当然还可以对它们进行扩容,这都不会对金丝雀部署本身产生任何的影响。
当然,对于新版的 Traefik 新特性也不止这么点,还有很多新特性,这里不再赘述,只是找几个比较常用的后续做测试,如果需要了解其他新特性可以参考 Traefik 2.0 官方文档 。
参考链接
- Traefik
- Traefik 2.0 - The Wait is Over!
- Traefik 2.0 正式版发布-阳明的博客|Kubernetes|Istio|Prometheus|Python|Golang|云原生
comments powered by Disqus