将 AWS ECS 服务与 CDK 连接

Connecting AWS ECS Services with the CDK

我想将两个容器部署到一个 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 的请求总是失败。

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

a) 该问题与 DNS 解析有关。
您可以通过在与 abc 服务和 运行: nslookup xyz.local 相同的子网内启动一个 EC2 实例来检查是否属于这种情况。如果 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