亚马逊AWS官方博客

基于Amazon API Gatewy的跨账号跨网络的私有API集成

一、背景介绍

本文主要讨论的问题是在使用Amazon API Gateway,通过Private Integration、Private API来完成私有网络环境下的跨账号或跨网络的API集成。API管理平台会被设计在单独的账号中(亚马逊云科技提供的是多租户的环境),因为客观上不同业务系统的存在,都需要和API管理平台集成,所以API管理平台很有可能会连接不同网络环境,可能是亚马逊云科技提供的其他的区域、线下的环境、或是其他云的环境。

在讨论正题之前,我们先来谈论下API管理平台。API是现代应用开发的一个典型部分。它们使应用程序、系统和服务能够有效沟通,打破了底层技术的孤岛。为了以有效和可扩展的方式最大限度地利用这些API,API管理是必须的。利用API管理平台可以使企业能够以安全、简便和高效的方式规划、设计、测试、发布、运营、安全和版本控制其API,从而获得企业所能提供的数据和服务的最大潜力。

Amazon API Gateway 是一种完全托管的服务,可以帮助开发人员轻松创建、发布、维护、监控和保护任意规模的API。API充当应用程序的前门,可从您的后端服务访问数据、业务逻辑或功能。使用 API Gateway,您可以创建 RESTful API、Http API和 WebSocket API,以便实现实时双向通信应用程序。API Gateway 支持容器化和无服务器工作负载,以及 Web 应用程序。

API Gateway 负责管理所有任务,涉及接受和处理成千上万个并发 API 调用,包括流量管理、CORS 支持、授权和访问控制、限制、监控,以及 API 版本管理。API Gateway 没有最低费用或启动成本。您只需为您收到的 API 调用和传出的数据量付费。

我们观察到不同的客户都在评估或是部署API管理平台,Amazon API Gateway作为一个云原生无服务器架构的API管理平台,将能很好的满足您对API管理的需求。

另外,基于OpenAPI接口规范实现的应用程序可以自动生成方法、参数和模型的文档。这有助于保持文档、客户端库和源代码的同步。并且OpenAPI规范是不分语言的。通过OpenAPI的声明性资源规范,客户可以理解和消费服务,而无需了解服务器的实现或访问服务器代码。API Gateway 也支持 OpenAPI v2.0 和 OpenAPI v3.0 的规范。

二、概念介绍

当您在使用API Gateway的过程中,有一些关键的概念和定义,是达成API Gateway主要功能的前置条件。

Integration(集成),这个是API Gateway实现其功能的核心概念。不论是Restful API、HTTP API还是WebSocket API,都是通过Integration(集成)这个关键动作将API Gateway暴露出的供访问的接口和后端的具体实现相连接。这里的后端可能是Lambda 函数、其他AWS服务、或是其他的 HTTP 资源、亦或是置放于VPC内的私有资源或内部网络中的资源。只是,REST API 由资源和方法组成;HTTP API 由路由和资源组成;WebSocket API也是由路由和路由键组成;

REST API 由资源和方法组成。资源是一种逻辑实体,应用程序可以通过资源路径来访问资源。方法与您的 API 用户提交的 REST API 请求以及返回给该用户的相应响应对应。

HTTP API 由路由和资源组成。将直接传入 API 请求路由到后端资源。路由包含两部分:HTTP 方法和资源路径,例如,GET /pets。您可以为路由定义特定的 HTTP 方法。或者,您可以使用 ANY 方法匹配尚未为资源定义的所有方法。您可以创建一个 $default 路由,用作与任何其他路由不匹配的请求的“捕获全部”方法。

WebSocket API由路由和路由键组成。与接收和响应请求的 REST API 不同,WebSocket API 支持客户端应用程序与后端之间的双向通信。后端可以向连接的客户端发送回调消息。

Private Integration:正如上面描述的那样,Integration(集成)是API Gateway中的一个关键动作。Private Integration强调的是集成置放于VPC内的私有资源或内部网络中的资源。官方文档介绍:

https://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/set-up-private-integration.html

VPC Link: 通过 VPC 链接(VPC Link),您可以创建私有集成,将 HTTP API 路由连接到 VPC 中的私有资源,例如 Network/Application Load Balancer 或基于 Amazon ECS 容器的应用程序。私有集成使用 VPC Link来封装 API Gateway 与目标 VPC 资源之间的连接。您可以跨不同的路由和 API 重复使用 VPC 链接。创建 VPC Link时,API Gateway 在您的账户中为 VPC 链接创建和管理弹性网络接口。

其实VPC Link就是为了实现Private Integration的一个技术组件。

