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

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

示例:

Service1:运行任务定义来运行nginx和phpfpm

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

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

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

  1. 我们需要开启服务发现(完成
  2. 设置正确的服务名称和命名空间,作为服务发现端点(完成
  3. 创建任务定义并使用上述属性集创建服务(完成
  4. 现在 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类型有何不同。

标签: amazon-web-services devops amazon-ecs service-discovery


【解决方案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 - 当你接受它作为答案时,它总是很高兴:)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    • 2019-11-12
    • 2020-12-13
    • 2020-03-12
    • 1970-01-01
    • 2018-05-18
    • 1970-01-01
    相关资源
    最近更新 更多