试试这款 Kubernetes HTTP 路由器和反向代理

Skipper 旨在处理大量的 HTTP 路由定义,超出您在 Nginx 或 Apache 中想要管理的数量。
109 位读者喜欢这篇文章。
8 ways to contribute to open source when you have no time

Opensource.com

Skipper 是一款用于服务组合的开源 HTTP 路由器和反向代理。正如其 GitHub 页面 所述,它旨在处理大量动态配置的 HTTP 路由定义(超过 600,000 条路由),具有详细的查找条件和灵活的请求流增强过滤器。它可以开箱即用,也可以通过自定义查找、过滤器逻辑和配置源进行扩展。

代理

当一些人想到代理时,他们会想象一个充当内网网关的网页,或者一个看起来可疑的网页,旨在解锁学校或工作网络上的社交媒体网站。前向代理是桌面基础设施运营商用来节省互联网带宽、实施家长控制或限制社交媒体访问的一种代理。另一种代理是个人用户导航到一个页面,提供凭据,然后被转发到受保护的内网资源。这种代理的反向是反向代理,它接受所有流量并将其转发到特定资源,如服务器或容器。这就是 Skipper 为基础设施所做的工作。

当我阅读 Matt Klein 关于现代网络负载均衡和代理的文章 时,我意识到我们作为 Skipper 的维护者,应该更详细地解释为什么以及如何利用 HTTP 代理。在本文中,我将把术语“HTTP(反向)代理”和“HTTP 路由器”视为相同。

HTTP 路由

根据 维基百科:“路由是在网络中为流量选择路径的过程。” 此定义指的是 OSI 第 3 层 的路由,最常见的是基于 IP 以及诸如 BGPOSPF 等路由协议。由于本文不是关于这些协议之一,我将尝试解释 HTTP 路由器的作用。但首先,我想介绍 Skipper,一个用 Go 编写的 OSI 第 7 层 HTTP 路由器库,它是零售商 Zalando 的电子商务商店和 Kubernetes Ingress 基础设施的核心组件。

在 Zalando,我们使用 Skipper 作为 Kubernetes Ingress 控制器,以支持我们的用户获得可见性、可靠性、安全性以及用于卸载常见应用程序的附加功能。

任何运行 HTTP 服务的组织,通常在微服务架构中,都需要将 HTTP 请求路由到正确的应用程序。HTTP 路由器根据 HTTP 请求提供的信息进行路由。例如,以下显示了一个 HTTP/1.1 请求。

