我正在尝试在 AWS Elastic Container Service 上部署一个简单的 Node Express 应用程序。我的应用程序非常简单,只有一个名为 app.js 的 js 文件,代码如下。
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => res.send('Hello World!'));
app.get('/health', (req, res) => res.send('OK'));
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
在执行任何操作之前,我创建了两个安全组,一个用于我的 ECS 任务,另一个用于应用程序负载均衡器,因为我将使用负载均衡器来执行我的 ECS 任务。
这是我的 ECS 任务安全组的入站规则配置,
ecs-task-sg
:
这是我的负载均衡器安全组的入站规则配置,称为
ecs-alb-sg
:
然后我构建了我的应用程序 docker 映像并将其推送到 ECR 存储库。这是我的 Dockerfile:
FROM node:16-alpine
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./
RUN npm install
# If you are building your code for production
# RUN npm ci --omit=dev
# Bundle app source
COPY . .
EXPOSE 3000
CMD [ "node", "app.js" ]
我运行以下命令在本地构建了图像:
docker build -f Dockerfile -t noderestapi .
然后我在本地运行该应用程序以检查一切是否按预期工作docker run -d -p 3000:3000 --name noderestapi noderestapi
一切都很好,我可以看到该应用程序正在 localhost:3000 上运行。然后我创建了一个 ECR 存储库来存储我的图像。我还从我的机器向 ECR 进行了身份验证。存储库是私有的,并且启用了标签不变性。
然后我通过运行以下命令来标记图像:
docker tag noderestapi:latest 1234556677.dkr.ecr.eu-west-2.amazonaws.com/noderestapi:v1
然后我将镜像推送到ECR存储库:
docker push 1234556677.dkr.ecr.eu-west-2.amazonaws.com/noderestapi:v1
一切都按预期进行。我可以在 ECR 存储库中看到该图像。
然后我开始配置弹性容器服务来启动我的应用程序。
首先,我按照以下步骤创建了 ECS 任务定义:
环境:
我使用上面屏幕截图中提到的设置创建了任务定义。
之后,我为 Fargate 创建了一个 ECS 集群(在默认 VPC 内)。我只是基本上输入了集群的名称,
noderestapi-cluster
。
然后我按照下面提到的步骤为集群创建了服务。
我点击了“创建”按钮:
然后我选择 Fargate 作为启动类型:
然后在部署配置部分下,我选择了我创建的任务定义:
在“网络”部分下,我选择了为任务创建的安全组,
ecs-task-sg
。
然后在负载均衡器下,我选择创建一个新的应用程序负载均衡器:
然后我创建了该服务。几分钟后,服务已完全创建。
服务创建后,我去负载均衡器更正我的负载均衡器的安全组。它被分配了 ECS 任务的安全组。因此,我分配了之前为负载均衡器创建的正确值,
ecs-alb-sg
。然后我打开负载均衡器的DNS,收到503错误。然后我检查了我的 ECS 集群,我可以看到服务正在努力启动任务。
我的配置有什么问题以及如何修复它?
也在 CloudWatch 中,我收到此错误。
exec /usr/local/bin/docker-entrypoint.sh: exec format error
您在负载均衡器设置中选择的容器是
noderestapi 80:80
。这看起来不正确。上面应该写着端口 3000
,而不是端口 80
。
此外,您显示的用于创建容器的屏幕截图的名称为
nodeapi
,而不是 noderestapi
。
看起来您创建了另一个配置为使用端口
80
而不是 3000
的容器或任务定义。但是,如果不更改 docker 映像中的设置,那将永远无法工作。
我建议将任务定义端口编辑为
3000
,并编辑目标组以将流量端口和健康检查端口更改为3000
,以匹配容器实际侦听的端口。只有负载均衡器侦听器应该使用端口 80
其他所有内容(任务定义、目标组等)都应反映容器正在侦听的实际端口。
检查安全组入站规则添加3000端口