繁体   English   中英

ECS Fargate 任务无法启动:“standard_init_linux.go:228:exec 用户进程导致:exec 格式错误”即使是为 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 用户进程导致:exec 格式错误”

我知道此错误通常是由于 Docker 映像不适用于正确的 CPU 架构或某些格式错误的 shell 脚本,因此已采取措施解决此问题。

我的 Docker 镜像是一个 nodejs express 服务器,我已经在我的 MacOs M1 机器上构建了它。 我已经构建了图像多架构(amd64 和 arm)以及 amd64。

我有一个手动 AWS 控制台在另一个 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)

光盘:

"runtimePlatform": null,

手动的:

"runtimePlatform": {
    "operatingSystemFamily": "LINUX",
    "cpuArchitecture": null
},

还有一些值,CDK 的数组为空,而手动任务 def 中的值为 null。 不确定这是否重要。 示例:手册:“entryPoint”:null,CDK:“entryPoint”:[],

为了完整起见,这是我的图像 Dockerfile:

# --------------> 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 "$1" ]
then
  echo "Please provide all parameters"
  echo "usage: ./docker_deploy.sh <AWS account profile> <AWS region>"
  exit 1
fi

if [ -z "$2" ]
then
  echo "Please provide all parameters"
  echo "usage: ./docker_deploy.sh <AWS account profile> <AWS region>"
  exit 1
fi

PROFILE="$1"
REGION="$2"

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM