AWS ECS私有和公共服务

8
我有这样一个场景,需要在AWS ECS上部署多个微服务。我希望这些微服务可以通过各自开发的API相互通信。同时,我也想在AWS ECS上部署前端应用程序,使其可以公开访问并与其他已部署在AWS ECS上的微服务进行通信。如何实现这一点呢?我能否通过将所有服务放置在私有子网中使用AWS ECS服务发现来实现它们之间的通信? 我能否使用弹性负载均衡器,使前端微服务仅通过HTTP/HTTPS协议对终端用户进行互联网访问,并将其保持在私有子网中?
请注意,以上内容中的HTML标签已被保留。
3个回答

13
将AWS负载均衡器(用于公共访问)和Amazon ECS服务发现(用于内部通信)相结合,是Web应用程序的完美选择。
ECS中的内置服务发现是另一个功能,使得开发动态容器环境变得容易,而无需管理应用程序之外的多个资源。ECS和Route 53结合使用,提供高可用性、完全托管和安全的服务发现。
服务发现是一种技术,用于通过容器的直接IP地址将流量从一个容器传输到另一个容器,而不是像负载均衡器这样的中介。它适用于各种用例:
- 私有的、内部的服务发现 - 服务之间低延迟通信 - 长期的双向连接,例如gRPC。
是的,您可以使用AWS ECS服务发现,在私有子网中拥有所有服务,以使它们之间能够通信。
这使得ECS服务能够自动在Amazon Route 53中注册自己,并获得可预测且友好的DNS名称。随着服务根据负载或容器健康状况的变化而缩放,Route 53托管区域会保持最新状态,允许其他服务根据每个服务的状态查找需要建立连接的位置。
是的,您可以使用负载均衡器使前端微服务可以通过互联网对终端用户进行访问。您可以查看此图表,其中显示了用于ECS中Web应用程序的AWS LB和服务发现。

https://aws.amazon.com/blogs/aws/amazon-ecs-service-discovery/

您可以通过ALB访问位于私有子网中的后端容器,而其余容器使用AWS服务发现。

Amazon ECS服务发现

让我们使用服务发现启动一个应用程序!首先,我将创建两个任务定义:“flask-backend”和“flask-worker”。它们都是简单的AWS Fargate任务,具有一个容器用于处理HTTP请求。我会让flask-backend请求worker.corp执行一些工作,并返回响应以及Route 53为worker返回的地址。例如下面的代码:

@app.route("/")
namespace = os.getenv("namespace")
worker_host = "worker" + namespace
def backend():
    r = requests.get("http://"+worker_host)
    worker = socket.gethostbyname(worker_host)
    return "Worker Message: {]\nFrom: {}".format(r.content, worker)

请注意,在这个私有架构中,没有公共子网,只有一个私有子网。子网内的容器可以使用其内部IP地址相互通信。但是他们需要一些方式来发现彼此的IP地址。
AWS服务发现提供了两种方法:
- 基于DNS(Route 53创建和维护一个自定义DNS名称,该名称解析为其他容器的一个或多个IP地址,例如http://nginx.service.production。然后其他容器可以通过使用此DNS名称打开连接来将流量发送到目标) - 基于API(容器可以查询API以获取可用IP地址目标列表,然后直接打开连接到另一个容器之一。)
您可以阅读更多关于AWS服务发现和用例 amazon-ecs-service-discoveryhere

如果我的 Web 层或前端是部署在公共子网中的单独 ECS 服务,它是否仍然可以使用服务发现与我的后端 ECS 服务(位于私有子网中)通信?还是您建议使用其他通信机制? - wildthing81
从 Web 层,您应该使用负载均衡器,私有服务发现仅在 AWS 网络中工作。 - Adiii
Web层部署在同一VPC的公共子网中。您所说的“在AWS网络内”是什么意思? - wildthing81

3
根据文档,“Amazon ECS不支持将服务注册到公共DNS命名空间中”。
换句话说,当它注册DNS时,它只使用服务的私有IP地址,这可能会有问题。 “公共”服务的DNS将注册到私有IP地址上,这只有在您连接到私有网络的VPN时才能正常工作,而不管您的子网规则是什么。
我认为更好的解决方案是将服务附加到两个负载均衡器之一...一个面向互联网,一个面向内部。我认为这更自然地适用于扩展服务。服务发现很酷,但实际上更多用于服务彼此交流,而不是外部客户端。
"Original Answer"翻译成"最初的回答"

1
我想知道为什么你的回答只有很少的赞。我有一个带有私有ALB的网络,本来打算放弃它,只使用ServiceDiscovery,直到我看了你的回答并意识到同时拥有两者是有合理的情况。谢谢。 - Bill Barrington

2
我希望将前端部署在 AWS ECS 上,可以公开访问,并且还可以与部署在 AWS ECS 上的其他微服务进行通信。我将使用服务发现来内部连接服务,使用弹性负载均衡器集成来使其对公众可用。负载均衡器可以在一侧进行负载平衡,DNS SRV 记录可以在内部为 API 进行负载平衡。这里在 Stack Overflow 上有一个类似的问题,答案 [1] 概述了使用 ECS 中的负载均衡器和服务发现集成的可能解决方案。

我可以使用 Elastic Load Balancer 使前端微服务通过 HTTP/HTTPS 协议仅在私有子网中保持对最终用户的可访问性吗?

是的,负载均衡器可以在私有子网中注册目标。

参考资料

[1] https://stackoverflow.com/a/57137451/10473469


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接