Private API:指的是API Gateway暴露的API只能在私有网络内部访问,不能从公网访问。

以上的Private Integration,Private API和VPC Link,这里还有一个博客文章,可供大家学习参考:https://aws.amazon.com/blogs/compute/understanding-vpc-links-in-amazon-api-gateway-private-integrations/

Proxy Integration(代理集成): 借助无所不包的代理资源 {proxy+} 和 REST/HTTP 方法,名为ANY,也就能匹配任何REST/HTTP方法,您可以使用代理集成来创建一个方法为ANY的API。该方法会暴露后端的一整套可访问的 HTTP 资源和操作。当后端 Web 服务器开放更多资源以供公开访问时,客户端可以通过这同一个 API 来访问新资源。

PrivateLink:Amazon PrivateLink 是一项具有高可用性的可扩展技术,它支持将您的 VPC 私密地连接到支持的亚马逊云科技服务、由其他 AWS 账户托管的服务(通过VPC 终端节点服务来实现)以及支持亚马逊云科技Marketplace 合作伙伴服务。您无需使用互联网网关、NAT 设备、公有 IP 地址、 Direct Connect 连接或 Amazon Site-to-Site VPN 连接,就能与该服务通信。

VPC Endpoint services(VPC 终端节点服务):您VPC 中自己的应用程序或服务。

VPC Endpoint(VPC 终端节点):在VPC中可让您私密地连接到VPC 终端节点服务的入口点。

三、架构图和问题定义

1) 架构图介绍

1.1)因为在真实的场景中,API管理平台会被设计在单独的账号中(亚马逊云科技提供的是多租户的环境),又因为客观上不同业务系统的存在,都需要和API管理平台集成,所以API管理平台很有可能会连接不同网络环境,可能是亚马逊云科技提供的其他的区域、线下的环境、或是其他云的环境。因此上面的架构图设计了跨账号、跨不同网络的环境。

1.2)这里设定3个云上的账号,分别是API-Gateway Account,Application Account和Consumer Account。为了配置方便,这里Consumer和API-Gateway在同一个账号中相同的VPC中。同时还有一个Other Place来表征可能是亚马逊云科技提供的其他的区域、线下的环境、或是其他云的环境。

2) 问题定义

如上面的架构图,本文主要讨论的问题是在使用API Gateway情况下,通过Private Integration、Private API、VPC Link以及VPC Endpoint services、VPC Endpoint。来完成私有网络环境下的跨账号或跨网络的API集成。

四、具体配置

配置主要分两块,一是和跨账号的内部应用API进行集成,二是通过和内部网络资源集成。

1. 和跨账号的内部应用API进行集成

1) 配置接口终端节点服务(VPC Endpoint Services)

登陆到Application Account(01477*******),在EC2中选择Load Balancers,查看通过EKS创建好的Service(以internal NLB的形式出现),这里相当于架构图上的紫色1和2

参考官方手册https://docs.amazonaws.cn/vpc/latest/privatelink/create-endpoint-service.html

完成“接口终端节点服务”创建,这里相当于架构图上的紫色3。

选择服务–VPC中的Endpoint Services,然后点击 Create endpoint service

选择之前EKS创建好的Service(以NLB暴露的)

其他选项保持默认。

https://docs.amazonaws.cn/vpc/latest/privatelink/add-endpoint-service-permissions.html

在创建终端节点服务配置后,您可以控制哪些服务使用者能够创建连接您服务的接口终端节点。

输入允许访问此接口终端节点服务的AWS账号中的IAM user或role的ARN,可以参考如下官方手册:

https://docs.amazonaws.cn/vpc/latest/privatelink/add-endpoint-service-permissions.html

创建好的“接口终端节点服务”如下,复制Service name,接下来会用。

2) 配置接口终端节点VPC Endpoint

登陆到API-Gateway Account(84234*******),选择服务–VPC中的Endpoint,然后点击 Create endpoint,输入Name和之前复制的Service name,并Verify

service。这里相当于架构图上的紫色4和5。

这里选择VPC和Subnets时需要注意,因为会分别在选定的子网中创建一个端点网络接口(ENI)。一个端点网络接口会从你的子网的IP地址范围内分配一个私有IP地址,并保持这个IP地址,直到接口端点被删除。

注意创建好的在子网中的网络接口(ENI),记录对应的子网和ip 地址。

3) 接受终端节点连接请求(Endpoint connections)

登陆到Application Account(01477*******),在VPC中选择Endpoint services,选择之前创建的Endpoint services。在Endpoint connections中选择Accept endpoint connection request。

4) 创建供VPC link使用的NLB

