如何从私有 AWS ALB 公开 API 端点
Posted
技术标签:
【中文标题】如何从私有 AWS ALB 公开 API 端点【英文标题】:How to expose APIs endpoints from private AWS ALB 【发布时间】:2018-07-23 00:32:37 【问题描述】:我们在 AWS ECS 上拥有多个微服务。我们有一个 ALB,它对不同的微服务有不同的目标组。我们希望在外部公开一些端点,而一些端点仅用于内部通信。
问题在于,如果我们将负载均衡器放在公共 VPC 中,这意味着我们将所有注册端点都暴露在外部。如果我们将负载均衡器移至私有 VPC,我们必须在公共 VPC 中使用某种代理,这需要额外的基础设施/成本以及所有安全问题(如 D-DOS 等)的自定义实现。
我们可以有哪些可能的方法,或者 AWS 是否为此提供了某种开箱即用的解决方案?
【问题讨论】:
【参考方案1】:我强烈建议为此运行 2 个 alb。当然,它会花费你更多(不是加倍,因为流量成本不会加倍),但是拥有一个内部负载均衡器和一个外部负载均衡器要简单得多。工作时间也要花钱!运行 2 个 albs 将是最少的管理员,并且可能是最便宜的整体。
【讨论】:
据我了解,一个 ALB(应用程序负载均衡器)无法重定向到另一个 ALB。如果我的理解不正确,请纠正我。 我认为你是对的,但我并不是建议你使用链白。有两个独立的 alb,一个用于内部,一个用于外部。 挑战是我们使用ECS,一个容器不能注册到两个ALB。如果单个微服务同时具有两种类型的端点(公共和私有),我们最终可能会运行两个具有两个 ALB 的 ECS,因此在内部和外部公开,从基础设施和管理的角度来看,这看起来非常多余。如果有任何问题,我们可以选择在公共 *** 中设置代理并将 ALB 移动到私有 ALB。 不幸的是,一个容器无法注册到 2 个 ELB;但是没有理由不能让每个服务注册到不同的 ALB。这确实意味着您不能从相同的服务定义运行服务的公共和私有方面。但是你可以运行你的服务两次,一次在公共后面,一次在私人后面。我不会那样构建服务,但如果我必须托管一个,那就是我会做的。这对我来说是一个有趣的问题,感谢您的反馈。我希望你最终得到你喜欢的东西。 谢谢,丹。我只是想澄清一件事,当您说两次运行服务时,您的意思是在单独的 ECS 服务下运行两个单独的容器,一个将注册公共 ALB,第二个将注册私有 ALB,对吗?【参考方案2】:结帐 WAF。它代表 Web 应用程序防火墙,可作为 AWS 服务使用。请按照以下步骤操作:
-
创建 WAF ACL。
为您的私有端点添加“字符串和正则表达式匹配”条件。
为允许访问私有端点的 IP 列表/范围添加“IP 地址”条件。
在您的 ACL 中创建一条规则以在满足上述两个条件时允许访问。
将 ALB 分配给您的 WAF ACL。
更新:
在这种情况下,您必须在公共子网中使用面向外部的 ALB,如 Dan Farrell 在下面的评论中所提到的。
【讨论】:
与内部 alb 的连接永远不会在外部端点上,对外部 elb 的请求永远不会来自外部端点。所以这只有在你把 alb 放在外部时才有效。然后您还必须允许来自外部 ips 的流量,因此无论您的内部流量如何通过【参考方案3】:我建议这样做:
一个内部 ALB 每个微服务一个目标组,受 ECS 限制。 一个网络负载均衡器 (NLB),一个基于 ip 的目标组。 基于 Ip 的目标组将具有内部 ALB ip 地址,因为 ALB 的私有 ip 地址不是静态的,您需要使用此 lambda 函数设置 cloudwatch cron 规则(来自 aws 文档并修改为在公共上工作端点):https://github.com/talal-shobaita/populate-nlb-tg-withalb/
ALB 和 NLB 都可扩展并受到 AWS 的 DDOS 保护,AWS WAF 是另一个出色的工具,可以直接连接到您的 ALB 侦听器以提供扩展保护。
或者,您可以等待 AWS 支持每个服务的多个目标组注册,这已经在他们的路线图中:
https://github.com/aws/containers-roadmap/issues/104
【讨论】:
【参考方案4】:这就是我们最终解决的方法。
-
两个 LB 一个在私有子网中,一个在公共子网中。
有些 API 本来是公开的,所以直接通过公共 LB 公开。
对于一些需要公开的私有 API 端点,在公共 LB 中添加一个代理,并通过此代理将这些特定路径从公共 LB 路由到私有 LB。
【讨论】:
【参考方案5】:如今,API 网关是执行此操作的最佳方式。您可以让您的 API 为多个不同的端点提供服务,同时通过 API Gateway 只为公共端点提供服务并代理回 API。
【讨论】:
【参考方案6】:我还没有看到它提到它,所以我会注意到我们使用 CloudMap 进行内部路由,使用 ALB 进行“外部”(在我们的例子中只是内部/VPC 间)通信。我没有深入阅读,但我认为this article 描述了它。
AWS Cloud Map 是一种托管解决方案,可让您将逻辑名称映射到应用程序的组件/资源。它允许应用程序使用 AWS 开发工具包、RESTful API 调用或 DNS 查询之一来发现资源。 AWS Cloud Map 为注册资源提供服务,这些资源可以是 Amazon DynamoDB 表、Amazon Simple Queue Service (SQS) 队列、使用 EC2 实例或 ECS 任务或使用无服务器堆栈构建的任何更高级别的应用程序服务。
...
Amazon ECS 与 AWS Cloud Map 紧密集成,为在 ECS 中运行的计算工作负载启用服务发现。当您为 ECS 服务启用服务发现时,它会自动跟踪 AWS Cloud Map 中的所有任务实例。
【讨论】:
【参考方案7】:你想看看AWS Security Groups。
安全组充当您的实例的虚拟防火墙,以控制入站和出站流量。
对于每个安全组,您可以添加控制入站流量到实例的规则,以及一组单独的控制出站流量的规则。
更具体到您的用例可能是他们在ELB Security Groups 上的文档。正如您所料,这些是在 ELB 级别而不是在实例级别应用的安全组。
使用安全组,您可以指定谁有权访问哪些端点。
【讨论】:
如果 ELB 对公共和私有端点有不同的侦听器,则安全组将起作用。这样您就可以通过侦听器的端口过滤传入的请求。这是可能的,但并不理想。相反,您可以为 ALB 启用 WAF 并配置一组规则。 将内部与外部端点(端口)隔离实际上是非常标准的做法。 就像 alb 本身一样,附加到 elb 的安全组将看到内部流量或外部流量,但不能同时看到两者。您不能在同一个 alb 上拥有内部和外部侦听器,因此除非您想公开所有流量然后设置防火墙,否则这将不起作用。请记住,外部流量也不会免费,内部地址上相同 az 中的流量将是免费的。 对,这个想法就是——如果你想维护一个单一的负载均衡器,允许所有流量和防火墙受保护的端口是做到这一点的方法。维护一个带有防火墙内部端口的安全组比维护两个安全组要容易得多。也许不是首选,但更容易。以上是关于如何从私有 AWS ALB 公开 API 端点的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 http 触发器从 AWS SNS 触发 GCP 云功能(私有)
AWS - 从公共 API 网关到 VPC 内 lambda 的路由