traefik 是一个开源的反向代理和负载均衡工具,现在官方介绍中将其定位为云原生的边缘路由器,且用了一堆修饰词:简单、自动、高速、全面、开源、产品级、内置监控指标和主流集群技术集成等等。
当然,官方如此描述也是有理有据的,其开源后热度直线上升,而且被广泛使用,尤其是在当下的“微服务”、“云原生”场景。
从我个人的角度讲,其相对于传统的反向代理显得更“现代”:
- 动态的更新配置,不需要重启/reload等操作。
- 原生支持Docker, Swarm mode, Kubernetes, Marathon, Consul, Etcd, Rancher, Amazon ECS等等后端。
- 支持 RestAPI
- 支持后端健康状态检查,根据状态自动地配置
这些特点,让其在云原生的场景下更贴合。而traefik本身的特性远不止如此。大家有兴趣可阅读它的官方文档:https://docs.traefik.io/,而且国内的资料介绍也很多。
本篇文章的背景是因为工作中用到了版本2中的一些特性,但国内关于新版的介绍资料较少,遂对 back to traefik 2.0 这篇文章的核心部分做了简单翻译提取。如有理解错漏,请指正。
目前(2019年5月21日)2.0 正在开发中,alpha4 版本在 4月17日发布。我们一起看看 2.0 有哪些东西。
核心概念
- Providers 是指你正在使用的集群技术 (Kubernetes, Docker, Consul, Mesos, Rancher…). Traefik 通过 provider 的 API 来发现对应到你的服务的 routes(路由).
- Entrypoints, 是最基本的配置,指监听请求的端口.
- Services 是在你的基础设施上的运行的软件的体现. Traefik 知道如何处理你的程序的多个实例(当前提供多种负载均衡的能力/方法), 然后通过 services 配置如何联通到真实的运行程序.
- Routers 将传入的请求和你的 service 连接起来. 他们持有的 rules 决定哪个 service 将处理对应的请求.
- 最后, 中间件是可以在请求被 service 处理之前对其进行更新的组件.Traefik 提供了一些开箱即用的中间件来处理 认证、速率限制、断路器、白名单、缓冲等等.
配置结构
从图中可以看到,配置氛围静态配置和动态配置。
- 静态配置,启动的时候加载。包括 Entrypoints、Provider 连接信息
- 动态配置,运行时可动态读取改变的。包括 Routes、Services、Middlewares、Certificates 。
新特性
TCP 支持
历时三年,经过大量的讨论和开发,目前 traefik 完全支持 TCP 协议。
示例如下:
1 | [entrypoints] |
使用 FileProvider,重定向所有 27010 端口的请求到数据库服务。
来看更厉害的,Traefik 支持基于 SNIs 的路由:
服务器名称指示(SNI)是TLS计算机网络协议的扩展,通过该协议,客户机在握手过程开始时指示要连接到哪个主机名。这允许服务器在相同的IP地址和TCP端口号上显示多个证书,因此允许由相同的IP地址提供多个安全(HTTPS)站点(或TLS上的任何其他服务),而不需要所有这些站点使用相同的证书。它在概念上等同于HTTP/1.1基于名称的虚拟主机,但适用于HTTPS。所需的主机名在原始SNI扩展中没有加密,因此窃听者可以看到请求的是哪个站点。
1 | [entrypoints] |
更更厉害的呢?Traefik 可以牛到在同一个端口上同时支持 HTTP 和 TCP。
1 | [entrypoints] |
在它的第一个alpha版本中,Traefik 只在 FileProvider 中可以启用TCP路由,但是请做好准备,因为它很快就会对其他 Providers 可用!
用来更新请求的中间件(Middlewares)
过去很多特性被嵌入到 Traefik 中,但没有针对性的定制和对应选项去调整。
Middlewares 填补了这一空白。你可以做到针对每一个 router 开启和调整相关特性。
Middlewares 是在请求实际转发到服务之前对其进行操作的组件,如果不满足要求的条件,甚至可以决定不转发请求。
在发布时,Traefik附带了以下中间件:
- AddPrefix(给请求添加一个前缀路径)
- BasicAuth
- DigestAuth
- ForwardAuth(委托第三方服务身份验证)
- Buffering
- Chain (定义可重用的Middleware集和)
- CircuitBreaker (断路器,避免调用压垮服务)
- Compress
- Errors(提供自定义的错误页面)
- Headers
- IpWhitelist
- MaxConn(限制连接到服务的并发连接数)
- PassTLSClientCert
- RateLimit(在给定时间段内限制对服务的请求数量)
- RedirectRegex
- RedirectScheme
- ReplacePath(在转发到服务之前更新请求路径)。
更重要的,项目重构了代码,使未来更方便地提供更多的中间件。
Kubernetes & CRD(CustomResourceDefinition)
在过去两年里,社区围绕“更好的 ingress”进行了大量的讨论,回看之前的 kubernettes provider,我们认为还有改进的空间。对于V2,如果我们想让 k8s 用户直接从中受益(比如 TCP 和 middleware),而不被大量 annotations 困扰,我们必须提供新的选择。
在备选方案中,CRD 越来越受欢迎,因为它们解决了ingress规范的缺点。受 Heptio 在 Contour 项目中的 IngressRoute 启发,我们扩展了这个规范来实现每个Traefik特性。
下面是一个例子:
1 | apiVersion: traefik.containo.us/v1alpha1 |
新的更有表现力的路由规则语法
Traefik 现在支持更有表现力的语法来定义 router rules,包含 and
, or
和 parenthesis
(括号)!
可用的 matchers 有 Headers, HeadersRegexp, Host, HostRegexp, Method, Path, PathPrefix, and Query.
由于 TCP 是完全不同的东东,所以目前只支持专用的 matcher:HostSNI。
Since TCP is a whole different world, for now, it only supports a dedicated matcher: HostSNI.
来看个例子:
1 | rule = (Host(`api.domain`) && PathPrefix(`/v2`)) || Host(`api-v2.domain`) |
Cross Provider
Traefik 一直与很多 providers 兼容, 这是他的优势之一:无论你的基础设施是什么,从裸机到各种协调器和集群方案,Traefik 都能搞定!
但从 V2 开始,我们更进一步做到了让用户在一个 provider 中声明元素(middlewares, services, routers)在其他不同的 provider 中使用。
让我们来看一个例子,例子中在配置文件中(file provider)声明了一个认证 middleware,在 Docker label(Docker Provider)中被使用。
1 | # somewhere in a configuration file for the file provider |
1 | # somewhere in a docker compose file |
当然,你可以在一个 provider 中声明 router 指向其他 provider 中定义的 services。
TLS Termination per Route
为了添加 TCP 支持到 Traefik 中,我们几乎重新思考了所有事情,从集群的大门-entrypoint 开始。
我们起初的想法是每个入口点(包括其端口)指定一种类型的协议。不幸的是,在某些情况下,特别是当人们使用Traefik为多个集群路由请求时,我们认为它的限制太大。因此,我们允许每个入口点有多个协议。
之后,讨论依然存在其他方面,我们一直在寻找让用户在配置TLS termination 或 passthrough 时有更好的控制方式。在路由器级别启用TLS的想法赢得了头脑风暴,然后通过了概念证明的测试(我们团队中有相当多的概念证明分支,以至于它几乎成为了一个迷因)。
下面是三个路由器监听同一个入口点的例子,第一个 router 完成TLS连接(在HTTPS上),第二个 router 完成TLS连接(在TCP上),第三个 router 向后传递,将 TLS连接的细节处理交给服务本身。
1 | [entrypoints] |
Labels, Key-Value Configuration, Tags, …
这只是表面上的一个小调整,但是对代码有很大的影响,我们重新编写了配置解析器。这个新系统确保 Traefik 中的每个选项都有相同的路径,无论是否用TOML [something.that.is.here]
或是容器上的一个 label something.that.is.there
,或是一个键(放在键值存储) something/that/is/somewhere
,或者是将来可能可用的任何东西。
修改了文档
我们更新了文档结构来帮助用户快速的理解如何配置 Traefik。同时,我们列出了配置结构的大纲,让专业用户更方便的学习配置的细节。
阅读最终版
是的,更多的内容还在路上,只是我们(团队)迫不及待去分享了。
新的 WebUI, 剩余的 providers, metrics, UDP, YAML, TLS stores & options, canary(金丝雀), 更多的文档 — 什么都是有可能的.
除了重新启用其他 providers (alpha只支持 file、Docker和k8s),并为所有这些 provider 启用TCP(目前只支持 file)之外,路线图还具有很多特性。
首先,最明显的是,一个贡献者正在积极地开发一个经过改进的WebUI,从我们看到的模型来看,它看起来非常有前途。我们希望这个新UI能够帮助您无缝地浏览数百条路由。
其次,我们正在对TLS配置进行改进,包括存储和选项,他们应该自解释。
再次,既然我们已经尝试了一种新的协议,那么我们不妨添加其他协议(如UDP)。
2.0 文档地址:https://docs.traefik.io/v2.0/,大的变更地址:https://github.com/containous/traefik/blob/master/CHANGELOG.md.