抖音技术能力大揭密!钜惠大礼、深度体验,尽在火山引擎增长沙龙,就等你来! 立即报名>> 了解详情
写点什么

使用 AWS Lambda 的“层 (Layer) ”功能实现依赖包管理

2019 年 10 月 12 日

使用AWS Lambda 的“层 (Layer) ”功能实现依赖包管理

AWS Lambda 是非常受开发者欢迎的无服务器运行代码的服务,现已原生支持各种主流开发语言,包括 Python/Node.js/Go/Java/Ruby/.NET(PowerShell),还支持自定义运行时,使得运行 C++/Rust/Php/Shell 等都成为可能。


我们在开发 Lambda 应用的时候,通常会有多个 Lambda 函数都共用的代码以及依赖的第三方包。 Lambda 函数要调用这些依赖包,原来的做法是在每个 Lambda 函数打包的时候,连带依赖包一起打包。每个函数都这么做是不方便,也影响速度的。或者可以多个 Lambda 函数连同所有依赖包打包成一个大的包,但这样也不好管理。


现在 AWS Lambda 新增了“层( Layer )” 功能使得可以单独上传并集中管理 Lambda 的依赖包了,这样 Lambda 函数打包的时候就只需要打包该函数本身的代码,依赖包只需要引用即可。这样的好处是显而易见的:


  • 开发者不用再关注依赖包,而可以更专注于业务逻辑的开发

  • 使得函数代码变小了,加快了部署的速度

  • 可以跨 AWS 账户共享代码和依赖包,可以通过 Policy 控制只共享给某个账户,或者共享给所有账户都能分享你的代码成果。

  • 这样多个账户的开发团队共享依赖包也可以轻松实现了。这真让人兴奋!


该功能在全球提供 Lambda 服务的 AWS 区域,包括由西云数据运营的 AWS 中国(宁夏)区域和由光环新网运营 AWS 中国(北京)区域均已支持。以下就以 Python 引用本账户下的共享代码,以及引用另一账户分享的 requests 包两个例子,具体介绍一下层功能的使用方法。


引用本账户的共享代码


1.打包


先把要共享代码保存在本地电脑的 python 目录下,本例文件名为 test2.py ,因为是示例,我们的代码只写了如下一行:


var_from_test2 = 'this is str in test2'
复制代码


然后把该 test2.py 文件 zip 成 share_package.zip ,打 zip 包时文件名可以根据你的习惯来命名,但要注意目录结构, python 的要放在 python 目录下,然后对 python 目录进行 zip 。所以新建一个 python 目录,打包后的目录结构是这样的:


  share_package.zip  python/test2.py
复制代码


Lambda 运行的时候会把依赖包放在运行环境的 /opt 目录下,并依据不同运行环境的下级目录来引用,所以需要严格按照如下图所示的目录结构打包:



2.创建层( Layer )


到 AWS Lambda 控制台的“层”菜单,创建一个新的层



输入层 名称、描述,选择刚才打包的 zip 文件上传,并选择运行时。然后点“创建”



这样层就创建成功了。以后如果要更新,则点“创建版本”进行更新。


注意:


层版本是不可修改的,如果一个版本被删除,或者层版本共享权限被取消了,已经引用了该版本的 Lambda 函数依然是能工作的,但不能再新建 Lambda 函数去引用这个被删除的层版本。



3.创建函数( Function )


到“函数”菜单下创建 Lambda 的主函数 test_main ,上传代码,并配置对应的执行角色(例如 lambda_base_execution )以及其他参数,这时候还没引入依赖包。先写一段简单代码,看看运行结果:


import jsonimport os
def lambda_handler(event, context): os.system('df')
return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!')}
复制代码


保存并测试执行,这时候看到执行了 Linux shell 的 df 命令,列出了 Lambda 运行环境的本地目录,除了根盘,只有一个 512MB 的 /tmp (这是可以供客户写入的临时盘)



