跳转到内容
搜索文档

开始使用

最后更新 查看 MarkdownAgent 设置

在本指南中,您将部署一个 Worker,该 Worker 能够响应最终用户请求以向一个或多个容器(Containers)发出请求。 在此示例中,每个容器都会运行一个用 Go 编写的小型 Web 服务器。

这个示例 Worker 应该能让您对简单的容器使用有所了解,并为更复杂的用例提供一个起点。

先决条件

确保 Docker 在本地运行

在本指南中,我们将与您的 Worker 代码一起构建并推送容器镜像。默认情况下,此过程使用 Docker 来完成。

当您运行 wrangler deploy 时,必须在本地运行 Docker。对于大多数人来说,安装 Docker 的最佳方式是按照安装 Docker Desktop 的文档进行操作。其他工具(如 Colima)也可能有效。

您可以通过在终端中运行 docker info 命令来检查 Docker 是否正常运行。如果 Docker 正在运行,该命令将成功执行。如果 Docker 未运行,docker info 命令将挂起或返回包含 "Cannot connect to the Docker daemon" 消息的错误。

部署您的第一个容器

运行以下命令以从入门模板创建并部署带有容器的新 Worker:

npm create cloudflare@latest -- --template=cloudflare/templates/containers-template

如果要将代码更改部署到 Worker 或容器代码中,可以使用 Wrangler CLI 运行以下命令:

npx wrangler deploy

运行 wrangler deploy 时,会发生以下情况:

  • Wrangler 使用 Docker 构建您的容器镜像。
  • Wrangler 将您的镜像推送到自动与您的 Cloudflare 账户集成的容器镜像注册表
  • Wrangler 部署您的 Worker,并配置 Cloudflare 的网络以准备好生成容器的实例。

第一次部署时,构建和推送通常需要最长的时间。随后的部署会更快,因为它们重用缓存的镜像层

检查部署状态

部署后,运行以下命令以显示 Cloudflare 账户中的容器列表及其部署状态:

npx wrangler containers list

并使用以下命令查看部署到 Cloudflare 注册表的镜像:

npx wrangler containers images list

向容器发出请求

现在,打开您的 Worker 的 URL。它应该看起来像 https://hello-containers.<YOUR_WORKERS_SUBDOMAIN>.workers.dev

如果您向路径 /container/1/container/2 发出请求,您的 Worker 会将请求路由到特定的容器。"/container/" 之后的每个不同路径都将路由到一个唯一的容器。

如果您向 /lb 发出请求,您将对随机选择的 3 个容器之一的请求进行负载均衡。

您可以通过读取每个请求的输出来确认此行为。

了解代码

既然您已经部署了第一个容器,让我们解释一下 Worker 的代码、配置文件、容器的代码中发生了什么,以及请求是如何路由的。

配置

您的 Wrangler 配置文件 定义了 Worker 和容器的配置:

{
	"containers": [
		{
			"max_instances": 10,
			"class_name": "MyContainer",
			"image": "./Dockerfile",
		},
	],
	"durable_objects": {
		"bindings": [
			{
				"name": "MY_CONTAINER",
				"class_name": "MyContainer",
			},
		],
	},
	"migrations": [
		{
			"tag": "v1",
			"new_sqlite_classes": ["MyContainer"],
		},
	],
}
[[containers]]
max_instances = 10
class_name = "MyContainer"
image = "./Dockerfile"

[[durable_objects.bindings]]
name = "MY_CONTAINER"
class_name = "MyContainer"

[[migrations]]
tag = "v1"
new_sqlite_classes = [ "MyContainer" ]

关于此配置的要点:

  • image 指向一个 Dockerfile、包含 Dockerfile 的目录,或指向一个完全限定的镜像引用,例如 registry.cloudflare.com/<YOUR_ACCOUNT_ID>/<IMAGE>:<TAG>
  • class_name 必须是 Durable Object 类名称
  • max_instances 声明将运行的并发运行容器实例的最大数量。
  • Durable Object 必须使用 new_sqlite_classes 而不是 new_classes

