「以译代学」创建 Lambda container images

原文🔗:https://docs.aws.amazon.com/lambda/latest/dg/images-create.html

AWS 提供了一系列的开源基础的 base images,让我们来创建自己的容器 image。这些基础的 images 里包括了一个 实时客户端( runtime interface client )来管理 Lambda 和你的函数代码的交互。

比如这个网址有包括一个 Node.js 和一个 Python 的例子: Container image support for Lambda

主题:

Prerequisites

先决条件

要在 Lambda 上部署一个 container image, 你需要 AWS CLI 和 Docker CLI( AWS CLI and Docker CLI)。额外的,请注意以下条件:

  • container image 必须要集成了 Lambda 的 Runtime API。AWS 里开源的 实时接口有集成,所以你可以添加一个这个事实交互客户端到你更接近的 basic image 中去让它支持 Lambda。
  • container image 需要能够在 只读文件系统(read-only file system)中运行。你的函数代码能够获取到一个可写的 /tmp 目录,大概 512 MB 到 10,240 MB之间,按 1MB递增的存储空间。(并不是很理解,意思是空间留大一点?)
  • 权限问题:默认的 Lambda用户必须能够读所有需要的文件去运行你的函数代码。Lambda 采用了安全性的最佳实践,即定义了一个有着最小 权限的(least-privileged permissions)默认的 Linux 用户。所以你要确认一下你的应用代码不需要依赖一些其他 Linux 用户无法访问的文件去运行。
  • Lambda 支持 只有 Linux-based 的 container images。
  • Lambda 提供 多架构的 基础 images。但是你为你的函数构建的 image 必须指定其中一种。Lambda 不支持用了多架构的container images。(意思是支持多种,但具体到一个上不能跨架构。)

Image types

镜像类型

你可以用一个 AWS 提供好的 基础镜像模版之类的来创建,比如 Alpine 或 Debian。Lambda 支持满足一下两个 image 显示格式的任意 image:

  • Docker image manifest V2, schema 2 (used with Docker version 1.10 and newer)
  • Open Container Initiative (OCI) Specifications (v1.0.0 and up)

Container tools

容器工具

为了创建 container image,你需要用任意一个开发工具支持上面的显示格式。

比如你可以用 Docker CLI 来构建、测试和部署你的容器images。

Container image settings

容器镜像设置

Lambda 支持在 Dockerfile 中设置:

  • ENTRYPOINT – Specifies the absolute path to the entry point of the application. ——进入点,明确进入应用的绝对路径
  • CMD – Specifies parameters that you want to pass in with ENTRYPOINT. ——明确你要和进入点一起传的参数
  • WORKDIR – Specifies the absolute path to the working directory. —— 明确工作目录的绝对路径
  • ENV – Specifies an environment variable for the Lambda function. ——明确 Lambda 函数的环境变量

参考链接:ENTRYPOINT、 Demystifying ENTRYPOINT and CMD in Docker

你可以在 Dockerfile 中就明确这些设置,也可以用 Lambda 终端或 Lambda API 来重写覆盖掉这些配置。这让你能够部署同一个容器镜像里的多个函数,用不同的运行配置(runtime configurations)。

Creating images from AWS base images

从 AWS base images 创建 images

为了一个新的 Lambda函数建 container image 的时候,你可以从 AWS base image for Lambda 开始。Lambda 提供了两种类型的基础镜像:

  • Multi-architecture base imageSpecify one of the main image tags (such as python:3.9 or java:11) to choose this type of image.
  • Architecture-specific base imageSpecify an image tag with an architecture suffix. For example, specify 3.9-arm64 to choose the arm64 base image for Python 3.9.

(我感觉课程上用第二种就可以了。)

也可以从其他的容器注册处(alternative base image from another container registry)使用替代的 base image。加入前面说过的 开源运行交互客户端就可以了。

Note:

AWS 阶段性的提供更新,如果你的 Dockerfile 在 FROM 属性下包括了 image 名字,你的 Docker客户端会从 Amazon ECR 仓库里拉取最新版本的 image。为了用最新的 base image,你必须重构你的容器镜像,并更新函数代码(update the function code)。

