分享一些关于网关和代理的初学者指南

你是否听说过网关,代理(正向和反向),负载平衡器,API网关?你可能做到了,即使你没有听说过,也可能听说过nginx,HAProxy,Envoy,Traefik,Gloo,Kong,Ambassador,Tyk等产品。你可能每次都使用网关,甚至都不知道。网关通常位于客户端与支持应用程序或服务之间。网关的工作是代理或“协商”客户端与服务器之间的通信。想象一下通过正门走进购物中心。当你走进时,可能会遇到以下其中一种情况:

分享一些关于网关和代理的初学者指南_第1张图片

购物中心目录。无论你去哪个购物中心,你都将遇到一个显示所有商店名称及其位置的目录,并且可能还包括地图。假设你想参观乐高商店。你知道这家商店在购物中心内,但你不知道确切的地址。幸运的是,知道商店的名称并使用目录查找商店在购物中心内的位置就足够了。

现在,如果我们将购物中心视为服务器(或服务器集群),那么购物中心中的商店就是在该服务器上运行的服务或应用程序。在这种情况下,客户端是你或你的计算机。如果购物中心中只有一家商店,那么问题就不那么重要了-只有一个地址,你知道去哪里。

分享一些关于网关和代理的初学者指南_第2张图片

但是,我们都知道那不是现实。就像购物中心里有数百家商店一样,服务器上也可以运行数百个或更多应用程序。我们可以说,记住所有地址的客户端至少是不实际的,更不用说在服务器上只运行一个应用程序了。

分享一些关于网关和代理的初学者指南_第3张图片

回到类比-你可以将Mall目录视为软件世界中的网关。该网关知道所有应用程序所在的位置。它知道服务器上运行的每个应用程序的实际地址(例如IP或完全限定的域名)。

就像你不需要知道商店的确切地址一样,客户端也不需要通过网关发出请求。

分享一些关于网关和代理的初学者指南_第4张图片

如果你想到达lego商店或致电应用程序,则可以请求http://stores.example.com/lego,网关将知道将请求转发或代理到实际地址。可以在客户端和应用程序之间放置一个用于传入流量的网关,因此称为入口网关。客户端不需要发出请求来分离应用程序,而只需要了解网关并向网关发出请求。路由传入的请求并通过公共端点公开API仅是网关可以承担的部分职责。网关执行的其他典型任务是速率限制,SSL终止,负载平衡等。

什么是限速?

分享一些关于网关和代理的初学者指南_第5张图片

将速率限制视为一个漏斗,它仅允许每单位时间一定数量的请求通过应用程序。如果我将购物中心的类比与黑色星期五结合在一起,则商店已满,因此你需要限制可以进入商店的人数。

速率限制器的作用非常相似-它限制了一定时间内可以发出的请求数量。例如,对于每秒10个请求的速率限制,客户端每秒只能发出10个请求。如果客户端尝试每秒发出10个以上的请求,则表示它们受到服务器的速率限制。在这种情况下,服务器的HTTP响应为429:Too Many Requests。

什么是SSL终止?

SSL代表安全套接字层协议。SSL终止或也称为SSL卸载是解密加密流量的过程。SSL终止与网关模式完美配合。当加密的流量到达网关时,它将在那里解密,然后传递到后端应用程序。在网关级别执行SSL终止还可以减轻服务器的负担,因为你仅在网关级别执行一次,而不是在每个应用程序中执行一次。

你可以在每个应用程序或服务上实现这些功能,如下图所示。

分享一些关于网关和代理的初学者指南_第6张图片

但是,如果在每个应用程序级别执行SSL终止和速率限制,则都会“花费”时间和资源。网关可以帮助卸载此功能,并在网关级别执行一次。

分享一些关于网关和代理的初学者指南_第7张图片

这是一些可以在网关级别上卸载和执行的功能的列表:

  认证方式

  SSL终止

  负载均衡

  限速

  断路

  基于客户端的响应转换

什么是断路?

  断路是可以帮助提高服务弹性的一种模式。一旦应用程序已经失败,它可以防止对应用程序进行不必要的请求。你可以检查“什么是电路断路?” 找到更多详细信息。

  网关方法也有其缺点。它是你必须开发,维护或至少配置(如果使用现有网关解决方案)的附加软件。你还需要确保网关不会成为瓶颈-如果不需要,不要尝试将太多的东西卸载到网关上。

  出口网关

