ECS Fargate 任务无法启动:"standard_init_linux.go:228: exec user process caused: exec format error" 即使是为 amd64 构建的
ECS Fargate task failing to start: "standard_init_linux.go:228: exec user process caused: exec format error" even when built for amd64
我的带有 Fargate 任务的 CDK 堆栈无法启动,任务直接停止并出现错误:
"standard_init_linux.go:228: exec user process caused: exec format
error"
我知道这个错误通常是由于 Docker 图像不适合正确的 CPU 架构或一些格式错误的 shell 脚本,因此已采取措施解决这个问题。
我的 Docker 图像是一个 nodejs express 服务器,我在我的 MacOs M1 机器上构建了它。 我已经构建了镜像多架构(amd64 和 arm)以及 amd64。
我在另一个 AWS 账户中的 ALB 后面有一个手动创建的 Fargare 服务,它模拟了我试图用 CDK 做的事情。 我在另一个 AWS 账户 ECS 存储库中有相同的 Docker 图像,我的任务在那里工作。
因此我得出结论,它不是 Docker 图像本身,而是任务定义的东西。
有什么问题吗?
这是我的 CDK 堆栈:
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as ecr from 'aws-cdk-lib/aws-ecr';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ecsp from 'aws-cdk-lib/aws-ecs-patterns';
export class HelloEcsStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const serviceName = 'my-backend';
const servicePort = 5432;
const vpc = new ec2.Vpc(this, "MyVpc", {
maxAzs: 2
});
const cluster = new ecs.Cluster(this, "BackendCluster", {
vpc: vpc
});
const load_balanced_fargate_service = new ecsp.ApplicationLoadBalancedFargateService(this, 'Backend', {
cluster: cluster,
taskImageOptions: {
image: ecs.ContainerImage.fromEcrRepository(
ecr.Repository.fromRepositoryName(this, id, 'backend-container-repo')
),
containerPort: servicePort,
environment: {
// some key values our backend needs
}
},
listenerPort: servicePort,
publicLoadBalancer: true
});
load_balanced_fargate_service.targetGroup.configureHealthCheck({
port: `${servicePort}`,
path: '/api/health'
});
}
}
手册中我的任务定义 JSON 与 CDK 变体之间的唯一区别是:
手动:任务内存和CPU更大(2048/1024)
CDK:
"runtimePlatform": null,
手动:
"runtimePlatform": {
"operatingSystemFamily": "LINUX",
"cpuArchitecture": null
},
也有一些值CDK中的数组为空,而手动任务def中的值为null。不确定这是否重要。例子:
手册:“入口点”:空,
CDK:“入口点”:[],
为了完整起见,这是我的 Docker图像文件:
# --------------> The build image
FROM node:latest AS build
WORKDIR /usr/src/app
COPY package*.json /usr/src/app/
RUN npm ci --only=production
# --------------> The production image
FROM node:lts-alpine
RUN apk add dumb-init
ENV NODE_ENV production
USER node
WORKDIR /usr/src/app
COPY --chown=node:node --from=build /usr/src/app/node_modules /usr/src/app/node_modules
COPY --chown=node:node . /usr/src/app
# Setup backend port (default can be overridden by --build-arg PORT <port value>)
ARG PORT=5432
ENV PORT=$PORT
EXPOSE $PORT
RUN echo
CMD ["dumb-init", "node", "server.js"]
毕竟是图片
我的问题是我首先在本地构建了一个图像,但在部署时我使用了 shell 脚本。该脚本没有正确标记图像,因此实际推送的图像是旧图像(架构错误)。通过在本地清除我的 docker 图像和容器发现了这一点,并且在构建 运行 脚本时出现错误。
更正后的构建和部署脚本现在如下所示:
#!/bin/bash
if [ -z "" ]
then
echo "Please provide all parameters"
echo "usage: ./docker_deploy.sh <AWS account profile> <AWS region>"
exit 1
fi
if [ -z "" ]
then
echo "Please provide all parameters"
echo "usage: ./docker_deploy.sh <AWS account profile> <AWS region>"
exit 1
fi
PROFILE=""
REGION=""
export AWS_PROFILE=$PROFILE
export AWS_REGION=$REGION
REPO_NAME=your-repo
if aws ecr describe-repositories --repository-names ${REPO_NAME} >/dev/null ; then
echo "ECR repository exists"
else
echo "ECR repository doest not exist, creating..."
aws ecr create-repository --repository-name ${REPO_NAME} >/dev/null
fi
REPO_URI=`aws ecr describe-repositories --repository-names ${REPO_NAME} | jq -r '.repositories[].repositoryUri | match( "([^/]*)" ).string'`
set -e # fail script on any individual command failing
aws ecr get-login-password --profile ${PROFILE} --region ${REGION} | docker login --username AWS --password-stdin ${REPO_URI}
docker build --platform=linux/amd64 -t ${REPO_NAME} .
docker tag ${REPO_NAME}:latest ${REPO_URI}/${REPO_NAME}:latest
docker push ${REPO_URI}/${REPO_NAME}:latest
我的带有 Fargate 任务的 CDK 堆栈无法启动,任务直接停止并出现错误:
"standard_init_linux.go:228: exec user process caused: exec format error"
我知道这个错误通常是由于 Docker 图像不适合正确的 CPU 架构或一些格式错误的 shell 脚本,因此已采取措施解决这个问题。
我的 Docker 图像是一个 nodejs express 服务器,我在我的 MacOs M1 机器上构建了它。 我已经构建了镜像多架构(amd64 和 arm)以及 amd64。
我在另一个 AWS 账户中的 ALB 后面有一个手动创建的 Fargare 服务,它模拟了我试图用 CDK 做的事情。 我在另一个 AWS 账户 ECS 存储库中有相同的 Docker 图像,我的任务在那里工作。
因此我得出结论,它不是 Docker 图像本身,而是任务定义的东西。
有什么问题吗?
这是我的 CDK 堆栈:
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as ecr from 'aws-cdk-lib/aws-ecr';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ecsp from 'aws-cdk-lib/aws-ecs-patterns';
export class HelloEcsStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const serviceName = 'my-backend';
const servicePort = 5432;
const vpc = new ec2.Vpc(this, "MyVpc", {
maxAzs: 2
});
const cluster = new ecs.Cluster(this, "BackendCluster", {
vpc: vpc
});
const load_balanced_fargate_service = new ecsp.ApplicationLoadBalancedFargateService(this, 'Backend', {
cluster: cluster,
taskImageOptions: {
image: ecs.ContainerImage.fromEcrRepository(
ecr.Repository.fromRepositoryName(this, id, 'backend-container-repo')
),
containerPort: servicePort,
environment: {
// some key values our backend needs
}
},
listenerPort: servicePort,
publicLoadBalancer: true
});
load_balanced_fargate_service.targetGroup.configureHealthCheck({
port: `${servicePort}`,
path: '/api/health'
});
}
}
手册中我的任务定义 JSON 与 CDK 变体之间的唯一区别是:
手动:任务内存和CPU更大(2048/1024)
CDK:
"runtimePlatform": null,
手动:
"runtimePlatform": {
"operatingSystemFamily": "LINUX",
"cpuArchitecture": null
},
也有一些值CDK中的数组为空,而手动任务def中的值为null。不确定这是否重要。例子: 手册:“入口点”:空, CDK:“入口点”:[],
为了完整起见,这是我的 Docker图像文件:
# --------------> The build image
FROM node:latest AS build
WORKDIR /usr/src/app
COPY package*.json /usr/src/app/
RUN npm ci --only=production
# --------------> The production image
FROM node:lts-alpine
RUN apk add dumb-init
ENV NODE_ENV production
USER node
WORKDIR /usr/src/app
COPY --chown=node:node --from=build /usr/src/app/node_modules /usr/src/app/node_modules
COPY --chown=node:node . /usr/src/app
# Setup backend port (default can be overridden by --build-arg PORT <port value>)
ARG PORT=5432
ENV PORT=$PORT
EXPOSE $PORT
RUN echo
CMD ["dumb-init", "node", "server.js"]
毕竟是图片
我的问题是我首先在本地构建了一个图像,但在部署时我使用了 shell 脚本。该脚本没有正确标记图像,因此实际推送的图像是旧图像(架构错误)。通过在本地清除我的 docker 图像和容器发现了这一点,并且在构建 运行 脚本时出现错误。
更正后的构建和部署脚本现在如下所示:
#!/bin/bash
if [ -z "" ]
then
echo "Please provide all parameters"
echo "usage: ./docker_deploy.sh <AWS account profile> <AWS region>"
exit 1
fi
if [ -z "" ]
then
echo "Please provide all parameters"
echo "usage: ./docker_deploy.sh <AWS account profile> <AWS region>"
exit 1
fi
PROFILE=""
REGION=""
export AWS_PROFILE=$PROFILE
export AWS_REGION=$REGION
REPO_NAME=your-repo
if aws ecr describe-repositories --repository-names ${REPO_NAME} >/dev/null ; then
echo "ECR repository exists"
else
echo "ECR repository doest not exist, creating..."
aws ecr create-repository --repository-name ${REPO_NAME} >/dev/null
fi
REPO_URI=`aws ecr describe-repositories --repository-names ${REPO_NAME} | jq -r '.repositories[].repositoryUri | match( "([^/]*)" ).string'`
set -e # fail script on any individual command failing
aws ecr get-login-password --profile ${PROFILE} --region ${REGION} | docker login --username AWS --password-stdin ${REPO_URI}
docker build --platform=linux/amd64 -t ${REPO_NAME} .
docker tag ${REPO_NAME}:latest ${REPO_URI}/${REPO_NAME}:latest
docker push ${REPO_URI}/${REPO_NAME}:latest