登陆到API-Gateway Account(84234*******),选择服务–EC2中的Target groups, 然后选择IP addresses, 配置如下,其他保持默认。这里相当于架构图上的紫色6。

在下一步中network选择对应的VPC,IP地址输入上一步记录下来的IP地址。

登陆到API-Gateway Account(84234*******),选择服务–EC2中的Load balancers,然后点击 Network Load Balancer处的Create。选择Internal。

这里选择对应的VPC和子网。

创建完成后,记录NLB DNS name( nlb-vpc-link-bbbd845d48779f09.elb.us-east-1.amazonaws.com )

5) 创建供VPC Link

登陆到API-Gateway Account(84234*******),选择服务–API Gateway中的VPC links, 然后点击Create选择VPC link for REST APIs, 在点击Create。这里相当于架构图上的紫色6。

在Target NLB中选择刚创建的NLB:

注意创建好的VPC Link的状态是Available, 同时记录VPC Link ID是nlb-vpc-link(wo74ch), 接下来需要使用。

6) 为创建Private Restful API而准备针对API GatewayVPC Endpoint

这里先解释一下,虽然都是叫VPC Endpoint,这里的VPC Endpoint是为API Gateway这Serverless服务创建一个Interface VPC Endpoint,也就是在指定的VPC中的子网创建ENI。而之前的创建的VPC Endpoint是为了访问其他账号的通过VPC Endpoint services暴露出来的服务。共同点是它们都用了Private Link的技术。

登陆到API-Gateway Account(84234*******),选择服务–VPC中的Endpoints, 然后点击Create endpoint。这里相当于架构图上的紫色8。

记录创建好的VPC Endpoint ID,接下来需要使用

7) 针对跨账号的资源创建Private Restful API

登陆到API-Gateway Account(84234*******),选择服务–API Gateway中的APIs, 然后选择REST API Private, 在点击Build。这里相当于架构图上的紫色7。

配置如下图,在Endpoint Type处选择Private, VPC Endpoint IDs输入上一步记录的VPC Endpoint ID。

接下来,我们接下来创建资源(Resource)和方法(Method)

创建Resource,勾选Configure as proxy resource和Enable API Gateway CORS,因为选择了Configure as proxy resource,所以将/{proxy+}配置为代理资源,可以捕获所有对其子资源的请求。例如,它适用于对/foo的GET请求。为了处理对/的请求,在/资源上添加一个新的ANY方法。否则资源的访问只能通过路径https://*.execute-api.*.amazonaws.com/test/{proxy+} 访问资源,无法通过路径 https://*.execute-api.*.amazonaws.com/test/ 访问资源。

在跳出的页面中配置private integration,具体配置如下,Integration type处选择VPC Link,勾选Use Proxy Integration,VPC Link处选择之前创建的VPC Link — nlb-vpc-link(wo74ch). Endpoint URL 输入NLB DNS name( nlb-vpc-link-bbbd845d48779f09.elb.us-east-1.amazonaws.com ). 注意此处的Endpoint URL参数不是用于将请求路由到终端节点,而是用于设置 Host 标头和证书验证。

同样的在/下如上面的步骤创建ANY method。否则资源的访问只能通过路径https://*.execute-api.*.amazonaws.com/test/{proxy+} 访问资源,无法通过路径 https://*.execute-api.*.amazonaws.com/test/ 访问资源。