4.引入依赖


下面来引入依赖包 test2 ,主函数 test_main 代码变成:


import jsonimport osimport test2
def lambda_handler(event, context): os.system('df') print(test2.var_from_test2) return{ 'statusCode': 200, 'body': json.dumps('Hello from Lambda!')}
复制代码


这里 import 了 test2 并且调用了其中的 var_from_test2 。


然后点 Layers 选项去连接层



添加层,选择刚才创建的层,并选择对应的层版本,然后“连接”



最后记得保存 Lambda 函数。这样就完成了依赖包的配置引用了。


注意:


每个 Lambda 函数最多可以配置 5 个层,函数加上层的总大小不能超过 250 MB ( unzipped size ) 。详见 AWS Lambda Limits https://docs.aws.amazon.com/lambda/latest/dg/limits.html


5.测试


测试执行,我们发现 test2 包的 var_from_test2 已经被主函数所调用。


并且我们看到 Linux shell 执行 df 的结果, Lambda 环境多了一个 /opt 目录,这个就是保存依赖包的目录。



引用其他 AWS 账户的包


1.本地安装 requests 包并上传到另一个 AWS 账户(以下称源账户)


在本地刚才已创建的 python 目录下,安装 requests 包到本目录:


pip install requests -t .
zip -r9 python-requests.zip ../python
复制代码


然后在源账户的 Lambda 控制台,创建层,并上传 python-requests.zip ,层名称定为 requests-layer ,版本为 1。记录下层版本的 ARN ,下面会用到。


2.在源账户设置层共享


使用 AWS CLI 命令行设置层共享权限,如果 CLI 没有 add-layer-version-permission 命令,则请升级 CLI 到最新版本


$ aws lambda add-layer-version-permission --layer-name requests-layer \--statement-id engineering-org --version-number 1 --principal '*' \--action lambda:GetLayerVersion
复制代码


对所有 AWS 账户都分享该包,可以设置 principal 为 ‘*’,如果只针对某个账户分享则设置对应的信任实体。


–principal ‘’ 等同于 –principal ‘arn:aws-cn:iam:::root’ 。把替换为目的账户的号码


–statement-id 是自定义的对该条策略的编号,如要对多个账户分享权限,可以多次下发该 add-layer-version-permission 命令,配置不同的帐号和 statement-id。


用 get-layer-version-policy 命令查询设置的权限策略


$ aws lambda add-layer-version-permission --layer-name requests-layer \--statement-id engineering-org --version-number 1 --principal '*' \--action lambda:GetLayerVersion
复制代码


3.在目的账户设置 Lambda 的 GetLayerVersion 权限


到要调用共享依赖包的那个账户(目的账户)在 IAM 控制台为 Lambda 的执行角色增加一个内联策略,赋 GetLayerVersion 的权限,使得 Lambda 可以获取其他账户的层


 
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "lambda:GetLayerVersion", "Resource": "*" } ]}
复制代码


考虑最小权限原则,在生产环境里 Resource 应该用源帐号层版本的 ARN 来代替 *


4.Lambda 函数连接层


到目的账户的 Lambda 函数菜单,选择对应的函数,并添加层到当前函数。



选择提供层 ARN ,然后粘贴我们刚才在源账户创建的层 ARN 。这样就完成了调用第三方账户共享依赖包的工作了。


5.测试


测试执行, Lambda 已经可以 import requests ,并发起访问。


检查看到 /opt/python 目录已经有了刚才打包的所有依赖。



相关文章:


Lambda 层说明


https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html


Lambda 运行环境和内置的库:


https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html


Lambda 的 IAM Policy


https://docs.aws.amazon.com/lambda/latest/dg/access-control-identity-based.html


IAM Policy 说明


https://docs.aws.amazon.com/AmazonS3/latest/dev/s3-bucket-user-policy-specifying-principal-intro.html


作者介绍:


黄卓斌


