返回

文章详情

如何在大规模上运行不受信任的客户代码

Hacker News2026年6月9日 15:31

Nango 是一个以代码为中心的平台,用于构建产品 API 集成。客户将他们的应用连接到 Salesforce、Google 日历、Slack 和其他几百个 API。这些集成背后的大部分代码是由我们的客户编写并部署给我们的。该代码是不受信任的,可能试图做任何事情:获取一个 API、转换数据、抛出异常、泄漏内存或故意尝试突破限制。我们每个月在不同工作负载下运行超过 1.5 亿个这样的函数。我们对代码运行时的要求:我们运行三种非常不同的工作负载:按需调用(Actions):为用户或代理运行,因此它们必须快速启动和完成。冷启动会造成损失。长时间运行的作业(Syncs):在后台复制数据,有时需要几个小时,处理数百万条记录。它们需要可恢复的执行。突发事件(webhooks):以不可预测的峰值出现,因此必须能够吸收突如其来的洪水。运行不受信任的代码增加了更多的要求:与我们的系统隔离:一个函数绝不能访问我们的数据库、机密或内部网络。租户之间的隔离:一个客户的代码不得访问另一个客户的代码,而一个客户的重型作业也不得让其他所有人饿死。执行之间的隔离:一个客户可以有长短期混合的作业。作业不应争夺相同的资源。成本和弹性:我们不会为闲置计算支付费用或手动扩展一个集群。满足这些要求并不容易。减少冷启动意味着保持环境温暖,这会花费金钱;长同步需要更长的运行时间;峰值 webhook 需要从零扩展的廉价计算。我们构建的每个运行时都有一些权衡,但我们一直尝试优先考虑安全性。我们开始使用进程中的沙箱 (vm2):在我们的前几年,我们在同一个进程中运行客户代码,使用 vm2,这是一个 Node.js 沙箱,它和运行作业的工作者在同一进程中。客户的函数与我们自己的代码并行执行,vm2 阻止它访问我们的数据库、机密和其他客户的数据。这很简单,不需要额外的基础设施。但是,在 2023 年,vm2 的维护者在一系列沙箱逃逸漏洞后暂时归档了该项目:沙箱中的代码可以访问主机并在工作者上运行。恶意集成也可以对我们这样做。我们了解到,进程中的 JavaScript 沙箱并不是一个真正的安全边界。与不受信任的代码共享一个进程,你只需一次逃逸就可能面临严重的问题。将不受信任的代码隔离在运行器中,所以我们停止在任何重要进程中运行客户代码。我们将系统分为两部分。调度器通过 HTTP 将每个客户的代码交给一个运行器,独立的运行器来执行它。每个客户都有自己长期存在的运行器,独立扩展:更多的 CPU 或内存,或为重的账户增加额外的副本。我们还构建了一个编排层,按需启动运行器,退休闲置的运行器,并在数百个运行器中推出更新。调度程序最初在 Temporal 上运行;后来我们将其移至 Postgres(另一个故事)。至关重要的是,运行器没有直接的数据库访问权限。要读取或写入记录,函数调用一个像 nango.batchSave(...) 这样的 SDK 方法,该方法通过网络调用到一个独立的持久化服务;持久化服务与数据库进行通信,运行器永远不会直接访问。一个运行器保持客户的代码和它所需的最小内容,没有更多。我们将这些运行器作为独立服务在 Render 上运行。转向 AWS Lambda:到 2025 年底,运行器模型在资源公平性和可观测性方面面临困难。一个运行器会同时运行一个客户的所有执行,因此一个重的作业,比如复制数百万条记录的连接,可能会让该客户的其他函数资源匮乏。当运行器遇到内存不足时,我们无法可靠地识别出是哪个函数导致了这个问题。我们希望隔离每次执行并观察每一次。AWS Lambda 同时提供了这两项功能。有了 Lambda,每次执行都在自己的硬件虚拟化的微虚拟机中运行,具有自己的内核,远比共享进程强大,AWS 处理扩展。我们也考虑过 Knative 和基于 WASM 的运行时等其他替代方案,但它们类似于 Lambda,而成熟程度远低于 Lambda。我们立即看到了改进。内存/CPU 问题现在指向单个连接的函数,在该函数自己的日志中可见,而不再是含糊的「这个运行器出现了问题」,而且一个不良的代码函数也不再影响其他函数。对于一个支持数百个客户的小团队来说,这显著减少了调试这些问题所花费的时间。然而,有一个问题。一个 Lambda 函数最多运行 15 分钟,而我们的同步作业运行得更长。所以我们在产品方面解决了这个问题:对同步作业每次运行设定 10 分钟的上限,并增加一个检查点功能,让同步作业可以在多个运行间继续,而不是依赖于单次长时间执行。可恢复的运行始终优于单次 24 小时作业,因为一个在第 23 小时崩溃并从零重新启动的作业就是自己的

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