
Serverless Framework Sandboxes 故障排查实战指南AWS Lambda MicroVMs 部署与运行时疑难问题定位【免费下载链接】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/serverlessServerless Framework 的sandboxes特性底层为 AWS Lambda MicroVMs / Firecracker 微虚拟机将镜像构建与实例运行拆成了两个生命周期这决定了它的大部分故障要么发生在部署期的镜像构建阶段要么发生在运行期的实例生命周期与数据面代理上。本文以官方排障指南skills/serverless-sandboxes/references/troubleshooting.md为核心骨架结合platform.md平台契约、config.md配置面、commands.mdCLI 面以及packages/serverless/lib/plugins/aws/sandboxes下的真实实现按症状——原因——修复——证据验证的方式系统整理部署期、运行期、日志三类高频故障并给出进入实例 Shell 的最后兜底手段。读完你既能对表下药也能理解NotStabilized、stateReason、502/403/429这些表象背后的平台机制从而独立完成一次端到端的排查闭环。排障心法先对症状再验证证据官方排障文档开篇就立下了一条纪律也是整个流程的骨架Match the symptom错误字符串、可观察行为或 CLI 输出到下表某一行套用其修复然后用真实证据验证——一次通过的部署、端点返回的 200、一行日志或get-microvm/get-microvm-image响应中的特定字段。没有这些证据之前不要宣布修好了。这条原则被完整实现进了沙箱插件的工程方法里。框架侧插件ServerlessSandboxes在配置里出现sandboxes键时加载按固定生命周期钩子推进before:package:initialize做同步校验、before:package:finalize编译出 CloudFormation 资源与产物、before:deploy:deploy上传产物见 index.js。因此任何排障动作的终点都不是改完 YAML而是跑通这条链路后拿到可观测信号。下面的排查路径全部遵循该顺序定位症状 → 应用修复 → 用证据确认。部署期故障镜像构建窗口里发生的事serverless deploy会在云端做一次真实的 Firecracker 快照构建耗时以分钟计期间把日志写入/aws/lambda-microvms/image-name日志组资源由 compilers/image.js 生成。下表覆盖最常见的四类部署期失败。症状原因修复校验时报unrecognized property memory或subnets、securityGroups等sandboxesschema 拒绝未知键其属性名与functions块不同改用minimumMemory、vpc.subnetIds、vpc.securityGroupIds——完整属性面见references/config.md连接器创建时报Availability zone use1-az3 is not available for compute type MicroVmInvalidParameterValueException该可用区不支持 MicroVMsAWS 不公布支持名单改用位于不同可用区的子网按可用区IDuse1-az3而非字母us-east-1c匹配——字母在不同账号下的映射不同部署期间 MicrovmImage 报NotStabilized尤其hooksvpc同时配置时镜像构建窗口超时往往是瞬态运行镜像构建查询命令看stateReasonstateReason为空即为瞬态 hooksVPC 超时重试部署即可部署失败日志组已存在堆栈之外已存在名为/aws/lambda-microvms/image-name的日志组删除或重命名该日志组unrecognized propertyschema 是严格的不要拿functions的属性名套用sandboxes不是给functions换了张标签而是一套独立的 schema。在插件的校验器里顶层sandboxes以及hooks、vpc、iam、observability等每个嵌套对象都显式声明additionalProperties: false——未知键是校验错误而非警告。例如钩子值的 schema 就只允许boolean或{ timeout: { type: number, minimum: 1 } }两种形状见 validators/schema.js多写任何键都会在校验阶段被拦下。校验发生在before:package:initialize命中时插件直接抛出SANDBOXES_VALIDATION_ERROR见 index.js。因此看到unrecognized property memory时答案不是删掉这个键而是换成 sandboxes 自己的命名内存minimumMemory而非functions的memorySize网络vpc.subnetIds/vpc.securityGroupIds而非subnets/securityGroupsminimumMemory的合法取值为512 | 1024 | 2048 | 4096 | 8192MiBvCPU 数 内存 GB 数 ÷ 2架构固定 ARM64/Graviton且变更该值会触发一次新的镜像构建——框架按规格为每个沙箱构建独立镜像而不是启动时重新配置单个镜像详见references/config.md。所有合法属性与默认值写作前务必对照 config.md 的完整属性表。可用区不支持 MicroVMs按 AZ ID 选子网Availability zone use1-az3 is not available for compute type MicroVm说明你挑选的可用区不提供 MicroVm 计算类型。要点有二AWS 不公布哪些可用区支持——只能靠报错试探AZ 名称us-east-1c是账号级别名不同账号下映射到不同底层可用区。必须按 AZ IDuse1-az3匹配use1-az3正是文档中点名的已知不支持示例。config.md同时给出约束一旦设置vpcsubnetIds与securityGroupIds各自至少一项校验阶段强制且所有子网必须属于同一个 VPCprotocol可选ipv4或dualstack。实践建议把实例分散到不同 AZ ID 的子网里遇到 capacity/placement 类报错时把一个子网挪到另一个 AZ ID 再部署——这也是 platform.md 明确推荐的诊断流程。NotStabilized读懂镜像构建的stateReason部署期的NotStabilized表示镜像在构建窗口内没有稳定下来hooks与vpc组合使用时会加剧该问题。不要盲猜直接查构建记录aws lambda-microvms list-microvm-image-builds \ --image-identifier image-arn --image-version version \ --query items[].[architecture,buildState,stateReason] --output table返回的stateReason会点名失败类型CONTAINER_BUILD_FAILED——容器构建本身失败。用本地docker build复现构建日志在/aws/lambda-microvms/image-name日志组里该日志组同时收拢云端镜像构建实录与应用运行时的 stdout/stderrBuildKit 阶段输出可能与请求日志交错判断时要对准应用自己的日志行。DISK_STORAGE_FULL——磁盘写满修剪镜像层后重试。INTERNAL_PLATFORM_ERROR——平台内部错误重试。stateReason为空——那就是瞬态的 hooksVPC 超时重试部署并确认readyhook 能在 hooks 端口上快速返回 200。另外注意stateReason只有在你显式查询list-microvm-image-builds或get-microvm/get-microvm-image时才可见commands.md强调部署失败时应先查构建记录再对照排障表。日志组已被占用框架为每个镜像在 CloudFormation 模板里声明同名日志组编译产物见 orchestrator.js日志组默认名/aws/lambda-microvms/Name可在observability.logs.logGroup覆盖。若堆栈外已手动存在同名的日志组CloudFormation 创建会冲突。此时删除或重命名那个游离的日志组即可——注意serverless remove会随堆栈一起删除这个自有的日志组因此游离日志组多来自此前手工操作或残留堆栈。运行期故障实例生命周期与数据面代理运行期故障横跨两套机制一是实例的生命周期状态机PENDING → RUNNING → SUSPENDING → SUSPENDED → TERMINATING → TERMINATEDautoResumeEnabled时SUSPENDED可因入站流量回到RUNNING二是实例背后那条必须带令牌才能访问的代理 HTTPS 端点。下表按症状逐条给出原因与修复症状原因修复实例启动数秒后 TERMINATEDrunhook 返回非 2xx或容器主进程退出aws lambda-microvms get-microvm查stateReason检查容器日志让runhook 快速返回 200实例忙着却挂起idle 计时只统计端点入站流量——出站工作不会重置它干完活就退出进程或调大maxIdleDurationSeconds/ 依赖maximumDurationInSeconds沙箱内 AWS 调用返回AccessDenied执行角色缺少权限向sandboxes.name.iam.executionRole.statements增加最小权限语句部署前可用 dev-mode 的 IAM 仿真复现RunMicrovm 报AccessDeniedException点名PassNetworkConnector或PassRole调用方 IAM 缺少对命名资源的 pass 授权按连接器 ARN 授予lambda:PassNetworkConnector/ 为执行角色授予iam:PassRole实例端点返回 403令牌缺失/过期或端口超出令牌的allowedPorts用正确的端口范围铸造新令牌通过X-aws-proxy-auth发送实例端点返回 502应用没监听、崩溃、恢复失败已挂起且autoResumeEnabled: false或自动恢复耗尽重试。启动最初几秒出现 502 也可能正常——快照恢复期间实例状态是最终一致的若是启动后最初几秒带退避重试即可不要轮询get-microvm否则查容器日志 / 实例状态恢复或重新启动实例端点返回 429命中实例级 RPS/连接上限调大minimumMemory上限随规格增长或在多个实例间分摊每个实例的 ID / UUID / token 都相同该值在镜像构建期生成并被固化进共享快照在runhook 里生成实例级状态或用 CSPRNG 每次调用现取——见references/platform.md快照唯一性已挂起的实例收到流量后不自动恢复启动时未设autoResumeEnabled、实例已 TERMINATED自动恢复不会复活已终止实例或慢resumehook 超时查get-microvm状态与stateReason设置autoResumeEnabled: true给resume显式 timeout启动即 TERMINATEDrunhook 是发射闸门runhook 是实例的启动闸门平台在它返回 200 之前会扣住该实例的全部端点流量返回非 2xx 会立刻终止实例并落入TERMINATED同时stateReason会点名是哪个 hook 失败。它的请求体是{microvmId: ..., runHookPayload: ...}——这也是整个生命周期里唯一能把实例级数据送进容器的地方。拿到aws lambda-microvms get-microvm --microvm-identifier id的输出后重点看state与stateReason两个字段。若根因是 hook 处理慢要记住运行时 hook 的默认 timeout 只有1 秒ready默认 60svalidate/run/resume/suspend/terminate均默认 1s构建期 hook 允许 1–3600s运行期 hook 只允许 1–60s。因此文档给出的 handler 契约是先快速回 200重活放响应之后异步做唯一例外是ready可回 503 表示还没就绪请重试。如果你的runhook 里做了真实工作才应答务必在serverless.yml里声明显式timeoutsandboxes: app: artifact: ./app hooks: run: timeout: 30同样的机制被 dev 仿真器完整复刻——dev会把非 2xx 的run直接转为实例终止并给出说明哪个 hook 失败的stateReason见dev-mode.md所以 hook 缺陷在本地就能暴露不必烧一次真实部署。忙却被挂起idle 只认入站流量这是 sandboxes 最反直觉的一条平台事实idle 计时器只统计实例端点上的最近一次入站请求除此之外什么都不算——不是 CPU 使用率、不是进程活动、不是出站连接。一个埋头计算但收不到入站请求的实例照常按maxIdleDurationSeconds挂起反过来只做出站调用的 worker比如轮询队列的进程永远不会被自己的活动续命。两个空闲闸门按序独立计时RUNNING ──(idle ≥ maxIdleDurationSeconds)──► SUSPENDED ──(elapsed ≥ suspendedDurationSeconds)──► TERMINATED │ │ │ inbound request (any time) │ inbound request, if autoResumeEnabled └────────────── stays RUNNING ◄───────────────┘字段约束maxIdleDurationSeconds60–28,800suspendedDurationSeconds最小 0设 0 挂起即终止跳过挂起窗口autoResumeEnabled布尔控制SUSPENDED实例是否随入站流量自动恢复另外两条不经任何闸门的立即终止路径要记住容器主进程随时退出 → 立即TERMINATEDmaximumDurationInSeconds1–28,800s硬顶 8 小时是 RUNNINGSUSPENDED 合计时长的绝对上限即使实例在正常服务也会触发。所以对于只出不进的 worker要么主动退出进程以立刻停表要么靠maximumDurationInSeconds兜底——否则它会因永远等不到入站流量而一直不挂起持续计费。dev 仿真器同样执行这套双闸门策略无入站流量到maxIdleDurationSeconds自动挂起再过一个suspendedDurationSeconds自动终止不传--idle-policy则两闸门都关闭实例一直跑适合测试一次性 worker。AccessDenied 一族执行角色与 pass 授权沙箱内发起的 AWS 调用走的是实例的执行角色报AccessDenied说明角色缺权限。修复姿势不是换一个宽泛的预置角色而是给框架生成的最小权限角色追加语句sandboxes: app: artifact: ./app iam: executionRole: statements: - Effect: Allow Action: - s3:GetObject Resource: arn:aws:s3:::example-bucket/*注意iam.executionRole与iam.buildRole支持三种形态自定义对象{ statements, managedPolicies, permissionsBoundary }语句会被合并进框架生成的最小权限角色而非替换、既有角色 ARN 字符串跳过生成原样使用、CloudFormation 内建函数引用Ref/Fn::GetAtt/Fn::ImportValue/Fn::Sub。实现上自定义语句与生成角色的合并逻辑位于 iam/policies.js对应的 schema 与单元测试见 validators/schema.js 与packages/serverless/test/unit/lib/plugins/aws/sandboxes/目录。两个高价值的前置手段dev-mode IAM 仿真serverless dev --sandbox app在本地用容器跑沙箱并尽可能假定沙箱真实的执行角色运行容器——生产里会踩的AccessDenied在本地部署前就能复现。角色假定失败时它会回退到你的 ambient 凭据并打印提示可用--no-assume-role显式跳过假定。RunMicrovm 时的 pass 授权若报错点名PassNetworkConnector/PassRole那是发起 RunMicrovm 的调用方 IAM框架部署角色或你的自建控制面代码缺 pass 授权与实例执行角色是两码事。需要按连接器 ARN 授予lambda:PassNetworkConnector、为执行角色授予iam:PassRole。框架在沙箱配置了vpc时会自动创建AWS::Lambda::NetworkConnector资源见 networkConnector.js其AssociatedComputeResourceTypes即[MicroVm]。数据面三兄弟403 / 502 / 429每个实例只能通过代理 HTTPS 端点访问没有直达微虚拟机的网络路径。平台对这三类代理层状态码的定义是403——令牌错误/过期或端口超出令牌allowedPorts范围。令牌由CreateMicrovmAuthToken铸造最多 60 分钟有效铸造时按端口限定作用域单端口{port}/ 区间{range}/ 全端口{allPorts}。请求必须携带X-aws-proxy-auth头。修复按正确的端口范围铸造新令牌再请求。502——应用没在目标端口监听、崩溃、恢复失败挂起 autoResumeEnabled: false或自动恢复把重试耗尽。注意启动后最初几秒的 502 可能是正常的快照恢复期间实例状态最终一致正确做法是带退避重试而不是轮询get-microvm去判断就绪。429——命中实例级吞吐上限。实例 RPS 随规格从 40 到 160、并发连接随规格从 8 到 128 线性扩展。修复调大minimumMemory上限随规格增长或把负载摊到多个实例上。代理默认把流量转给实例的 8080 端口可用X-aws-proxy-port按请求覆盖必须在令牌作用域内x-aws-proxy-*头命名空间被代理保留你发送的这类头在到达实例前都会被剥掉。代理对 HTTP/2、WebSocket、gRPC、SSE 协议透明。框架的invoke --sandbox与日志/数据面代码同样围绕这套状态码与生命周期语义工作实例编排与输出逻辑集中在 orchestrator.js产出NameImageIdentifier供RunMicrovm/list-microvms作为imageIdentifier使用运行期数据面实现在 runtime/dataplane.js。想知道这些行为在单元层如何被验证可以读packages/serverless/test/unit/lib/plugins/aws/sandboxes/runtime/dataplane.test.js与compilation/orchestrator.test.js。每个实例的 ID 都相同快照唯一性陷阱镜像构建会产出一份 Firecracker 快照该镜像版本的每个实例都从同一快照启动或恢复。因此构建期生成的任何东西——UUID、PRNG 种子、令牌、拉取的密钥——都会被固化进快照于是每个实例包括之后从同一快照恢复的实例拿到的值完全相同。platform.md 给出的修复优先级值在首次使用时生成而不是构建期生成在runhook 里生成——它是保证按实例执行的唯一位置且能从runHookPayload读取出该实例的差异化数据必须在别处读随机性时用 CSPRNG 每次调用现读而非一次性播种——Node 里用crypto.randomUUID()/crypto.randomBytes()绝不要用Math.random()播种的生成器。内核层面AWS 文档化了快照恢复时内核 RNG 会重新播种所以按调用读取/dev/urandom、crypto.randomBytes是安全的但用户态库除非每次调用都重新读内核否则不会自动受益。只有 AWS 默认基础镜像public.ecr.aws/lambda/microvms:al2023-minimal自带的 OpenSSL 构建会在恢复时自动重播种其他基础镜像不一定。顺便牢记非本地的出站 TCP 连接在run和resume时都会被切断AWS SDK 会透明重试所以一般无感其他 HTTP/数据库客户端要自己配好重连。挂起后不自动恢复自动恢复的成立条件是三者缺一不可启动时设了autoResumeEnabled: true、实例仍处于SUSPENDED它永远不会复活已TERMINATED的实例、resumehook 在显式 timeout 内完成。排查时先get-microvm看状态与stateReason。autoResumeEnabled开启后入站请求会命中SUSPENDED实例并触发恢复Lambda 会一直扣住该请求直到恢复完成——调用方看到的是延迟而非错误只有恢复本身失败才会得到 502。若resumehook 干重活务必给它显式timeout否则 1 秒默认值大概率让它超时。日志排查先放大时间窗口症状原因修复serverless logs --sandbox什么都不打印默认窗口是最近 10 分钟--startTime 30m沙箱日志组的流名内嵌microvmId框架的 observability 编译逻辑甚至会用SOURCE log-group | stats count_distinct(logStream) as microvms by bin(5m)这样的查询按微虚拟机聚合计数见 compilers/observability.js可见日志里没有内容极少意味着没有产生日志更多是窗口没对上。logs --sandbox name必需显式点名沙箱与invoke --sandbox同规则没有隐式默认默认只看最近 10 分钟。放宽窗口serverless logs --sandbox app --startTime 30m--startTime支持相对偏移30m、2h、1d或绝对时间戳。沙箱日志没有 tail/跟随模式传--tail会被接受但忽略并给出警告命令总是打印解析后的窗口然后退出。日志组里还混着云端镜像构建实录与应用运行时输出判断应用行为时对齐你自己的日志行。最后手段用 SHELL_INGRESS 钻进实例当日志不足以解释行为时官方排障指南给出的兜底是进到运行中的实例里交互排障。连接器在启动时固定、事后无法追加所以预估可能需要 Shell 时要在 launch 参数里带上它arn:aws:lambda:region:aws:network-connector:aws-network-connector:SHELL_INGRESS放在ingressNetworkConnectors中。然后铸造 Shell 令牌aws lambda-microvms create-microvm-shell-auth-token \ --microvm-identifier microvm-id --expiration-in-minutes 15连接方式二选一AWS 控制台 MicroVM 详情页的 Connect 按钮或用 WebSocket 客户端携带子协议lambda-microvms、lambda-microvms.authentication.token、lambda-microvms.port.8022。Shell 落在与应用相同的容器里——同一套文件系统、进程与网络可以直接观察进程、查文件、手动触达端点。调用方 IAM 还需要lambda:CreateMicrovmShellAuthToken把该令牌当密钥对待过期时间保持短≤60 分钟。Shell 排查配合另一组诊断利器使用效果最佳get-microvm查单实例状态与stateReason、list-microvms --image-identifier arn --query items[].[microvmId,state]按镜像列实例注意响应键是items、terminate-microvm在serverless remove前清理仍引用镜像的存活实例。排查工具箱与快速对照把散落各处的诊断原语收拢成一个速查清单故障时按顺序取用想弄清什么用什么镜像构建为何失败 /NotStabilizedaws lambda-microvms list-microvm-image-builds --image-identifier arn --image-version version→ 读stateReason实例为何 TERMINATEDaws lambda-microvms get-microvm --microvm-identifier id→ 读statestateReason点名失败 hook实例现在什么状态 / 是否可恢复同上确认是否还SUSPENDED、autoResumeEnabled是否生效直接调实例端点create-microvm-auth-token铸造令牌 →curl -H X-aws-proxy-auth: token endpoint/path403 换令牌502 退避重试429 扩容本地先复现 / IAM 仿真serverless dev --sandbox name等待MicroVMs API ready后把 AWS CLI 指向http://127.0.0.1:9100或传--endpoint-url清理账单先terminate-microvm全部存活实例再serverless remove修剪INACTIVE镜像版本用delete-microvm-image-version最后提醒三件事它们贯穿所有排障场景其一不要轮询get-microvm判断就绪用一次带认证的端点请求的成功代替其二不要对框架登录失败或 AWS 凭据失败做重试循环——前者引导用户交互式serverless login后者引导serverless login aws/serverless login aws sso其三挂起的快照和旧镜像版本即使没有实例在跑也在计费验证完立刻serverless remove清理临时部署。以上内容在官方排障文档troubleshooting.md的See also里分别指向 config.md完整配置面、dev-mode.md本地开发循环与 IAM 仿真、platform.md生命周期状态机与平台契约它们是本指南逐条症状背后原理的完整出处。【免费下载链接】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),仅供参考