无法使 AWS ECS 服务通过服务发现进行通信

Posted

技术标签:

【中文标题】无法使 AWS ECS 服务通过服务发现进行通信【英文标题】:Not able to make AWS ECS services communicate over service discovery 【发布时间】:2019-11-15 18:35:53 【问题描述】:

我正在尝试让 2 个服务通过 AWS ECS 服务中的服务发现端点进行通信。

示例:

Service1:运行任务定义来运行nginxphpfpm

Service2:运行任务定义来运行redis

现在,我需要让 service1 容器与 service2 通信 容器

根据互联网上的文档和资源。这就是我所做的,无法实现需求。

    我们需要开启服务发现(完成) 设置正确的服务名称和命名空间,作为服务发现端点(完成) 创建任务定义并使用上述属性集创建服务(完成) 现在 AWS 将在 Route53 上生成一条 SRV 记录(OK

现在,当使用服务发现端点时,通常采用格式 service_discovery_service_name.service_discovery_namespace.

错误日志显示,无法解析名称。

【问题讨论】:

您需要在为每个服务任务分配 IP 的 Route53 中创建 DNS Type A 记录而不是 SRV。只有当您的通信支持 SRV 记录查找时,您才需要 SRV 记录,即客户端需要知道它需要执行 SRV 查找然后获取 IP。 @Imran 是的,但是 aws ECS 具有该功能的内置权利,并且也生成了 A 记录,该记录又指向实例的 IP 地址 您在任务定义中使用了哪种 docker 网络模式?如果您不使用awspvc,那么它将仅创建SRV 类型,然后指向A 类型。当您执行nslookup myapp.local 时,您将不会得到任何东西,因为它的类型是SRV 而不是A。当您尝试nslookup -type=srv myapp.local 时,您将获得 SRV 列表,然后您可以尝试 nslookup taskid.myapp.local 提供容器的 IP。除非您的客户端支持执行 SRV 查找然后执行 IP 查找,否则您最好只创建 A 记录。如果您需要示例,请告诉我,将其作为答案发布。 我的任务定义网络模式是桥接,它创建的 SRV 具有 taskid 和指向容器 ip 的 A 记录。请检查在编辑问题部分上传的图片@Imran 这就是我要说的!您的客户端(Service1)需要知道它需要对 Service2 执行SRV 查找,然后使用 SRV 结果(端口和主机名)的详细信息进行通信。例如 - 如果您的 Service1 是 nginx,那么 premium 是 nginx supports 的版本。如果您的 Service1 是 phpfpm,我不确定它是否支持 SRV 查找通信。首先understandSRV记录与A类型有何不同。 【参考方案1】:

我想详细说明@Imran 的详细答案,因为大多数答案都讨论了SRV DNS 记录类型,并且仅针对高级版本的 Nginx(和SRV)显示 Nginx 示例。

如果您使用 ECS Fargate 并配置了 A DNS 记录。最重要的是配置一个合适的resolver

来自文档:

配置名称服务器,用于将上游服务器的名称解析为 地址,例如:

解析器 127.0.0.1 [::1]:5353;

地址可以指定为 域名或 IP 地址,带有可选端口。如果端口不是 指定,则使用端口 53。名称服务器在 循环时装。

话虽如此,解析器必须解析私有 DNS。因此,我们需要使用NS DNS 记录。 使用 8.8.8.8 作为解析器将不起作用,因为此 DNS 无法解析私有 DNS。

NS 代表“名称服务器”,此记录指示哪个 DNS 服务器 对该域具有权威性(哪个服务器包含实际的 DNS 记录)。一个域通常会有多个 NS 记录,它们可以 指明该域的主要和备用名称服务器。

为了获得 DNS 解析器,请运行以下命令:

aws route53 list-resource-record-sets --hosted-zone-id %HOSTED_ZONE_ID% --query "ResourceRecordSets[?Type == 'NS']"

选择其中一条资源记录并将其放入 Nginx resolver(包括尾随的.)。

Nginx 基本模板:

events 
  worker_connections 768;


http 
  # DNS Resolver
  resolver ns-###.awsdns-####.com. valid=10s;
  gzip on;
  gzip_proxied any;
  gzip_types text/plain application/json;
  gzip_min_length 1000;
  fastcgi_buffers 16 16k; 
  fastcgi_buffer_size 32k;

  server 

    listen 80;
    
    location / 
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header Host $host;
          proxy_redirect   off;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          # This is the important part
          proxy_pass http://ecs-fargate-svc.local:8080;
    

    location = /health-check 
      return 200 'all good';
    

  

需要考虑的几点:

不要忘记添加映射端口(在我的示例中为 8080)。 确保安全组允许 VPC 内的流量。 由于使用 Fargate 并且我们的日志有限,请考虑在 ECS Fargate 任务所在的 VPC 中创建一个 EC2 实例,并尝试 curl\ping URL\DNS 记录。

我的服务发现:

文档:

Nginx resolver

The name server (NS) record

【讨论】:

【参考方案2】:

根据我们的谈话,这里是正在发生的事情的一些摘要。

如果 Service1(在您的情况下为nginx)需要使用 AWS ServiceDiscovery 选项与 Service2(redis) 交互并使用 SRV 记录,则 Service1 需要注意它需要执行 DNS SRV 查找而不是 DNS A(Address) 查找。

您有多种选择。首先,如果您想继续使用SRV 记录,那么您的客户端nginx 需要代理redis 上游服务器,其中serviceresolve 选项为available,仅在premium 版本的nginx 中.检查我在答案底部测试过的示例 nginx 配置。

1234563

其他选项,如果您不想依赖SRV 记录而是转至标准A 记录查找,那么您将不得不对容器使用awsvpc 模式并选择A 选项。

使用 DNS A 选项,您对 service_discovery_service_name.service_discovery_namespace 的查询将正常工作。 使用 DNS A 选项,有一些限制。由于 ENI 的数量限制取决于 EC2 实例系列,因此您无法在同一 EC2 实例上为给定服务创建多个任务,因此我只希望 SRV 记录。

示例 nginx DNS SRV 选项配置:

stream 
    resolver 172.31.0.2;
    upstream redis 
        zone tcp_servers 64k;
        server redisservice.local service=_http._tcp resolve;
    
    server 
        listen 12345;
        status_zone tcp_server;
        proxy_pass redis;
    

一些参考资料-

https://aws.amazon.com/blogs/aws/amazon-ecs-service-discovery/ https://docs.aws.amazon.com/AmazonECS/latest/developerguide/create-service-discovery.html

【讨论】:

如果不使用 nginx-plus。我想我可以使用前端服务发现(弹性负载均衡器)来解决这个问题。 @Imran @TaraPrasadGurung 我上面提到的另一个选项也没有使用 nginx-plus,但它有一些注意事项。是的。如果体积不是那么高,那么 ELB 是不错的选择,而不是 nginx-plus。 PS - 当你接受它作为答案时,它总是很高兴:)。

以上是关于无法使 AWS ECS 服务通过服务发现进行通信的主要内容,如果未能解决你的问题,请参考以下文章

AWS S3 Angular 应用程序通过 Route 53 地址调用 ECS 任务

基于AWS的云监控解决方案

如何根据多个警报扩展 aws ecs 服务

AWS 使用 Fargate 对 ECS 服务的多个端口进行负载平衡

ECS 服务的 AWS 网络负载均衡器运行状况检查失败

关于阿里云ecs服务器无法用FTP进行连接问题