Я хочу развернуть два контейнера в кластере 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 всегда терпит неудачу.
Это была попытка. Но домен CM разрешился в IP, поэтому у меня сложилось впечатление, что часть работает, и я предположил, что CM был самым чистым способом здесь.





Я пытаюсь сделать обоснованное предположение, поскольку вижу здесь две отправные точки:
а) Проблема связана с разрешением DNS.
Вы можете проверить, так ли это, запустив экземпляр EC2 в той же подсети, что и служба abc, и запустив: nslookup xyz.local. Если разрешение DNS дает IP-адрес контейнера (контейнеров) службы xyz, то разрешение DNS не является проблемой.
б) Группа безопасности службы 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));
Я еще не пробовал это, но мне приходят на ум две возможные причины вашей проблемы.
Спасибо за ответ. Я думаю, ваше второе предположение верно, но ApplicationLoadBalancedFargateService, похоже, не реализует IConnectable, поэтому connections отсутствует, а вызов allowFrom завершается ошибкой.
А, нашел решение здесь пришлось использовать abc.service, чтобы получить FargateService, который реализует IConnectable.
Кроме того, это сработало сейчас. Большое спасибо. Я думаю, я искал неделями. Я даже видел репозиторий на GitHub с этим решением, но подумал: «Группы безопасности? Ни за что!»
Вы определенно хотите использовать CloudMap здесь или это была попытка реализации? Я собирался попробовать создать что-то подобное, но колебался, когда увидел, что вы используете CloudMap, и захотел проверить.