另一方面(或另一端),出口网关在你的专用网络内部运行,并且可以用作退出网络的流量的出口点。例如,如果你的应用程序与外部API(例如,Github)进行交互,则对https://api.github.com的任何请求都将首先通过出口网关,然后出口网关可以将调用代理到外部服务。

分享一些关于网关和代理的初学者指南_第8张图片

你为什么要使用出口网关?出口网关用于控制所有退出网络的流量。例如,如果你知道自己的外部依赖关系(例如Github API),则可以阻止任何其他出站连接。万一你的服务受到威胁,阻止所有出站连接将阻止潜在的攻击者进行进一步的攻击。如果我们更进一步,则可以在专用计算机上运行出口网关,在其中可以应用更严格的安全策略并分别监视计算机。另一个常见的情况是你的服务器无法访问外部IP或公共Internet。在这种情况下,你的出口网关(可访问网络中的服务)充当所有外部请求的出口点。

实践中的网关

让我们以一个简单的示例来结束此示例,该示例显示网关的一些基本功能。我将使用HAProxy,但其他代理也可以实现相同的功能。你可以从GitHub存储库中获取源代码。

我创建了一个名为Square的服务,该服务公开了一个API。API从URL(一个数字)中获取一个参数,然后返回该数字的平方。该服务打包在Docker映像中。要在你的机器上运行它,你将必须下载并安装Docker。你可以按照说明下载和安装Docker Desktop。

安装Docker Desktop后,打开终端窗口,然后运行learnloudnative/square:0.1.0Docker映像。

第一次运行上述命令时,可能需要花费一些时间,因为Docker需要下载(或使用Docker术语提取)镜像。由于Square服务公开了API,因此我们需要在要访问API的位置提供端口号。因此-p 8080:8080-第一个8080是说我们要在本地计算机的端口8080上公开该服务,第二个8080是该服务正在侦听的端口号。

下载映像并运行容器后,你将看到以下消息:

让我们尝试向服务发送请求。打开第二个终端窗口,以使服务保持运行,并运行以下命令

分享一些关于网关和代理的初学者指南_第9张图片

该服务将返回结果(625),你将在上一个终端窗口中注意到请求也已记录:

分享一些关于网关和代理的初学者指南_第10张图片

你可以按CTRL + C停止运行该程序。

添加代理

为了使事情更容易运行,我将使用同时运行Square服务和HAProxy实例的Docker Compose。如果您不熟悉Docker Compose,请不要担心,它只是同时运行多个Docker容器的一种方式。

该docker-compose.yaml文件定义了两个服务- haproxy和和square-service。该docker-compose.yaml文件如下所示:

分享一些关于网关和代理的初学者指南_第11张图片

除了撰写文件之外,我们还需要一个配置文件来配置HAProxy应该做什么。记住,我们不会直接调用square-serviceDirect,而是将请求发送到代理,代理会将请求传递给square-service。

使用haproxy.cfg具有以下内容的文件配置HAProxy :

分享一些关于网关和代理的初学者指南_第12张图片

我们对两个部分感兴趣- frontend和backend。我们正在调用前端部分api_gateway,这是将代理绑定到地址和端口以及路由传入流量的位置。我们只是在前端部分之后定义default_backend的be_square后端设置a 即可。

在后端部分,我们将创建一个s1带有端点的单个服务器square-service:8080-这是我们为docker-compose.yaml文件中的Square服务定义的名称。

让我们使用Docker compose来运行这两个服务。请确保您从你的文件夹运行以下命令docker-compose.yaml和haproxy.cfg文件包括:

分享一些关于网关和代理的初学者指南_第13张图片

Docker compose完成工作,创建一个新网络和两个服务。从第二个终端,让我们再次运行curl命令:

分享一些关于网关和代理的初学者指南_第14张图片

请注意,这次,我们使用的端口5000是HAProxy公开的端口(请查看docker-compose.yaml文件中的ports部分)。和之前一样,你可以从Square服务获得响应。这次的区别是请求首先通过了代理。

您可以再次按CTRL + C停止运行Docker compose。

在HAProxy上启用统计信息

由于每个请求都通过代理,因此它可以收集有关请求,前端和后端服务器的统计信息。