亚马逊 AWS 解决方案架构师,负责基于 AWS 的云计算方案架构咨询和设计。拥有 20 年移动互联网、大型企业和电信行业复杂应用系统架构和设计经验。曾任职移动互联网公司 CTO ,受聘为大型国有金融集团技术顾问,曾任职华为、诺基亚等世界 500 强 IT 企业,曾长期驻访美国、印度等从事合作项目开发。


本文转载自 AWS 技术博客。


原文链接:


https://amazonaws-china.com/cn/blogs/china/use-aws-lambda-layer-function/


2019 年 10 月 12 日 17:52564
用户头像

发布了 1286 篇内容, 共 39.4 次阅读, 收获喜欢 42 次。

关注

欲了解 AWS 的更多信息,请访问【AWS 技术专区】

评论

发布
暂无评论
发现更多内容

做产品少走弯路:上帝视角(2)

我是IT民工

产品 方法 路径 知识体系

如何用日记提升写作能力?

石云升

学习 方法 写作

使用 Docker 镜像 | Docker 系列

AlwaysBeta

Docker 容器 虚拟私有云

白话说流——什么是流,从批认识流(二)

KAMI

大数据 flink 流计算

[翻译]The Go Blog《Go maps in action》

卓丁

go golang hashmap map 哈希表

ARTS WEEK3

紫枫

ARTS 打卡计划

原创 | TDD工具集:JUnit、AssertJ和Mockito (二十一)编写测试-动态测试

编程道与术

Java 编程 TDD 单元测试 JUnit

Libra教程之:Libra协议的关键概念

程序那些事

区块链 libra blockchain 协议

食堂就餐卡系统架构设计文档

dony.zhang

小师妹学JavaIO之:NIO中那些奇怪的Buffer

程序那些事

io nio Java 25 周年 小师妹 buffer

拙见/ 什么是自驱力?

ZoomQuiet大妈

自我提升 大妈 是也乎 IMHO 蟒营®

SpringMVC中Http请求方式转换(post转换为put/delete等方式)

知春秋

springmvc post post到put方式请求 post到delete方式请求

由一次管理后台定时推送功能引发的对RabbitMQ延迟队列的思考(一)

LSJ

Java RabbitMQ 延迟队列

算法基础:排序算法看这一篇就够了

公众号:好奇心森林

排序算法

[转载]Go 和 Java的15个主要差异

卓丁

Java golang

JVM学习笔记——JVM类加载机制

王海

Java JVM Java 面试

架构师训练营作业1-食堂就餐卡系统设计

索隆

Kafka零数据丢失的配置方案

奈学教育

kafka

Libra白皮书解读

程序那些事

区块链 facebook 数字货币 libra

游戏夜读 | 如何面对前景渺茫?

game1night

你不能不掌握的软技能——业务语言

KAMI

方法论 开发 沟通 软技能

公司治理的两个关键要素:存在的基石 + 成长的飞轮

霍太稳@极客邦科技

发展 公司管理 增长

3年内从负债到买房三套,勤劳不能致富,工资只能温饱

陆陆通通

创业 程序员 赚钱 买房

LeetCode 756. Pyramid Transition Matrix

liu_liu

LeetCode

读《你的灯还亮着吗》

liu_liu

读书感悟

《Golang工具go doc使用透析》

卓丁

golang godoc go doc golang如何实现接口 源码阅读

B端产品经理养成记(4):敏捷项目

涛哥

敏捷 产品经理

OFD 版式技术解析系列(二):OFD的颜色显示

华宇法律科技

[架构师训练营] Week01 - 食堂就餐卡系统设计

谭方敏

学习

k8s 上运行我们的 springboot 服务之——自动化测试

柠檬

maven DevOps Unit Test

架构师训练营第一周作业

Benjamin

Study Go: From Zero to Hero

Study Go: From Zero to Hero

使用AWS Lambda 的“层 (Layer) ”功能实现依赖包管理-InfoQ