跳转到内容
搜索文档

容器生命周期

最后更新 查看 MarkdownAgent 设置

部署

在使用容器部署应用程序后,你的镜像会被上传到 Cloudflare Registry 并在 Cloudflare 网络中全局分发。 Cloudflare 会在全球预先调度实例并预先拉取镜像,以确保在扩展并发容器实例数量时能够快速启动。

与部署时立即更新的 Workers 不同,容器实例使用滚动部署策略进行更新。 这允许你在发布期间优雅地关闭任何正在运行的实例。有关更多细节,请参阅发布。

请求生命周期

从客户端到 Worker

回想一下,容器由 Durable Objects 和 Workers 支持。 请求首先通过 Worker 路由,通常由在请求用户之间拥有最佳延迟的位置的数据中心处理。 如果开启了智能放置(Smart Placement),或者如果最近的位置处于高负载状态,则可能会选择不同的数据中心来优化整体延迟。

由于所有容器请求都通过 Worker 传递,因此终端用户无法向容器实例发出非 HTTP 的 TCP 或 UDP 请求。如果你有需要终端用户入站 TCP 或 UDP 的用例,请让我们知道 ↗。

从 Worker 到 Durable Object

从 Worker,请求通过一个 Durable Object 实例传递(Container 类扩展了 Durable Object 类)。 每个 Durable Object 实例都是一个全局可路由的隔离区,可以执行代码并存储状态。这允许 开发人员轻松寻址并路由到特定的容器实例(无论它们被放置在何处), 在容器状态改变时定义并运行钩子(hooks),对实例执行定期检查,并存储与 每个实例相关联的持久状态。

启动容器

当 Durable Object 实例请求启动新的容器实例时,会选择具有预先拉取镜像的 最近位置。

启动其他容器实例将使用其他具有预先拉取镜像的位置, 并且 Cloudflare 会在后台自动开始准备额外的机器 以进行额外的扩展和快速冷启动。由于预热的位置数量是有限的, 某些容器实例可能会在距离终端用户较远的位置启动。这样做 是为了确保容器实例快速启动。你只 需要为积极运行的实例付费,而不需要为任何未使用的预热镜像付费。

冷启动

冷启动是指容器实例从完全停止的状态启动。 如果你使用一个全新的 ID 调用 env.MY_CONTAINER.get(id) 并且首次 启动此实例,则会导致冷启动。 这将首次从其入口点(entrypoint)启动容器镜像。根据 此入口点执行的操作,启动需要不同长度的时间。

容器冷启动通常在 1-3 秒范围内,但这取决于 镜像大小和代码执行时间等因素。

向正在运行的容器发起请求

当请求启动新的容器实例时,会选择具有预先拉取镜像的最近位置。 之后无论它们源自何处,对该特定实例的后续请求,只要 该实例保持活动状态,就会被路由到这个位置。

但是,一旦该容器实例停止并重新启动,将来的请求可能会被路由到一个不同的位置。 这个位置将再次是距离源请求最近的具有预先拉取镜像的位置。

容器运行时

每个容器实例都在其自己的 VM 内运行,这提供了 与 Cloudflare 网络上运行的其他工作负载的强隔离。容器 应该为 linux/amd64 架构构建,并应保持在 大小限制范围内。

正如开发人员配置的那样,每个容器上自动设置了日志记录、指标收集和 网络。

容器关闭

如果你没有在 Container 类上设置 sleepAfter, 或者手动停止该实例,容器将在停止接收请求后很快关闭。 通过设置 sleepAfter,容器将在指定的大约持续时间内保持活动状态。

你可以通过调用其上的 stop() 或 destroy() 手动关闭容器实例。

当容器实例将要被关闭时,系统会向它发送 SIGTERM 信号, 然后在 15 分钟后发送 SIGKILL 信号。你应该在这段时间内执行任何必要的 清理以确保优雅关闭。

生命周期钩子

Container 类提供了当容器改变状态时运行 Worker 代码的钩子:

  • onStart() — 在容器启动后运行。

  • onStop() — 在容器进程退出后运行。接收退出代码和停止原因。

  • onActivityExpired() — 当 sleepAfter 计时器过期且没有传入请求时运行。默认实现调用 stop() 来关闭容器。你可以使用它仅在某些条件下停止容器。

  • onError() — 当容器退出并带有错误时运行。

请参阅状态钩子示例以获取完整实现。

持久磁盘

所有磁盘都是临时的。当容器实例进入睡眠状态时,下次 它启动时,它将拥有一个由其容器镜像定义的全新磁盘。

快照功能即将推出,该功能允许用户快速从 整个容器或目录持久化和恢复磁盘。

你也可以使用 FUSE 将磁盘持久化 到 R2 或其他对象存储后端。不过在使用 FUSE 时,不应期望原生 SSD 般的性能。

请求示例

  • 开发人员部署了一个容器。Cloudflare 会在其网络中自动准备就绪实例。
  • 位于阿根廷巴里洛切的客户端发出请求。它到达阿根廷内乌肯的附近 Cloudflare 位置的 Worker。
  • 这个 Worker 请求调用 getContainer(env.MY_CONTAINER, "session-1337")。在底层,这带起了一个 Durable Object,接着它调用 this.ctx.container.start。
  • 这请求最近的可用容器实例。Cloudflare 识别出阿根廷布宜诺斯艾利斯有一个可用实例,并 在那里启动它。
  • 不同的用户需要路由到相同的容器。此用户的请求到达 运行在美国圣地亚哥 Cloudflare 位置的 Worker。
  • Worker 再次调用 getContainer(env.MY_CONTAINER, "session-1337")。
  • 如果初始容器实例仍在运行,请求被路由到布宜诺斯艾利斯的原始位置。 如果初始容器已进入睡眠状态,Cloudflare 将 再次尝试找到该容器最近的“空闲”实例,可能 是位于北美的一个,并在那里启动实例。

这篇文档对您有帮助吗?