容器镜像

您的容器镜像必须能够在 linux/amd64 架构上运行,但除此之外,几乎没有其他限制。

在您刚刚部署的示例中,它是一个简单的 Golang 服务器,它使用将在 Worker 中设置的 MESSAGE 环境变量和自动生成的环境变量 CLOUDFLARE_DEPLOYMENT_ID,在端口 8080 上响应请求。

func handler(w http.ResponseWriter, r *http.Request) {
	message := os.Getenv("MESSAGE")
	instanceId := os.Getenv("CLOUDFLARE_DEPLOYMENT_ID")

	fmt.Fprintf(w, "Hi, I'm a container and this is my message: %s, and my instance ID is: %s", message, instanceId)
}

Worker 代码

容器配置

首先要注意扩展了 Container 类的 MyContainer

export class MyContainer extends Container {
  defaultPort = 8080;
  sleepAfter = '10s';
  envVars = {
    MESSAGE: 'I was passed in via the container class!',
  };

  override onStart() {
    console.log('Container successfully started');
  }

  override onStop() {
    console.log('Container successfully shut down');
  }

  override onError(error: unknown) {
    console.log('Container error:', error);
  }
}

这定义了容器的基本配置:

  • defaultPort 设置了 fetchcontainerFetch 方法将用来与容器通信的端口。它还会阻止请求,直到容器侦听该端口为止。
  • sleepAfter 设置容器在空闲一定时间后休眠的超时。
  • envVars 设置在容器启动时将传递给容器的环境变量。
  • onStartonStoponError 分别是容器启动、停止或出错时运行的钩子。

Container 类本身扩展了 DurableObject,因此您的子类可以访问完整的 Durable Object API。Durable Object 处理路由、生命周期和持久状态,而容器进程在 Linux VM 中运行您的镜像。这意味着您可以使用 this.ctx.storage 来持久化容器重启后仍然存在的数据,并驻留在容器本身附近。

有关更多详细信息,请参阅 容器类参考低级 Durable Object 容器 API

路由到容器

当请求进入 Cloudflare 时,您的 Worker 的 fetch 处理程序 将被调用。这是处理传入请求的代码。示例代码中的 fetch 处理程序在不同的路由上以两种方式启动容器:

  • /container/ 发出请求会将每个路径的请求传递给新容器。这是通过启动新的容器实例来完成的。您可能会注意到,对新路径的第一个请求比随后的请求耗时更长,这是因为新容器正在启动。

    if (pathname.startsWith("/container")) {
    	const container = env.MY_CONTAINER.getByName(pathname);
    	return await container.fetch(request);
    }
  • /lb 发出请求将跨多个容器对请求进行负载均衡。这里使用了一个简单的 getRandom 辅助方法,该方法从设定的数量(在此示例中为 3 个)中随机选取一个 ID,然后路由到该容器实例。您可以将其替换为您选择实现的任何路由或负载均衡逻辑:

    if (pathname.startsWith("/lb")) {
    	const container = await getRandom(env.MY_CONTAINER, 3);
    	return await container.fetch(request);
    }

这允许多种使用容器的方式:

  • 如果您只是想将请求发送到许多无状态且可互换的容器,则应使用负载均衡。
  • 如果您有状态服务或需要单独寻址的容器,则应请求特定的容器实例。
  • 如果您正在运行短期作业,希望对容器生命周期进行细粒度控制,希望参数化容器入口点或环境变量,或者希望将多个容器调用链接在一起,则应请求特定的容器实例。

在仪表板中查看容器

容器仪表板向您显示有关您的容器的有用信息,包括:

  • 状态和运行状况
  • 指标
  • 日志

启动 Worker 后,通过在仪表板侧边栏中选择 Workers & Pages > Containers(容器) 前往容器仪表板。

后续步骤

要做更多:

  • 通过更改 Dockerfile 并调用 wrangler deploy 来修改镜像
  • 查看我们的示例以获取更多灵感
  • 查看常见问题解答以了解当前平台的行为和限制

这篇文档对您有帮助吗?