让我们在HAProxy中启用统计信息,方法是在haproxy.cfg文件末尾添加以下几行:

分享一些关于网关和代理的初学者指南_第15张图片

上面启用了port 8404和URI的统计信息/stats。由于我们要从代理访问统计信息,因此我们还需要在中公开它docker-compose.yaml。在文件"8404:8404"的ports键下添加以下行docker-compose.yaml:

ports:

分享一些关于网关和代理的初学者指南_第16张图片

停止docker-compose如果它正在运行(按CTRL + C),然后运行docker-compose down以删除服务,然后docker-compose up再次启动它们。

容器启动后,即可http://localhost:8404/stats在浏览器中打开。通过运行curl localhost:5000/square/25以生成一些数据来提出几个请求。你将在HAProxy的统计信息报告中注意到会话数。

分享一些关于网关和代理的初学者指南_第17张图片

启用健康检查

HAProxy还支持运行状况检查。可以将HAProxy配置为定期向后端服务发出TCP请求,以确保它们“有效”。要启用运行状况检查,你可以check在haproxy.cfg文件中定义服务器后端的同一行上添加单词。像这样:

更新配置文件后,停止Docker compose(CTRL + C),然后docker-compose up再次运行以重新启动容器。

如果你打开或刷新stats页面http://localhost:8404/stats,你会注意到be_square表中的行现在变为绿色,这意味着代理正在执行运行状况检查,并且该服务运行正常。在报告图例中,你将看到已active UP使用的。此外,该LastChk列还将显示运行状况检查的结果。

拒绝要求

假设我们要保护我们的Square服务,并要求用户在发出请求时提供API密钥。如果他们没有API密钥,则我们不想允许他们调用该服务。

使用HAProxy进行此操作的一种方法是对其进行配置,以使其拒绝所有未设置API标头的请求。为此,你可以bind在haproxy.cfg文件的前端部分中的命令之后添加以下行:

此行告诉代理拒绝所有请求,除非有一个名为api-keyset 的标头。让我们重新启动容器(CTRL + C和docker-compose up),看看它是如何工作的。

  如果你在未api-key设置标头的情况下发出请求,则会返回403响应,如下所示:

分享一些关于网关和代理的初学者指南_第18张图片

但是,如果你包含api-key标头,则代理将使请求通过,然后你将获得服务的响应,就像之前一样:

分享一些关于网关和代理的初学者指南_第19张图片

限速请求

最后,我们还要实现一个速率限制器,这样一个用户就不能发出太多请求,也不会给服务带来不必要的压力。

我们将不得不在haproxy.cfg文件中定义几件事。我将首先分别解释它们,然后我们将它们放在一起。

存储/计数请求

为了使速率限制器正常工作,我们需要一种计数和存储所发出请求数量的方法。我们将使用HAProxy称为stick table的内存中存储。使用stick表,你可以存储请求数,然后在一定时间(在我们的情况下为5分钟)后自动使请求过期(删除):

设置请求限制

我们还需要设置一个限制。这个限制是一个数字,从这一点开始,我们将拒绝(或限制)请求。我们将使用访问控制列表或ACL来测试条件(例如,请求数量是否大于X)并基于该条件执行操作(例如,拒绝请求):

上一行检查具有特定api-key值的请求数是否大于10。如果未超出限制,我们将跟踪请求并允许其继续:

否则,如果超出限制,我们将拒绝该请求:

所有这些更改都需要frontend api_gateway在haproxy.cfg文件的部分中进行。这应该是这样的:

分享一些关于网关和代理的初学者指南_第20张图片

是时候尝试一下了!重新启动容器,并向该服务发出10个请求。在第11个请求上,你将获得429 Too Many Requests响应,如下所示:

分享一些关于网关和代理的初学者指南_第21张图片

您可以等待5分钟以使速率限制器信息失效,或者尝试使用其他方法api-key,您会发现请求将通过

分享一些关于网关和代理的初学者指南_第22张图片

最后,您可以再次检查stats页面,特别是表中的Denied列api_gateway。“ 拒绝”列将显示被拒绝的请求数。

总结

在本文中,我解释了什么是网关或代理,并展示了一些实用的示例,说明了如何使用网关来实现速率限制或拒绝请求。

你可能感兴趣的:(分享一些关于网关和代理的初学者指南)