亚马逊AWS官方博客

ECS+Route 53,解决云中微服务系统的服务发现问题

为什么微服务需要服务发现(Service Discovery)

我们可以想象一下,当我们需要远程的访问REST API或者Thrift API时,我们必须得知道服务的网络地址(IP Address和port)。传统的应用程序都是运行在固定的物理机器上,IP Address和端口号都是相对固定的。可以通过配置文件方式来实现不定期更新的IP Address和端口号。但是,在基于云的微服务应用中,这是一个非常难以解决的问题。

在基于云的微服务应用中,服务实例的网络地址(IP Address和Port)是动态分配的,并且由于系统的auto-scaling, failures 和 upgrades等因数,一些服务运行的实例数量也是动态变化的。因此,客户端代码需要使用一个非常精细和准确的服务发现机制。

ECS 服务发现(Service Discovery)

Amazon ECS现在能支持与Route 53结合集成的服务发现功能。 这使得ECS服务可以在Amazon Route 53中自动注册一个可预测且命名友好的DNS名称。当您的服务负载或容器根据运行状况而扩展或缩小时,通过Route 53托管的区域可以保持最新状态, 并允许其他服务根据每个服务的状态查找他们需要建立连接的位置。 让你通过ECS运行在VPC内部的Task,可以被更好的发现。

下面的拓扑图很好的演示了ECS Service Discovery的架构和发现流程。大家可以在https://servicediscovery.ranman.com/.这个网址找到基于本图所做的演示。这个演示是在AWS全球博客上发表的。https://amazonaws-china.com/blogs/aws/amazon-ecs-service-discovery/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+AmazonWebServicesBlog+(Amazon+Web+Services+Blog)

注意

服务发现目前仅在以下4个区域可使用:

ECS服务发现(Service Discovery) 概念和术语

服务发现由以下组件组成:

•  服务发现名称空间(Service discovery namespace):一组共享相同域名的逻辑服务组,如example.com。 每个Route 53托管区域和每个VPC都需要一个命名空间。 如果您使用Amazon ECS控制台来创建服务发现功能,则该工作流将为每个ECS群集创建一个私有命名空间。

•  服务发现服务(Service discovery service):存在于服务发现命名空间中,并由名称空间的服务名称和DNS配置组成。 它提供了以下核心组件:

服务目录(Service directory):允许您通过DNS或Route 53自动命名API查找服务获取一个或多个可用于连接到该服务的可用连接端口(endpoint)。

•  健康检查(Health checks):执行定期的容器级健康检查。 如果端点(endpoint)未通过运行状况检查,则将其从DNS路由中删除并标记为不健康。 有关更多信息,请参阅How Amazon Route 53 Checks the Health of Your Resources

 

ECS服务发现(Service Discovery) 设计和考虑

使用服务发现时应考虑以下内容:

•  服务发现支持公共命名空间,但在创建服务发现服务之前,您必须拥有一个现有的公用托管区域,并使用Route 53进行注册。

•  服务发现仅支持使用awsvpc网络模式的任务。

•  可以在您的VPC中查询服务发现服务的DNS记录。它们使用以下格式:“<服务发现服务名称>.<服务发现名称空间>”。有关示例,请参阅Creating a Service Using Service Discovery.

•  您可以为每个服务中的任务创建A或SRV记录的任意组合。如果您使用SRV记录,则需要一个端口。

•  在对服务名称进行DNS查询时,A记录会返回一组与您的任务相对应的IP地址。 SRV记录会为每个任务返回一组IP地址和端口。

•  如果为ECS服务配置了负载均衡器并启用了服务发现,则会使用A记录将流量路由到负载均衡器。负载均衡器也处理健康检查。

•  为服务发现服务指定运行状况检查时,您必须使用由Amazon ECS管理的定制运行状况检查或Route 53运行状况检查。健康检查的两个选项不能合并。

HealthCheckCustomConfig —— Amazon ECS代表您管理健康检查。 Amazon ECS使用来自容器和Elastic Load Balancing运行状况检查的信息以及任务状态来使用Route 53更新运行状况。这是在创建服务发现服务时使用–health-check-custom-config参数指定的。有关更多信息,请参阅Amazon Route 53 API参考中的HealthCheckCustomConfig

HealthCheckConfig —— Route 53创建运行状况检查以监视任务。这要求任务公开可用。这是在创建服务发现服务时使用–health-check-config参数指定的。有关更多信息,请参阅Amazon Route 53 API参考中的HealthCheckConfig

•  如果您使用的是Amazon ECS控制台,则工作流会为每个ECS服务创建一个服务发现服务,并将所有任务IP地址映射为A记录,或将任务IP地址和端口映射为SRV记录。

•  配置了服务发现的现有ECS服务将无法更新其服务发现内容的相关配置。

注意

Fargate也支持任务支持服务发现,但必须使用平台版本v1.1.0或更高版本。 有关更多信息,请参阅 AWS Fargate Platform Versions

