AWS ECS服务连接与服务发现

6
AWS Cloud Map 允许您为您的 VPC 设置一些命名空间,然后在该命名空间内为各个服务分配名称。这些名称可以是 A) 仅通过 API 调用进行私有发现,B) 可通过 API 调用或在 VPC 内部私有 DNS 中进行发现,或 C) 可通过公共 DNS 和 API 调用进行发现。ECS 可以与 Cloud Map 交互,自动注册服务。所有这些都在 AWS ECS 中称为 服务发现
AWS ECS 还有一个相对较新的东西叫做 服务连接。它利用 Cloud Map,但还向您的 ECS 服务添加了一个旁路“代理”容器,从而有效地创建了一个自动服务网格。
我使用CloudFormation使得Service Connect与ECS配合工作。在我的CloudFormation中,我配置了AWS::ECS::Cluster,并将ServiceConnectDefaults配置为我想要使用的Cloud Map命名空间,例如example.internal。然后,在ServiceConnectConfiguration下,我为AWS::ECS::Service定义设置了enabled: true,同时提供了一些额外的细节,比如为service/port提供一个名称。假设我已经给我的服务/端口命名为my-service,我相信现在同一VPC中使用Service Connect的其他服务可以连接到my-service.example.internal,而无需使用DNS,sidecar-proxy会自动找到某个my-service的实例进行连接!(我还没有测试过这一点;我首先想要在当前问题上获得一些澄清。)

但是我也想要私有DNS访问,这样至少可以去Cloud9并发出例如curl my-service.example.internal/api/test而不需要查找my-service实例之一的IP地址。我发现我可以定义一个AWS::ServiceDiscovery::PrivateDnsNamespace和一个AWS::ServiceDiscovery::Service(使用相同的名称my-service),甚至可以使用ServiceRegistries将后者与我的ECS服务关联起来。但是当我尝试部署我的CloudFormation堆栈时,我会收到错误:

提供的请求无效:CreateService错误:服务已存在。

我猜想为了让Service Connect正常工作,ECS内部创建了自己的AWS::ServiceDiscovery::Service,此时它发现我的CloudFormation堆栈已经创建了一个同名的AWS::ServiceDiscovery::Service。但是如果我不自己创建AWS::ServiceDiscovery::Service,那么ECS创建的那个将不会为my-service提供DNS条目。

我是否可以推断出AWS ECS可以与Service Connect一起使用(在这种情况下将没有服务DNS条目,但是旁路代理将使用API调用来查找注册的服务),或者Service Discovery(在这种情况下,我手动创建Cloud Map DNS条目,ECS将根据我关联到ECS服务的AWS::ServiceDiscovery::Service自动注册它们),但不能同时使用两者?还是我配置有误?

我想,如果我正在使用Service Discovery并获得DNS条目,我只需在其他服务中指示(在我的情况下是私有的)DNS条目,它们将通过Cloud Map找到它们,为我提供与Service Connect相同的功能,而无需旁路代理。但也许Service Connect具有一些额外的监控功能,我将失去它们吗?

有没有人能够确认这个理解是否正确,并且详细阐述在使用Service Connect或Service Discovery与ECS时的实际差异和影响?

我在意识到Service Connect不会为我添加一个支持DNS的AWS::ServiceDiscovery::Service之前,为此努力了几天。我只是创建了自己的,并使用AWS::ECS::Service ServiceRegistry来注册我的容器。我的服务发现客户端是一个传统的应用程序,因此它需要进行DNS查找,在这种情况下,我并没有从Service Connect中获得太多好处。 - Maj
1个回答

8
使用Service Connect与使用普通的Cloud Map进行服务发现相比,带来的好处是当服务实例关闭时更快的故障转移。使用基于DNS的Cloud Map查找意味着当一个服务关闭时,可能需要一段时间(基于TTL设置)才能让客户端意识到它应该获取一个新的IP地址。更糟糕的是,您的客户端库可能会将相同的IP地址缓存更长时间,并且您的客户端重试逻辑可能会在失败时继续尝试相同的IP地址。
另一方面,Service Connect引入了一个侧车“代理”容器,拦截出站连接并将其路由到正确的目标。该侧车使用API调用Cloud Map以实时查找健康服务实例的IP地址,而不是依赖可能过期的DNS条目。这带来了服务网格(如Envoy)的标准优点,但在这种情况下,Service Connect为您管理侧车。有关这些好处的更多讨论,请参见将现有的Amazon ECS服务从服务发现迁移到Amazon ECS Service Connect

