一、背景介绍
本文主要讨论的问题是在使用 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 函数、其他 Amazon 服务、或是其他的 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 私密地连接到支持的亚马逊云科技服务、由其他 Amazon 账户托管的服务(通过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
在创建终端节点服务配置后,您可以控制哪些服务使用者能够创建连接您服务的接口终端节点。
输入允许访问此接口终端节点服务的 Amazon 账号中的 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 Gateway 的 VPC 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
(Amazon other Region/On-premise/3rd location) 中资源,有 IP 地址是 172.31.12.59。这里相当于架构图上的红色 1。
2)利用之前创建好的针对 API Gateway 的 VPC 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
(Amazon other Region/On-premise/3rd location) 建立了连接的 VPC,协议选择 TCP。配置如下,其他保持默认。
在下一步中 network 选择对应的 Other private IP address,IP 地址输入在 Other Place
(Amazon 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:
创建好的 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://docs.amazonaws.cn/vpc/latest/privatelink/create-endpoint-service.html
https://docs.amazonaws.cn/vpc/latest/privatelink/add-endpoint-service-permissions.html
本篇作者
金忠敏
Amazon 解决方案架构师,现在专注于云计算解决方案和架构的工作。具有超过 15 年的 IT 从业经验,曾从事软件开发,售后支持,系统交付,售前等工作。参与过很多大型项目架构设计和实施交付。
文章来源:https://dev.amazoncloud.cn/column/article/630a3483d4155422a46...