ECS服务发现(Service Discovery)定价

使用Amazon ECS服务发现的客户需要使用Route 53自动命名API。 这涉及创建托管区域和查询服务注册表的成本。 有关更多信息,请参阅Amazon Route 53 Pricing

Amazon ECS执行容器级别的运行状况检查,并将其结果发布到Route 53自定义运行状况检查的API。目前这个功能对客户是免费使用的。 如果您为公开的任务配置其他网络健康检查,则需要为这些健康检查付费。

 

动手搭建ECS服务发现(Service Discovery)

一、自建ECS Service Discovery Private Hosted Zone

1. 创建ECS Service

我这里使用的region是us-east-1,并且是使用Fargate作为基础架构。

1.1 配置服务

1.2 配置网络

在这里配置Service Discovery的相关信息。在配置之前,你需要提前创建好一个用于该Service的Load Balancer和对应的Target Group。

提前创建好Load Balancer和Target Group

在Load Balancing部分添加你刚才加入的ALB

下面是重头部分,配置Service Discovery

1.3 配置自动扩展Auto-Scaling

可以根据自己的需要选择是否要task级别的自动扩展

1.4 整体回顾

在ECS创建时最后的review可以看见,ECS的auto scaling在Route 53创建了新的Hosted Zone

Route 53的界面可以看见新加的Hosted Zone

2. 验证创建好的服务发现是否能正常运行

在创建好带ECS Service Discovery的Cluster之后,已经可以在Route 53的Private Zone上发现有关Service的A记录了。注意这个A记录的格式。service discovery service name.service discovery namespace.

注意Route 53上条目的名称和ECS的Service名称的关系

因为是Private Hosted Zone的测试,所以需要在同一个VPC下面的EC2通过dig命令查看该服务的域名信息。由下图看以发现是可以正常查到的。

现在在该Service下新增一个新的Task,观察Route 53上面是否会同样生成一个新的条目:

等到Task的状态是RUNNING之后,再回去看Route 53的记录,发现又新添了一条

主机上也马上能查到。

至此,我们可以看见通过ECS的服务发现来创建对应的任务(Task)并且自动的通过DNS来获取IP地址是非常方便的。它很好的解决了开篇提出的在云环境下发现服务变化困难的问题。

二、自建ECS Service Discovery Public Hosted Zone

注意:在AWS Console中只能创建Private namespace,如果希望创建Public namespace,即给公网使用的Service Discovery,只能通过CLI。创建的过程注意参考官网文档(虽然官网是Private Zone的,但是参考还是可以的)

https://docs.thinkwithwp.com/AmazonECS/latest/developerguide/service-discovery.html#service-discovery-query

注意:你要把AWS CLI升级到最新的版本

1. 通过以下命令在已有的VPC中创建public namespace

aws servicediscovery create-public-dns-namespace –name Phoenix-Test-Public-Service-Discovery.com

输出:

{
    "OperationId": "kf2rfgf777u4uzjlxloc5d2y7hh4th6t-jfghkvqu"
}

1.1 查看创建public namespace的操作是否完成,如果完成,那么会显示成功,并且在Route 53上会生成一个public的域名

aws servicediscovery get-operation –operation-id kf2rfgf777u4uzjlxloc5d2y7hh4th6t-jfghkvqu

输出:

{
    "Operation": {
        "Id": "kf2rfgf777u4uzjlxloc5d2y7hh4th6t-jfghkvqu",
        "Type": "CREATE_NAMESPACE",
        "Status": "SUCCESS",
        "CreateDate": 1522567839.414,
        "UpdateDate": 1522567840.175,
        "Targets": {
            "NAMESPACE": "ns-t7e7zfqbjoubhvaz"
        }
    }
}

在Route 53的Hosted Zone下面能看见相同的Pulbic Zone出现,注意这个Zone只能由系统的Service Discovery进行修改,无法自己在这个Hosted Zone里面创建任何Record Set(会报没有权限的错误)

2. 创建完毕之后,后面的步骤和创建并使用Private Namespace是一样的。这里就不赘述了。仅把不一样的地方展现出来。一样也要注意要创建Target Group和ALB/NLB。在Private Hosted Zone里面,Enable public DNS health check是不能用的。而在Public Hosted Zone中则可以

3. 测试Public Namespace的工作情况。可以看见在Public Hosted Zone中出现了对应的DNS条目。但是注意,返回的是Task的Private IP的A记录。而非Public IP。

在自己能连上公网的PC机上去dig这个域名,是可以返回任务的私网IP地址的。即其能成功的在公网上发布。

 

姚远

姚远,AWS解决方案架构师,负责基于AWS的云计算方案架构的咨询和设计,同时致力于AWS云服务在国内的应用和推广。现致力于网络和DevOps相关领域的研究。在加入AWS之前,在思科中国担任系统工程师,负责方案咨询和架构设计,在企业私有云和基础网络方面有丰富经验。