具体步骤:

  1. 在本地机器,为你的新函数(new func)创建一个项目目录(project directory)。
  2. 在 project directory 下创建一个叫 app 的目录,然后把 function handler code 添加到 app 目录下。
  3. 用 文本编辑器创建一个新的 Dockerfile。 AWS 提供两个环境变量:
    • LAMBDA_TASK_ROOT=/var/task
    • LAMBDA_RUNTIME_DIR=/var/runtime

在 ${LAMBDA_TASK_ROOT}  目录下安装依赖。它和 handler 是平级的,以保证运行的时候可以定位到。

下面是 Dockerfile 的例子:

FROM public.ecr.aws/lambda/python:3.8 

# Copy function code COPY app.py ${LAMBDA_TASK_ROOT} 

# Install the function's dependencies using file requirements.txt 
# from your project folder. COPY requirements.txt . RUN pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}" 


# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "app.handler" ] 

4. 用 docker build 命令创建 image,跟着一个名字,比如创还能了一个叫 hello-world 的镜像:

docker build -t hello-world .

5. 用 run 来开启 Docker 镜像,接上例:

docker run -p 9000:8000 hello-world 

6. (可选)用 runtime interface emulator 测试一下你的应用。打开另一个新的终端窗口,用 curl 提交一个事件给下来的 endpoint:

curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'

这个命令会调 container image 里的函数,并返回响应。

Creating images from alternative base images

前提:AWS CLI + Docker Desktop + function code

步骤和上面的很像。前面多了一步找一个 base image,如 Alpine, Debian和 Ubuntu。

然后创项目目录,创 app目录,加 handler 代码。

不一样的地方来了,Dockerfile 有所不同:

  1. FROM 属性 , 设置成 base image 的 URI。
  2. 添加命令安装 runtime interface client。
  3. ENTRYPOINT 来调用 runtime interface client。
  4. CMD 明确 Lambda function handler, 和上面的一样。

例子:

# Define function directory
ARG FUNCTION_DIR="/function"

FROM python:buster as build-image

# Install aws-lambda-cpp build dependencies
RUN apt-get update && \
  apt-get install -y \
  g++ \
  make \
  cmake \
  unzip \
  libcurl4-openssl-dev

# Include global arg in this stage of the build
ARG FUNCTION_DIR
# Create function directory
RUN mkdir -p ${FUNCTION_DIR}

# Copy function code
COPY app/* ${FUNCTION_DIR}

# Install the runtime interface client
RUN pip install \
        --target ${FUNCTION_DIR} \
        awslambdaric

# Multi-stage build: grab a fresh copy of the base image
FROM python:buster

# 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 build image dependencies
COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}

ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric" ]
CMD [ "app.handler" ]

5. 一样的命令 build 就好了。

Upload the image to the Amazon ECR repository

把 image 上传到 亚马逊的 ECR 仓库

在 Amazon ECR,如果你重新把 image tag 给了另一个 image,Lambda不会更新版本的。

123456789012 要替换成你自己的 AWS 账户ID,设置 region value 到你想创建的 region。(那设置时区会影响另一个时区的人使用吗?今天看的 FSDL 的 Lec 09 讲到不同的时区会有不同的 CO2 排放量,哇,神奇的角度)

  1. 将 Docker CLI 验证注册到 Amazon ECR registry:
    • aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com
  2. create-repository 命令在 Amazon ECR 创建仓库:
    • aws ecr create-repository --repository-name hello-world --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE

3. 标记 image 和你的仓库匹配,然后用 docker push 命令部署到 Amazon ECR:

docker tag hello-world:latest 123456789012.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest

docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest

你的容器镜像已经在 Amazon ECR 容器注册过了,你就可以  create and run Lambda函数了! Finally!

最后又提供了一个 AWS Serverless Application Model (AWS SAM) 工具箱来创建。用 AWS SAM CLI init 命令来设置项目的脚手架。

在 AWS SAM 模版中,设置 Runtime type 到 Image,提供 base image 的 URI 就可以了。

更多请看:Building applications (AWS Serverless Application Model Developer Guide.)


了解 小匚的个人博客 的更多信息

订阅后即可通过电子邮件收到最新文章。

了解 小匚的个人博客 的更多信息

立即订阅以继续阅读并访问完整档案。

继续阅读

了解 小匚的个人博客 的更多信息

立即订阅以继续阅读并访问完整档案。

继续阅读

退出移动版