用Docker构建AWS Lambda来提供处理图片的微服务

打算用AWS Lambda来做一个图片转视频的python微服务,但是发现相关的库如moviepy/opencv都很大,超过了Lambda 256M的package大小限制。因此,尝试着用Docker来实现这个Lambda,只要不超过500M就可以免费用AWS一年。本文适合希望了解通过Lambda+Docker搭建微服务的朋友。因为有些坑还是花了不少时间解决的,所以短时间内有一定的参考价值。

装Docker

我之前没有用过Docker,所以花了一些时间准备,有类似需要的朋友可以参考(https://blog.csdn.net/yingjil/article/details/130677662)

装AWS CLI

brew install awscli

配置AWS CLI

后面用来连接docker和AWS

jak@jphome TravelVideoAPI % aws configure
AWS Access Key ID [****************WKF4]: 
AWS Secret Access Key [****************KasP]: 
Default region name [us-west-2]: 
Default output format [None]: 

准备AWS ECR

希望用CLI命令行的朋友可以参考官方文档。这里我用UI演示一下。
登录AWS Console,选择ECR
在这里插入图片描述
点击Create repository(注意,不要选Public。我在这里浪费了不少时间。Public没有Private仓库 500M的限制,但是Lambda目前不支持Public。)
在这里插入图片描述
自定义Image的名字(我这个名字有点长了,因为是CDK创建的)。
在这里插入图片描述
选中新创建的Repo,点击View push commands
在这里插入图片描述
本文后面的操作基本就是按照这个顺序,这里的命令已经根据你的账号信息适配,你直接运行即可。
在这里插入图片描述

准备Lambda代码

在这里插入图片描述
更完整的目录结构如下(省去了和本文无关的内容)

jak@jphome TravelVideoAPI % tree
.
├── README.md
├── app.py
├── cdk.json
├── my_lambda
│   ├── Dockerfile
│   ├── lambda_handler.py
│   └── requirements.txt
├── requirements.txt
└── tests
    ├── data
    │   ├── lambda_event_sample.json
    │   └── test_image1.png
    ├── requirements-dev.txt
    └── test_lambda.py

准备docker image

因为是用CDK生成的,image的名字有点长,如果你手动做就可以自定义一个更可读的名字。和docker相关的内容都在my_lambda目录。

cd my_lambda

Dockerfile内容

这里的Key都是假的,帮助理解。把Key写在code里不是好习惯,后面会改进。

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

# 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}"

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

ENV OPENAI_API_KEY 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
ENV DOUYIN_SECRET_ttbaedcc5025d2e24301 c40894832c3158146603501235defba5f80baf
ENV AWS_ACCESS_KEY_ID AKIAU43UQ62MUDWKF4
ENV AWS_SECRET_ACCESS_KEY WcqoLjBdtutydAIOIInJ/mKe7WscNt5JYF3oKasP
ENV AWS_REGION us-west-2

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

授权你的docker cli可以访问你的ECR

aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin 336833330237.dkr.ecr.us-west-2.amazonaws.com

构建你的Image

docker build -t cdk-hnb659fds-container-assets-336833330237-us-west-2 .

踩过的坑

ERROR: failed to solve: public.ecr.aws/lambda/python:3.9: pulling from host public.ecr.aws failed with status code [manifests 3.9]: 403 Forbidden

解决办法是运行以下命令,从而授权docker去访问ecr-public。具体参考这里

aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/lambda

本地测试

本地把Lambda跑起来

docker run -p 9000:8080 cdk-hnb659fds-container-assets-336833330237-us-west-2
调用一下

def test_api_locally():
    # read from test_image1.png from data folder
    with open("data/test_image1.png", 'rb') as f:
        image1_bytes = f.read()

    data = {"body": "{\"text1\":\"一家三口\",\"image1\":\"" + base64.b64encode(image1_bytes).decode('utf-8') + "\"}"}
    res = requests.post(f"http://localhost:9000/2015-03-31/functions/function/invocations", json=data)
    r = json.loads(res.text)

    with open("test_output_locally.mp4", 'wb') as f:
        f.write(base64.b64decode(r['body'].encode('utf-8')))
    assert res.status_code == 200

生成效果mp4。本地测试通过,接下来就要上传AWS了。

这里踩过一个坑

curl -XPOST “http://localhost:9000/2015-03-31/functions/function/invocations” -d ‘{}’

报错

{“errorMessage”: “Unable to import module ‘lambda_handler’: cannot import name ‘DEFAULT_CIPHERS’ from ‘urllib3.util.ssl_’ (/var/task/urllib3/util/ssl_.py)”, “errorType”: “Runtime.ImportModuleError”, “requestId”: “9c9bce02-eb70-45de-b287-43fbb7c388c9”, “stackTrace”: []}%

解决办法在(https://github.com/psf/requests/issues/6443)找到,调整requirements.txt如下

requests < 2.30.0

提交Image到ECR

docker tag cdk-hnb659fds-container-assets-336833330237-us-west-2:latest 336833330237.dkr.ecr.us-west-2.amazonaws.com/cdk-hnb659fds-container-assets-336833330237-us-west-2:latest
docker push 336833330237.dkr.ecr.us-west-2.amazonaws.com/cdk-hnb659fds-container-assets-336833330237-us-west-2:latest

AWS上创建Lambda使用ECR里的Image

TBD

远程测试Lambda

def test_api_remotely():
    # read from test_image1.png from data folder
    with open("data/test_image1.png", 'rb') as f:
        image1_bytes = f.read()

    # data = {"body": "{\"text1\":\"一家三口\",\"image1\":\"" + base64.b64encode(image1_bytes).decode('utf-8') + "\"}"}
    data = {"text1": "一家三口", "image1": base64.b64encode(image1_bytes).decode('utf-8')}
    res = requests.post("https://tterehkxbzlu6thhgac6owrm0kmjha.lambda-url.us-west-2.on.aws/", json=data)

    with open("test_output_remotely.mp4", 'wb') as f:
        f.write(base64.b64decode(res.text.encode('utf-8')))
    assert res.status_code == 200

生成效果mp4

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yingjil

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值