簡體   English   中英

AWS Lambda Alpine Python Container 顯示 IMAGE Launch 錯誤 exec 格式錯誤

[英]AWS Lambda Alpine Python Container shows IMAGE Launch error exec format error

我正在編寫一個 Lambda 函數來使用 unoconv 和 libreoffice 將 excel 文件轉換為 PDF,為此我使用的是 alpine 基礎圖像。 Dockerfile 如下。

# Define global args
ARG FUNCTION_DIR="/home/app/"
ARG RUNTIME_VERSION="3.9"
ARG DISTRO_VERSION="3.12"

# Stage 1 - bundle base image + runtime
# Grab a fresh copy of the image and install GCC
FROM python:${RUNTIME_VERSION}-alpine${DISTRO_VERSION} AS python-alpine
# Install GCC (Alpine uses musl but we compile and link dependencies with GCC)
RUN apk add --no-cache \
    libstdc++

# Stage 2 - build function and dependencies
FROM python-alpine AS build-image
# Install aws-lambda-cpp build dependencies
RUN apk add --no-cache \
    build-base \
    libtool \
    autoconf \
    automake \
    libexecinfo-dev \
    make \
    cmake \
    libcurl
# Include global args in this stage of the build
ARG FUNCTION_DIR
ARG RUNTIME_VERSION
# Create function directory
RUN mkdir -p ${FUNCTION_DIR}
# Copy handler function
COPY app.py ${FUNCTION_DIR}
COPY requirements.txt ${FUNCTION_DIR}
# Optional – Install the function's dependencies
RUN python${RUNTIME_VERSION} -m pip install -r /home/app/requirements.txt --target ${FUNCTION_DIR}
# Install Lambda Runtime Interface Client for Python
RUN python${RUNTIME_VERSION} -m pip install awslambdaric --target ${FUNCTION_DIR}

# Stage 3 - final runtime image
# Grab a fresh copy of the Python image
FROM python-alpine
# Include global arg in this stage of the build
ARG FUNCTION_DIR
# Set working directory to function root directory
WORKDIR ${FUNCTION_DIR}
# Copy in the built dependencies
COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}

#
ARG PUID=1000
ARG PGID=1000
#
RUN set -xe \
    && apk add --no-cache --purge -uU \
        curl icu-libs unzip zlib-dev musl \
        mesa-gl mesa-dri-swrast \
        libreoffice libreoffice-base libreoffice-lang-uk \
        ttf-freefont ttf-opensans ttf-ubuntu-font-family ttf-inconsolata \
    ttf-liberation ttf-dejavu \
        libstdc++ dbus-x11 \
    && echo "http://dl-cdn.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories \
    && echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories \
    && echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \
    && apk add --no-cache -U \
    ttf-font-awesome ttf-mononoki ttf-hack \
    && rm -rf /var/cache/apk/* /tmp/*

RUN pip install unoconv

# (Optional) Add Lambda Runtime Interface Emulator and use a script in the ENTRYPOINT for simpler local runs
ADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/bin/aws-lambda-rie
COPY entry.sh /
RUN chmod 755 /usr/bin/aws-lambda-rie /entry.sh
ENTRYPOINT [ "/entry.sh" ]
CMD [ "app.handler" ]

entry.sh 文件內容如下。

#!/bin/sh
if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
    exec /usr/bin/aws-lambda-rie /usr/local/bin/python -m awslambdaric $1
else
    exec /usr/local/bin/python -m awslambdaric $1
fi

requirements.txt 文件內容如下。

unotools
unoconv
boto3

app.py 文件內容如下。

import sys
import boto3
import subprocess
import json

def handler(event, context):       
    bucketname = "somebucket"
    filename = "Sample/example.xlsx"
    outputfilename = filename.rsplit('.', 1)[0] + '.pdf'

    s3 = boto3.client('s3')

    try:
        s3.download_file(bucketname, filename, "file.xlsx")
    except Exception as e:
        return str(e)

    try:
        result = subprocess.run(['unoconv', '-f', 'pdf', "file.xlsx"], stdout=subprocess.PIPE)
    except Exception as e:
        return str(e)

    try:
        with open("file.pdf", "rb") as f:
            s3.upload_fileobj(f, bucketname, outputfilename)
    except Exception as e:
        return str(e)

    body = {
        "message": "Converted excel to pdf"        
    }
    response = {
        "statusCode": 200,
        "event": json.dumps(event),
        "body": json.dumps(body),
        "path": "app.py"
    }
    return response

我構建了這個容器並在本地運行容器,這沒有問題。 但是,當我將圖像推送到 ECR 並使用新的最新圖像更新功能並運行測試時,它會顯示此錯誤。

{
  "errorMessage": "RequestId: SOME_ID_HERE Error: fork/exec /usr/local/bin/python awslambdaric: no such file or directory",
  "errorType": "Runtime.InvalidEntrypoint"
}
IMAGE   Launch error: fork/exec /usr/local/bin/python awslambdaric: no such file or directory   Entrypoint: [/usr/local/bin/python awslambdaric]    Cmd: [app.handler]  WorkingDir: [/home/app/]

查看錯誤,我認為這與架構有關。 有人可以幫助我了解導致問題的原因嗎?

問題是架構,我在 Mac Mini M1 上構建我的圖像。 當我通過提供 --platform=linux/amd64 選項構建映像時,錯誤消失了。 當然,Lambda 函數中唯一可寫的文件夾是 /tmp 因此,我也必須更改它才能正常工作。

我在 M1 Pro 上遇到了同樣的問題,不得不使用docker buildx來解決這個問題。

docker buildx build --platform linux/amd64 -f ./Dockerfile -t myDockerTag .

萬分感謝! 這些答案確實為我指明了正確的方向。

由於 M1 使用 ARM64,另一種選擇是讓它默認構建 arm64 並讓 lambda 函數我們該架構

docker build myDockerTag:latest .

然后在使用 Lambda CLI 時

aws lambda create-function --region <region_name> --architecture arm64 --function-name <function_name> --package-type Image --code ImageUri=<ECR Image URI> --role <iam_role_url>

對於訪問此內容的任何人,問題還可能是由於該映像是在與 AWS 上指定的 CPU 架構不同的 CPU 架構上構建的。 例如,如果您在 M1 上構建了映像,則必須在 lambda 映像對話框中選擇arm64選項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM