【问题标题】:Connecting AWS ECS Services with the CDK将 AWS ECS 服务与 CDK 连接
【发布时间】:2020-12-24 06:01:05
【问题描述】:

我想将两个容器部署到 ECS 集群中,一个从外部使用 HTTP 调用,然后它调用另一个容器,同样通过 HTTP。

const cluster = new ecs.Cluster(this, "mycluster", {});
cluster.addDefaultCloudMapNamespace({ name: "local" });

new ecsPatterns.ApplicationLoadBalancedFargateService(this, "abc", {
  cluster,
  taskImageOptions: {
    containerPort: 8000,
    image: ecs.ContainerImage.fromRegistry("my/abc-image:latest"),
  },
});

const xyztask = new ecs.FargateTaskDefinition(this, "xyztask");
const xyz = xyztask.addContainer("xyzcontainer", {
  image: ecs.ContainerImage.fromRegistry("my/xyz-image:latest"),
});
xyz.addPortMappings({ containerPort: 8000 });
new ecs.FargateService(this, "xyz", {
  cluster,
  taskDefinition: xyztask,
  cloudMapOptions: { name: "xyz" },
});

abc 服务如下所示:

const axios = require("axios");
const bodyParser = require("body-parser");
const express = require("express");

const app = express();
app.use(bodyParser.json());

app.post("/", async ({ body: { x } }, response) => {
  response.end(JSON.stringify({ x }));
  await axios.post(
    `http://xyz.local:8000/`,
    { x },
    { timeout: 3000 }
  );
});

app.listen(8000);

xyz 服务如下所示:

const axios = require("axios");
const bodyParser = require("body-parser");
const express = require("express");

const app = express();
app.use(bodyParser.json());

app.post("/", async ({ body: { x } }, response) => {
  response.end();
});

app.listen(8000);

abc 服务可从外部获得,但不知何故,对 xyz 的请求总是失败。

【问题讨论】:

  • 您确定要在这里使用 CloudMap 还是尝试实现?我打算尝试旋转类似的东西,但当我看到你在使用 CloudMap 并想检查时我犹豫了。
  • 这是一次尝试。但是 CM 域解析为 IP,所以我觉得部分工作正常,我认为 CM 是这里最干净的方式。

标签: amazon-web-services amazon-ecs aws-cdk


【解决方案1】:

我尝试做出有根据的猜测,因为我在这里看到了两个起点:

a) 该问题与 DNS 解析有关。
您可以通过在与 abc 服务相同的子网中启动 EC2 实例并运行:nslookup xyz.local 来检查是否是这种情况。如果 dns 解析产生 xyz 服务容器的 IP,则 DNS 解析不是问题。

b) xyz 服务的安全组阻止来自 abc 服务的传入呼叫。默认情况下允许传出连接,但通常不允许传入连接(ApplicationLoadBalancedFargateService 构造除外,它默认为来自任何地方的连接打开 ALB 的安全组 [1])。我猜 FargateService 构造默认情况下不会打开任何传入的容器端口,因此您必须手动连接这两个服务:

// initialize both services as before
const abc = new ecsPatterns.ApplicationLoadBalancedFargateService(...)
const xyz = new ecs.FargateService(...);

// add the ingress rule to xyz service for abc service's traffic via TCP port 8000
xyz.connections.allowFrom(abc, Port.tcp(8000));

我还没有尝试过,但这是我想到的两个可能的问题原因。

参考文献

[1]https://github.com/aws/aws-cdk/blob/53f092f8a658e7b72adc996a0d06b18f7ca7ab4d/packages/%40aws-cdk/aws-ecs-patterns/lib/base/application-load-balanced-service-base.ts#L69

【讨论】:

  • 感谢您的回答。我认为,您的第二个假设是正确的,但 ApplicationLoadBalancedFargateService 似乎没有实现 IConnectable 所以缺少 connections 并且 allowFrom 调用失败。
  • 啊,发现solution here必须使用abc.service才能得到实现IConnectableFargateService
  • 另外,它现在工作了。非常感谢。我想,我搜索了几个星期。我什至在 GitHub 上看到了一个带有该解决方案的存储库,但我认为“安全组?不可能!”
猜你喜欢
  • 2021-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-23
  • 1970-01-01
  • 2020-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多