因为Service Connect不依赖DNS,它不会注册私有DNS条目,而是使用Cloud Map注册仅通过API调用才能发现的端点。似乎没有办法告诉Service Connect也在DNS中注册服务名称。

您不能同时为相同的服务名称使用Service Connect和Service Discovery,因为如问题中所述,两者都会尝试在Cloud Map中注册相同的服务名称。但您可以使用两者,并使用两个不同的服务名称!如果您定义了任务定义端口映射和服务ServiceConnectConfiguration,并使用诸如my-service-connect这样的服务/端口发现名称,已指定ECS集群ServiceConnectDefaults的命名空间为example.internal,则即使没有该名称的DNS条目,您的其他ECS服务也可以连接到my-service-connect.example.internal,正如上面所述。

但是,您还可以定义一个AWS :: ServiceDiscovery :: PrivateDnsNamespace,名称为example.internal(Service Connect将使用它而不是创建新的),以及使用不同服务名称,例如my-serviceAWS :: ServiceDiscovery :: Service。使用ServiceRegistries将此服务发现与ECS服务关联,并且您将拥有最佳的两个世界! ECS服务可以使用my-service-connect.example.internal进行通信,但是您仍然可以转到Cloud9并通过DNS连接到my-service.example.internal(请注意不同的名称),因为ECS将确保两者都已注册。不能保证这两种方法在任何特定时间都引用相同的服务实例,如果服务实例关闭,则DNS方法my-service.example.internal可能会过时,直到新的DNS值传播,但对于Cloud9中的临时测试(首先的动机)几乎没有影响。
我已发布一篇博客文章使用AWS ECS服务连接和服务发现相结合,其中深入介绍了如何使其工作,并提供了完整的CloudFormation模板片段。

1
我的理解是,边车不会进行Route53调用。这是两种独立但互补的技术。请仔细阅读我的回答和博客文章。例如,我说:“边车使用API调用Cloud Map实时查找服务的健康实例的IP地址,而不是依赖可能过时的DNS条目。”我认为Service Connect的边车根本不使用Route53。 - Garret Wilson
1
在您提到的页面上写着:“……一种在命名空间内统一引用服务的方式,不依赖于Amazon VPC DNS配置……。”这是服务网格与基于DNS的服务发现的标准目的之一。还可以参考《将现有的Amazon ECS服务从服务发现迁移到Amazon ECS Service Connect》(https://aws.amazon.com/blogs/containers/migrate-existing-amazon-ecs-services-from-service-discovery-to-amazon-ecs-service-connect/)中所述:“……Amazon ECS Service Connect处理请求的方式不再依赖于Amazon Route 53中的DNS托管区域……。” - Garret Wilson
1
事实上,这个问题的核心动机之一是Service Connect默认创建了一个Cloud Map AWS::ServiceDiscovery::HttpNamespace,根据文档所述,"无法使用DNS进行发现",因此Service Connect必须使用Cloud Map API调用。换句话说,透明地使用Cloud Map API调用而不是Route 53 DNS几乎就是Service Connect的全部意义所在。 - Garret Wilson
1
也许你所忽略的是,你可以以两种不同的方式使用Cloud Map:通过DNS或仅通过API调用。这就是为什么有AWS::ServiceDiscovery::PrivateDnsNamespaceAWS::ServiceDiscovery::HttpNamespace之间的区别。Service Connect使用后者。 - Garret Wilson
1
请查看什么是AWS Cloud Map?:"[命名空间]...指定了您希望如何定位资源的方式:使用AWS Cloud Map DiscoverInstances API调用,在VPC中进行DNS查询,或者进行公共DNS查询"。 - Garret Wilson
显示剩余9条评论

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