在 VPC 内的 Amazon ECS 服务之间联网 - Amazon Elastic Container Service

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在 VPC 内的 Amazon ECS 服务之间联网

在 VPC 中使用 Amazon ECS 任务,您可以将整体应用程序拆分为不同的部分,这些部分可以在安全的环境中独立部署和扩展。这种架构称为面向服务的架构 (SOA) 或微服务。但是,要确保 VPC 内外的所有部分都能相互通信,可能具有挑战性。有几种促进沟通的方法,它们的优点和缺点各不相同。

使用服务 Connect

我们推荐 Amazon ECS Service Connect,它为服务发现、连接和流量监控提供亚马逊 ECS 配置。借助 Service Connect,您的应用程序可以使用短名称和标准端口连接到同一集群中的 ECS 服务,也可以连接到其他集群中的 ECS 服务,包括同一 AWS 区域集群中的 VPC。有关更多信息,请参阅《亚马逊弹性容器服务开发者指南》中的 Amazon ECS Service Connect

使用 Service Connect 时,ECS 会管理服务发现的所有部分:创建可以发现的名称,在任务开始和停止时动态管理每个任务的条目,在配置为发现名称的每个任务中运行代理。您的应用程序可以通过使用 DNS 名称的标准功能,并建立连接来查找这些名称。如果您的应用程序已执行此操作,则您无需修改应用程序即可使用 Service Connect。

该图显示了使用服务连接的网络架构。
更改仅在部署期间发生

您在每个 ECS 服务和任务定义中提供完整的配置。ECS 管理每个服务部署中对此配置的更改,以确保部署中的所有任务都以相同的方式运行。例如,DNS 作为服务发现的一个常见问题是控制迁移。如果您将 DNS 名称更改为指向新的替换 IP 地址,则在所有客户端开始使用新服务之前,可能需要最大的 TTL 时间。使用 Service Connect,客户端部署将通过替换客户端任务来更新配置。您可以像配置任何其他部署一样配置部署断路器和其他部署配置,以对 Service Connect 更改造成影响。

使用服务发现

另一种 service-to-service 通信方法是使用服务发现进行直接通信。在这种方法中,您可以使用与 Amazon ECS 的 AWS Cloud Map 服务发现集成。使用服务发现,Amazon ECS 将已启动的任务列表同步到 AWS Cloud Map,后者维护一个 DNS 主机名,该主机名解析为来自该特定服务的一个或多个任务的内部 IP 地址。Amazon VPC 中的其他服务可以使用此 DNS 主机名,以通过其内部 IP 地址将流量直接发送到另一个容器。有关更多信息,请参阅《Amazon 弹性容器服务开发者指南》中的服务发现

该图显示了使用服务发现的网络架构。

在上图中,有三种服务。 serviceA有一个容器并与之通信serviceB,后者有两个容器。 serviceB还必须与之通信serviceC,后者只有一个容器。这三个服务中的每个容器都可以使用中的内部 DNS 名称从 AWS Cloud Map 需要与之通信的下游服务中查找容器的内部 IP 地址。

这种 service-to-service 通信方式可提供低延迟。乍一看,它也很简单,因为容器之间没有额外的组件。流量直接从一个容器传递到另一个容器。

这种方法适用于使用 awsvpc 网络模式时,在这种模式下,每项任务都有自己唯一的 IP 地址。大多数软件仅支持使用 DNS A 记录,这些记录可直接解析为 IP 地址。使用 awsvpc 网络模式时,每项任务的 IP 地址都是一个 A 记录。但是,如果您使用 bridge 网络模式,则多个容器可能会共享相同的 IP 地址。此外,动态端口映射会导致容器在该单个 IP 地址上被随机分配端口号。此时,A 记录已不足以进行服务发现。您还必须使用 SRV 记录。这种类型的记录可以同时跟踪 IP 地址和端口号,但需要您相应地配置应用程序。您使用的某些预建应用程序可能不支持 SRV 记录。

awsvpc 网络模式的另一个优点是,您的每项服务都有一个唯一的安全组。您可以将此安全组配置为只允许来自需要与该服务通信的特定上游服务的传入连接。

使用服务发现进行直接 service-to-service 通信的主要缺点是,您必须实现额外的逻辑才能进行重试和处理连接失败。DNS 记录有一 time-to-live 个 (TTL) 期限,用于控制缓存多长时间。更新 DNS 记录和缓存过期需要一些时间,这样您的应用程序可以获取 DNS 记录的最新版本。因此,您的应用程序最终可能会将 DNS 记录解析为指向另一个不再存在的容器。您的应用程序需要处理重试,并具有忽略不良后端的逻辑。

使用内部负载均衡器

另一种 service-to-service 通信方法是使用内部负载均衡器。内部负载均衡器完全存在于您的 VPC 内部,并且只能由您的 VPC 内部的服务访问。

该图显示了使用内部负载均衡器的网络架构。

负载均衡器通过将冗余资源部署到每个子网来保持高可用性。当来自的容器serviceA需要与来自的容器通信时serviceB,它会打开与负载均衡器的连接。然后,负载均衡器会从中打开与容器的连接service B。负载均衡器充当管理每项服务之间所有连接的集中场所。

如果容器serviceB停止,则负载均衡器可以将该容器从池中移除。负载均衡器还会对其池中的每个下游目标进行运行状况检查,并可以自动将不良目标从池中移除,直到它们恢复正常。应用程序不再需要知道有多少下游容器。他们只需打开与负载均衡器的连接。

这种方法对所有网络模式都有利。使用网络模式时,负载均衡器可以跟踪任务 IP 地址,在使用awsvpc网络模式时还可以跟踪更高级的 IP 地址和端口组合。bridge它可以在所有 IP 地址和端口组合之间均匀分配流量,即使多个容器实际上托管在同一 Amazon EC2 实例上,只是在不同的端口上。

这种方法的一个缺点是成本。为了实现高可用性,负载均衡器需要在每个可用区中都有资源。由于为负载均衡器和流经负载均衡器的流量支付开销,这会增加额外成本。

但是,您可以通过让多个服务共享一个负载均衡器来降低开销成本。这特别适用于使用 Application Load Balancer 的 REST 服务。您可以创建基于路径的路由规则,将流量路由到不同的服务。例如,/api/user/*可能路由到作为user服务一部分的容器,而/api/order/*可能路由到关联的order服务。使用这种方法,您只需为一个 Application Load Balancer 付费,并且您的 API 有一个一致的 URL。但是,您可以将流量拆分到后端的各种微服务。