Serverless Framework 如何用 serverless dev --sandbox 本地运行 AWS Lambda MicroVM 容器并热重载?
【免费下载链接】serverless⚡ Serverless Framework – Effortlessly build apps that auto-scale, incur zero costs when idle, and require minimal maintenance using AWS Lambda and other managed cloud services.项目地址: https://gitcode.com/GitHub_Trending/se/serverless
任务很直接:你已经用 Serverless Framework v4 的sandboxes配置定义了一个 AWS Lambda MicroVM(容器化工作负载,由Dockerfile构建镜像),希望在部署到 AWS 之前,在本机跑起来一个可以反复迭代的开发循环——改代码、自动重建镜像、新请求用上新镜像,而不是每次改动都走一遍serverless deploy。serverless dev --sandbox <name>就是为这个场景设计的:它从Dockerfile构建镜像,启动一个本地、SDK 兼容的 Lambda MicroVMs 控制平面(control-plane),按需用 Docker 容器启动 MicroVM 实例,流式输出日志,并在文件变化时热重载(来源:sandboxes 指南、dev 命令参考)。
准备条件
dev对 sandbox 的运行环境有明确硬性要求,缺一不可:
- 本机必须有可用的 Docker daemon。镜像按 daemon 的原生 CPU 架构构建,所以 daemon 架构与机器不同时(VM 或远程
DOCKER_HOST)也能工作。 artifact必须是本地目录且包含Dockerfile。路径相对于serverless.yml解析。如果 sandbox 的artifact是s3://zip,dev无法运行——开发循环必须用本地目录。- (可选但建议)sandbox 已经部署过。默认情况下
dev会让容器以该 sandbox 已部署的 execution role 身份运行(见下文 IAM emulation),这要求角色已存在。不部署也能跑,但会回退到本机 AWS 凭据。
最小可运行的serverless.yml(来自指南 Quick Start,sandbox 名echo与后文命令一致):
service: my-sandbox-service frameworkVersion: '4' provider: name: aws region: us-east-1 sandboxes: echo: # sandbox 名称,用于 CloudFormation 逻辑 ID artifact: ./app # 本地目录,需包含 Dockerfile对应的./app/Dockerfile和./app/server.mjs在指南 Quick Start 中有完整示例(node:22-slim基础镜像,HTTP 服务监听 8080 端口),直接照抄即可。
启动本地 dev 会话
在项目根目录执行:
serverless dev --sandbox echo # 只有一个 sandbox 时 --sandbox 可省略 serverless dev --mode sandboxes # 等价写法;服务只含 sandboxes 时可自动检测 serverless dev --sandbox echo --port 9300 # 控制平面端口(默认 9100)三个命令的关系:
--sandbox <name>指定要跑的 sandbox,服务中只定义了一个 sandbox 时可以省略;--mode sandboxes是等价入口,服务里只有 sandboxes 时会被自动检测;--port改的是控制平面端口的本地监听端口(默认9100),不是容器应用端口。
控制平面端点在不同会话之间保持稳定(默认http://127.0.0.1:9100),你代码里指向的地址不用每次改。如果端口被占用,dev会报错退出让你换端口;要同时跑两个 sandbox,给各自的--port即可。
验证 dev 会话已就绪
启动成功后dev会打印控制平面端点(以下为文档示例输出):
Endpoint http://127.0.0.1:9100 ← point your AWS SDK or CLI here e.g. aws … --endpoint-url http://127.0.0.1:9100 MicroVMs API ready — Ctrl-C to stop看到MicroVMs API ready即表示控制平面就绪。接下来可以按生产环境同样的调用序列(RunMicrovm→GetMicrovm→CreateMicrovmAuthToken→ 访问实例端点 →TerminateMicrovm)驱动它——指南给出了针对本地模拟器的完整 CLI 序列(依赖jq解析 JSON):
EP=http://127.0.0.1:9100 RUN=$(aws lambda-microvms run-microvm --endpoint-url $EP --image-identifier local) ID=$(echo "$RUN" | jq -r .microvmId); ENDPOINT=$(echo "$RUN" | jq -r .endpoint) TOK=$(aws lambda-microvms create-microvm-auth-token --endpoint-url $EP \ --microvm-identifier "$ID" --allowed-ports '[{"port":8080}]' --expiration-in-minutes 60 \ --query 'authToken."X-aws-proxy-auth"' --output text) curl -H "X-aws-proxy-auth: $TOK" -H "X-aws-proxy-port: 8080" "$ENDPOINT/hello" aws lambda-microvms terminate-microvm --endpoint-url $EP --microvm-identifier "$ID"本地调用与生产有两个文档明确指出的差异,执行时注意:
- 传
--image-identifier local——模拟器把任意 identifier 映射到当前运行的 sandbox,--execution-role-arn可省略; - 返回的
endpoint是可直接使用的 HTTP URL(如http://127.0.0.1:<port>),原样使用即可,不要像生产那样给裸 HTTPS 主机名加https://前缀。请求头X-aws-proxy-auth和X-aws-proxy-port的生产约定在本地同样生效。
行为层面的判断依据:
- 每次
RunMicrovm都会从当前镜像启动一个全新容器并返回唯一endpoint;TerminateMicrovm停掉它; - 端点强制生产代理契约:缺少
CreateMicrovmAuthToken签发的X-aws-proxy-auth令牌会返回403,按X-aws-proxy-port路由(默认8080); - 空闲生命周期镜像生产:模拟器遵守你传给
RunMicrovm的idlePolicy,空闲实例先docker pause挂起再终止,忘记 terminate 的实例会被自动回收,不会一直挂着; - 容器日志会流式打到本地终端。
热重载如何工作
serverless dev --sandbox <name>会监听 sandbox 的构建上下文目录(即artifact目录——Dockerfile和你的源码)。文件变化时的行为是:
- 镜像自动重建;
- 下一次
RunMicrovm会用新镜像启动新容器——已经在跑的实例继续用它启动时的镜像,不会被替换; - 无需重新执行命令即可持续迭代。
几个边界细节:
- 框架与工具目录被忽略:
.serverless、node_modules、.git、virtualenv/缓存目录、测试文件(*.test.js、*.spec.js、*_test.py、*.test.py)不会触发重建; - 重建失败(如 Docker build 报错)时,运行中的实例继续工作,错误被打印出来,dev 会话保持存活——修好代码再次保存文件即可重试;
Ctrl-C停止会话。
所以热重载的验证方式是:改./app下的源码文件并保存,等重建完成,再发起一次新的RunMicrovm+ 请求,响应应体现新代码的行为;旧实例上的请求不受影响。
IAM emulation:容器以哪个身份运行
默认情况下dev让本地容器以 sandbox 已部署的 execution role 身份运行:通过 STS 假设该角色,把临时凭据注入容器,这样应用发出的 AWS 调用使用与生产相同的权限——真实的AccessDenied会在开发阶段暴露,而不是部署后才出现。相关细节:
- 前提是 sandbox 已部署(角色必须存在才能假设);
- 为了让本地身份可以假设角色,
dev会临时向 execution role 的信任策略添加一条标记为ServerlessSandboxesLocalDevPolicy的 statement,Ctrl-C停止时移除。这要求你的本地身份有iam:GetRole、iam:UpdateAssumeRolePolicy和sts:AssumeRole权限; - 如果角色无法假设(未部署、缺权限等),
dev打印提示并回退到你本机的 ambient AWS 凭据,循环继续可用; - 传
--no-assume-role可跳过整个 emulation,直接用本机凭据运行; - 注意:如果
dev被SIGKILL而非Ctrl-C终止,临时信任 statement 不会被立即移除——下次dev运行时会被清理(或去重复用)。在那之前,你的本地身份仍可以假设该 execution role; - 一个已知例外:直接从实例元数据服务(
169.254.169.254)读凭据的应用会绕过注入的凭据,只有走 AWS SDK 默认凭据链的应用能拿到。
本地模拟不覆盖的范围
文档明确列出了本地 dev 循环与生产的差距,这些项需要部署后另行验证:
- 不复制生产的 proxy/auth 路径与网络出口隔离;
- 模拟器不校验请求签名,不模拟网络隔离与服务配额;
minimumMemory磁盘档位、DISK_STORAGE_FULL这类镜像构建约束是平台侧的,本地 Docker 构建不一定能复现。
本地验证完核心逻辑后,用serverless invoke --sandbox echo对已部署的 sandbox 跑一次性实例,再用serverless logs --sandbox echo查看 CloudWatch 日志组/aws/lambda-microvms/<image-name>中的构建与运行日志,完成与生产路径的交叉核对(两者用法见 sandboxes 指南 的 Invoking a Sandbox 与 Logs 章节)。
【免费下载链接】serverless⚡ Serverless Framework – Effortlessly build apps that auto-scale, incur zero costs when idle, and require minimal maintenance using AWS Lambda and other managed cloud services.项目地址: https://gitcode.com/GitHub_Trending/se/serverless
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考