GET /details HTTP/1.1
Host: www.zalando.de
User-Agent: curl/7.49.0
Accept: */*
Authorization: Bearer <token>
...

我们可以根据方法 GET、路径 /detailsHost 标头 www.zalando.de 或请求的任何任意部分进行路由。

应用程序所有者面临的一个常见问题是将 API 拆分为多个应用程序,因此您需要将组件的职责拆分为子组件。另一个常见的任务是支持重构;也许您已经重写了应用程序的一部分,并且现在想要单独部署它。

例如,假设您有一个商店,其中包含产品列表及其详细信息,并且您需要将其拆分为商店产品后端应用程序。在 /,您的商店显示产品列表,在 /details,它显示产品详细信息,例如颜色、尺寸、可持续性和价格。

Figure 1: shop

图 1:商店

您需要将产品详细信息的职责拆分到其自己的应用程序中,以便 / 保留在商店应用程序中,而 /details 被重构到产品应用程序中。

Figure 2: product and shop

图 2:两个后端应用程序,产品商店

为了确保 HTTP 代理为传入请求找到正确的后端,它使用路由表来检查目标以确保其正确。

路由表

在 Skipper 中,路由表是通过从不同来源拉取 dataclients 生成的信息来创建的。一个来源可以是 路由文件,类似于您在更流行的 HTTP 服务器(如 Apache 或 Nginx)中可能看到的。

根据您组织的规模——或者更好的是,后端应用程序的数量——路由表可能会变得非常大。Skipper 将路由表实现为一棵树,它可以扩展到超过 600,000 条路由(远远超过您在 Nginx 或 Apache 配置中想要管理的数量)。

继续上面的示例应用程序,表 1 显示了 图 2 中的路由表。商店 / 应路由到 shop,而 /detail 应路由到 product 应用程序。

路径 应用
/ /
/detail 产品

表 1:路由表

Skipper 中可用的 dataclients 从不同的来源获取路由以及路由的组成。

Dataclient

Skipper 的路由文件 dataclient 中的路由配置类似于您可能从 Nginx 或 Apache 中的 HTTP 代理中了解到的。在 Skipper 中,路由文件以 eskip 语法指定所有路由,如图 3 所示。

r1: P1() && P2() && .. && PN()
    -> f1()
    -> f2()
    ...
    -> fN()
    -> <backend>;
r2: ...
...

图 3:eskip 中的路由文件

在上面

  • r1, r2, ... 是唯一的 routeID。
  • P1, P2,..,PN 是定义匹配的谓词。
  • f1, f2,..,fN 是在选择路由后应用的过滤器。过滤器可以更改请求和响应。
  • 最后,定义了 Skipper 后端。这可以是一个 URL、一个负载均衡的 URL 列表,以及用于特殊情况的其他后端,例如 直接响应

路由字符串 是另一个 dataclient,它对于测试非常方便。例如,如果您需要一个伪后端用于您的演示,该后端以 HTML 回复绿色背景,则可以使用

$ skipper -routes-string='* 
-> inlineContent(
      "<html><body style=\"background-color: green;\"></body></html>"
   )'

到目前为止,Skipper 最受欢迎的 dataclient 是 Kubernetes dataclient,它用于从 Kubernetes API 服务器 获取信息,并从 Skipper Ingress 资源和 RouteGroup 自定义资源定义 (CRD) 创建路由表。

总结以上内容,dataclients 从不同的提供程序获取信息以构建 Skipper 的路由表。表 1 显示了商店/描述示例的路由表,Skipper 使用谓词来选择路由以处理请求。

谓词

在 Skipper 中,传入的请求与所有路由的 谓词 匹配,以找到与传入请求最匹配的路由。谓词是基于传入请求进行匹配的函数。在 图 2 和表 1 的示例中,Skipper 将具有类似于图 4 的路由表

shop: Path("/")
    -> "https://shop.zalando";
product: Path("/detail")
    -> "https://product.zalando";

图 4:Skipper 路由表

这意味着路径为 / 的 HTTP 请求将与 Path("/") 谓词匹配,这样 Skipper 将执行商店路由。路径为 /detail 的请求将与 Path("/detail") 匹配并路由到产品应用程序。

通常,路由行为可以通过谓词来更改。您可以选择许多谓词。例如,Method("POST") 仅当传递 POST 请求时才为真。具有更多谓词的路由被认为更具体。此外,具有更多谓词的路由在路由选择中比谓词较少的路由具有更高的权重。

特殊情况是 Path()PathSubtree(),它们首先在树中匹配,并减少了作为列表扫描的路由数量。例如,图 5 所示的树结构有助于将路由数量扩展到 Zalando 生产设置之一中的 600,000 多个。

Skipper tree example

图 5:树结构

过滤器

选择路由后,将应用请求过滤器。过滤器作用于请求或响应;它们可以更改发送到后端的传入请求,并且可以更改发送到客户端的响应。

例如,setRequestHeader("Foo", "bar") 将 HTTP 标头 "Foo" 设置为值 "bar",这样后端会在请求中看到此标头。

响应过滤器 responseCookie("keks", "val", 3600) 在响应中为调用者(在本例中可能是浏览器)设置一个名为 "keks" 的 Cookie。Cookie 的值为 "val",有效期为一小时。

一个作用于请求和响应的过滤器是 enableAccessLog(40, 5)。这将为来自后端的所有状态代码为 40x 或 5xx 的响应执行访问日志记录。

从示例中可以看出,过滤器可以更改请求或响应,或者只是基于它们执行某些工作。另一个过滤器示例是 auth filtersratelimits。如果请求不应被允许通过,这些过滤器将阻止请求传递到后端。例如,要从名为 /var/www 的目录提供静态内容,可以使用过滤器 static("/var/www")

了解更多

本文提供了 Skipper 及其功能的基本概述。有关更多信息,请查阅 Skipper 的文档,并请在评论中分享您的问题或反馈。

下一步阅读
标签
Sandor
Sandor Szücs Sr. 软件工程师,开发者生产力,Zalando SE @sszuecs

6 条评论

不错的帖子!

好帖子

非常好的解释,我一直在寻找这种技术。我希望您将来能解释更多关于过滤器的内容,谢谢。此致,Fazal Jan 来自 https://checkiqama.info

Creative Commons License本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.