在Deploy API 之前需要创建Resource Policy,来限定和保护你的API可供满足什么条件的访问,比如限定ip地址,VPC,只能通过API Gateway VPC endpoint才能访问。选择Resource Policy输入如下内容:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/*",
            "Condition": {
                "StringNotEquals": {
                    "aws:sourceVpce": "vpce-0416bbea8fb2bd63a"
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/*"
        }
    ]
}

“aws:sourceVpce”: “vpce-0416bbea8fb2bd63a”为限定只能从名为vpce-0416bbea8fb2bd63a的VPC endpoint来访问此API。

通过Deploy API来部署API:

因为Resource Policy的限制,只能通过私网环境访问。

8) 跨账号通过私有网络测试Private Restful API

现在模拟从Consumer Account发起对api — https://3eqr0osoc3.execute-api.us-east-1.amazonaws.com/test 访问

测试成功。

2. 和内部网络资源集成

和内部网络资源集成又分两种情况

(1)需要被集成的资源是通过IP地址来访问的

(2)需要被集成的资源是通过Endpoint/URL来访问的

接下来针对被集成的资源是通过IP地址来访问的来讨论,具体的配置过程:

1) 确保网络打通

在架构图中,通过Transit Gateway以及Direct connect和线下或是其他网络环境已经建立了网络连接。我在这里是通过同一个亚马逊云科技的账号跨不同的区域来模拟此种场景。

这里相当于架构图上的红色2,3,4,5。

我已经在Other Region部署好了nginx的EC2的环境,用来模拟在Other Place

(AWS other Region/On-premise/3rd location)中资源,有IP地址是172.31.12.59。这里相当于架构图上的红色1。

2)利用之前创建好的针对API GatewayVPC Endpoint

也可以参考之前的步骤:

6)为创建Private Restful API而准备针对API Gateway的VPC Endpoint

这里相当于架构图上的红色9。

3)创建为VPC link准备的NLB

登陆到API-Gateway Account(84234*******),选择服务–EC2中的Target groups, 然后选择IP addresses, 选择已经和Other Place

(AWS other Region/On-premise/3rd location)建立了连接的VPC,协议选择TCP。配置如下,其他保持默认。

在下一步中network选择对应的Other private IP address,IP地址输入在Other Place

(AWS other Region/On-premise/3rd location)中部署的资源EC的IP地址172.31.12.59。再点击Include as pending below.这样你就可以在Review Targets看到添加的Target.

登陆到API-Gateway Account(84234*******),选择服务–EC2中的Load balancers,然后点击 Network Load Balancer处的Create。选择Internal。

这里选择对应的VPC和子网。

选择刚才创建好的Target Group。

创建完成后,记录NLB DNS name( nlb-other-network-137d7c7c7e159265.elb.us-east-1.amazonaws.com )

4) 创建VPC Link

登陆到API-Gateway Account(84234*******),选择服务–API Gateway中的VPC links, 然后点击Create选择VPC link for REST APIs, 在点击Create。这里相当于架构图上的红色6,7。在Target NLB中选择刚创建的NLB:

注意创建好的VPC Link的状态是Available, 同时记录VPC Link ID是nlb-other-network (6h953x), 接下来需要使用。

5)针对跨网络的资源创建Private Restful API

登陆到API-Gateway Account(84234*******),选择服务–API Gateway中的APIs, 然后选择REST API Private, 在点击Build。这里相当于架构图上的红色8。

配置如下图,在Endpoint Type处选择Private, VPC Endpoint IDs输入之前创建的VPC Endpoint ID。

接下来,我们接下来创建资源(Resource)和方法(Method)

创建Resource,勾选Configure as proxy resource和Enable API Gateway CORS,因为选择了Configure as proxy resource,所以将/{proxy+}配置为代理资源,可以捕获所有对其子资源的请求。例如,它适用于对/foo的GET请求。为了处理对/的请求,在/资源上添加一个新的ANY方法。否则资源的访问只能通过路径https://*.execute-api.*.amazonaws.com/test/{proxy+} 访问资源,无法通过路径 https://*.execute-api.*.amazonaws.com/test/ 访问资源。

在跳出的页面中配置private integration,具体配置如下,Integration type处选择VPC Link,勾选Use Proxy Integration,VPC Link处选择之前创建的VPC Link — nlb-other-network (6h953x). Endpoint URL 输入上一步准备的NLB DNS name( nlb-other-network-137d7c7c7e159265.elb.us-east-1.amazonaws.com )。注意此处的Endpoint URL参数不是用于将请求路由到终端节点,而是用于设置 Host 标头和证书验证。

同样的在/下如上面的步骤创建ANY method。此处不赘述。

在Deploy API 之前需要创建Resource Policy和Deploy API,遵照之前的步骤就可以了。

通过Deploy API来部署API:

Serverless

创建好的API如下:

5) 跨网络通过私有网络测试Private Restful API

现在模拟从Consumer Account发起对api — https://buw9ocq5f5.execute-api.us-east-1.amazonaws.com/newtest访问

测试成功。

五、总结

通过以上的步骤,我们通过亚马逊云科技API管理平台API Gateway完成跨账号和内部应用API进行集成,另外通过和内部网络资源集成。很好的满足了在私有网络情况下通过Rest对API管理和集成。

参考材料:

https://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/set-up-api-with-vpclink-cli.html

https://docs.amazonaws.cn/aws/latest/userguide/api-gateway.html

https://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/set-up-private-integration.html

https://aws.amazon.com/blogs/compute/understanding-vpc-links-in-amazon-api-gateway-private-integrations/

https://docs.amazonaws.cn/vpc/latest/privatelink/create-endpoint-service.html

https://docs.amazonaws.cn/vpc/latest/privatelink/add-endpoint-service-permissions.html

本篇作者

金忠敏

AWS解决方案架构师,现在专注于云计算解决方案和架构的工作。具有超过15年的IT从业经验,曾从事软件开发,售后支持,系统交付,售前等工作。参与过很多大型项目架构设计和实施交付。