路由和反向代理
Skipper是开放源代码HTTP路由器和用于服务组合的反向代理。 正如其GitHub页面所述,它旨在处理大量动态配置的HTTP路由定义(> 600,000个路由),并提供详细的查找条件并使用过滤器灵活地增加请求流。 它可以直接使用,也可以与自定义查找,过滤器逻辑和配置源一起扩展。
当有人想到代理时,他们会想到一个网页,该网页充当Intranet的网关或外观可疑的网页,旨在解除封锁学校或工作网络上的社交媒体网站。 前向代理是桌面基础结构的运营商用来节省Internet带宽,执行父母控制或限制社交媒体访问的代理。 另一种代理是个人用户导航到页面,提供凭据,然后转发到受保护的Intranet资源的代理。 这种代理的逆向是反向代理,它接受所有流量并将其转发到特定资源,例如服务器或容器。 这就是Skipper为基础架构所做的工作。
Matt Klein在有关现代网络负载平衡和代理的文章中,我意识到,作为Skipper维护者,我们应该解释有关为什么以及如何利用HTTP代理的更多功能和细节。 在本文中,我将把“ HTTP(反向)代理”和“ HTTP路由器”这两个术语视为相同。根据Wikipedia的说法:“路由是为网络中的流量选择路径的过程。” 此定义涉及OSI第3层的路由,最常见的是基于IP的路由协议,例如BGP或OSPF 。 由于本文不是其中之一,因此我将尝试解释HTTP路由器的含义。 但是首先,我想介绍Skipper,这是一个用Go编写的OSI 7层 HTTP路由器库,也是零售商Zalando的电子商务商店和Kubernetes Ingress基础结构的核心组件。
在Zalando,我们将Skipper用作Kubernetes Ingress控制器,以可视性,可靠性,安全性和附加功能为用户提供支持,以减轻常见应用程序的负担。
任何通常在微服务架构中运行HTTP服务的组织都需要将HTTP请求路由到正确的应用程序。 HTTP路由器根据HTTP请求提供的信息进行路由。 例如,以下显示了HTTP / 1.1请求。
我们可以基于GET方法,路径/ details , Host头文件www.zalando.de或请求的任意部分进行路由 。
应用程序所有者面临的一个常见问题是将一个API拆分为多个应用程序,因此您需要将一个组件的职责划分为多个子组件。 另一个常见的任务是支持重构。 也许您已经重写了应用程序的一部分,并且现在想单独部署它。
例如,假设您有一个商店,其中列出了产品及其详细信息,并且需要将其拆分为商店和产品后端应用程序。 在/ ,您的商店显示产品列表,在/ details ,显示产品详细信息,例如颜色,尺寸,可持续性和价格。
您需要将产品详细信息的责任划分到其自己的应用程序中,以便将/保留在商店应用程序中,并将/ details重构为产品应用程序。
为了确保HTTP代理找到传入请求的正确后端,它使用路由表检查目标以确保其正确。
在船长,路由表通过拉动通过生成的信息创建dataclients从不同的来源。 一个来源可以是路由文件 ,类似于您在更流行的HTTP服务器(例如Apache或Nginx)中看到的文件 。
取决于组织的规模,或者更好的是,后端应用程序的数量,路由表可能会变得非常大。 Skipper将路由表实现为一棵树,该树可以扩展到超过600,000条路由(远远超出您要在Nginx或Apache配置中管理的路由)。
在上面的示例应用程序之后,表1显示了图2的路由表。 商店/应该路由到商店, /详细信息应该路由到产品应用程序。
表1:路由表
Skipper中可用的数据客户端从不同来源获取路由以及路由的组成。
Skipper的路由文件dataclient中的路由配置类似于Nginx或Apache中HTTP代理所提供的配置。 在Skipper中,路由文件以eskip语法指定所有路由,如图3所示。
图3:eskip中的Routes文件
在上面:
- r1,r2,...是唯一的routeID。
- P1,P2,..,PN是定义匹配的谓词。
- f1,f2,..,。fN是在选择路线之后应用的过滤器。 过滤器可以更改请求和响应。
- 最后,定义了Skipper后端。 这可以是单个URL,负载均衡的URL列表,以及其他一些特殊情况(例如直接响应)的 URL。
路由字符串是另一个方便测试的数据客户端。 例如,如果您的演示需要一个伪后端,该伪后端使用HTML回复绿色背景,则可以使用:
到目前为止,Skipper最受欢迎的数据客户端是Kubernetes数据客户端,它用于从Kubernetes API服务器获取信息并从Skipper Ingress资源和RouteGroup自定义资源定义(CRD)创建路由表。
综上所述,数据客户端从不同的提供程序获取信息以构建Skipper的路由表。 表1显示了商店/说明示例的路由表,Skipper使用谓词选择处理请求的路由。
在Skipper中,将传入请求与所有路由的谓词进行匹配,以找到传入请求的最佳匹配路由。 谓词是根据传入请求进行匹配的函数。 在图2和表1的示例中,Skipper的路由表类似于图4:
图4:船长路由表
这意味着带有路径/的 HTTP请求将由Path(“ /”)谓词进行匹配,以便Skipper将执行车间路线。 具有路径/ detail的请求将由Path(“ / detail”)匹配,并路由到产品应用程序。
通常,可以通过谓词更改路由行为。 您可以选择很多谓词。 例如,仅当传递POST请求时, Method(“ POST”)才为true。 具有更多谓词的路由被认为是更具体的。 同样,具有更多谓词的路由比具有更少谓词的路由具有更大的权重。
特殊情况是Path()和PathSubtree() ,它们在树中首先匹配,并减少了作为列表扫描的路由数。 例如,图5中所示的树结构有助于在Zalando的一种生产设置中将路线数量扩展到超过600,000条。
选择路由后,将应用请求过滤器 。 过滤器根据请求或响应进行工作; 他们可以将传入的请求更改为后端,也可以更改对客户端的响应。
例如, setRequestHeader(“ Foo”,“ bar”)将HTTP标头“ Foo”设置为值“ bar” ,以便后端在请求中看到此标头。
响应过滤器responsecookie(“ keks”,“ val”,3600)在对调用者的响应中设置一个名为“ keks”的cookie,在这种情况下可能是浏览器。 cookie的值为“ val” ,有效期为一小时。
在请求和响应上起作用的一种过滤器是enableAccessLog(40,5) 。 这将访问状态码为40x或5xx的后端所有响应的访问日志。
从示例中可以看到,过滤器可以更改请求或响应,或者仅基于请求或响应进行一些工作。 另一个过滤器示例是auth过滤器或ratelimits 。 如果不允许请求通过,这些将阻止请求传递到后端。 例如,要从名为/ var / www的目录中提供静态内容,可以使用过滤器static(“ / var / www”) 。
本文提供了Skipper及其功能的基本概述。 有关更多信息,请查阅Skipper的文档 ,并在评论中分享您的问题或反馈。