在使用容器部署应用程序后,你的镜像会被上传到 Cloudflare Registry 并在 Cloudflare 网络中全局分发。 Cloudflare 会在全球预先调度实例并预先拉取镜像,以确保在扩展并发容器实例数量时能够快速启动。
与部署时立即更新的 Workers 不同,容器实例使用滚动部署策略进行更新。 这允许你在发布期间优雅地关闭任何正在运行的实例。有关更多细节,请参阅发布。
回想一下,容器由 Durable Objects 和 Workers 支持。 请求首先通过 Worker 路由,通常由在请求用户之间拥有最佳延迟的位置的数据中心处理。 如果开启了智能放置(Smart Placement),或者如果最近的位置处于高负载状态,则可能会选择不同的数据中心来优化整体延迟。
由于所有容器请求都通过 Worker 传递,因此终端用户无法向容器实例发出非 HTTP 的 TCP 或 UDP 请求。如果你有需要终端用户入站 TCP 或 UDP 的用例,请让我们知道 ↗。
从 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 将 再次尝试找到该容器最近的“空闲”实例,可能 是位于北美的一个,并在那里启动实例。