跳转到内容
搜索文档

使用 Tunnel 连接私有数据库

最后更新 查看 MarkdownAgent 设置

Hyperdrive 可使用 Cloudflare TunnelCloudflare Access 安全连接到私有数据库。

工作原理

当数据库隔离在私有网络内(例如虚拟私有云或本地网络)时,须启用从网络到 Cloudflare 的安全连接。

从 Cloudflare Worker 到源数据库的请求经过 Hyperdrive、Cloudflare Access 和 cloudflared 建立的 Cloudflare Tunnel。cloudflared 必须在可访问数据库的私有网络中运行。

Cloudflare Tunnel 将从私有网络到 Cloudflare 建立出站双向连接。Cloudflare Access 将保护 Cloudflare Tunnel,使其仅可被 Hyperdrive 配置访问。

从 Cloudflare Worker 到源数据库的请求经过 Hyperdrive、Cloudflare Access 和 cloudflared 建立的 Cloudflare Tunnel。

开始之前

所有教程都假设你已经完成了快速入门指南,该指南帮助你设置 Cloudflare Workers 账户、C3Wrangler

前置条件

  • 私有网络中的数据库,已配置使用 TLS/SSL
  • Cloudflare 账户上的主机名,用于将请求路由到数据库。

1. 在私有网络中创建 tunnel

1.1. 创建 tunnel

首先,在私有网络中创建 Cloudflare Tunnel,在网络与 Cloudflare 之间建立安全连接。须配置网络,使 tunnel 有权出站连接到 Cloudflare 网络并访问网络内的数据库。

  1. 登录 Cloudflare 仪表板,转到 Networking(网络) > Tunnels(隧道)

    Go to Tunnels ↗
  2. 选择 Create a tunnel(创建隧道)

  3. 为您的隧道输入名称。我们建议选择能够反映您希望通过此隧道连接的资源类型的名称(例如,enterprise-VPC-01)。

  4. 选择 Create Tunnel(创建隧道)

  5. 选择您的操作系统,然后复制安装命令并在您的源服务器的终端上运行。

  6. 等待隧道连接。连接建立后,选择 Continue(继续)

1.2. 使用公网主机名连接数据库

tunnel 须配置为使用 Cloudflare 上的公网主机名,以便 Hyperdrive 将请求路由到该 tunnel。若 Cloudflare 上尚无主机名,需注册新主机名添加 zone 到 Cloudflare 才能继续。

  1. Published application routes(已发布的应用程序路由) 选项卡中,选择 Domain(域名) 并指定任何子域或路径信息。此信息将用于 Hyperdrive 配置以路由到此 tunnel。

  2. Service(服务) 部分,指定 Type(类型)TCP 以及数据库的 URL 和配置端口,例如 localhost:5432my-database-host.database-provider.com:5432。tunnel 将使用此地址将请求路由到数据库。

  3. 选择 Save tunnel(保存隧道)

2. 创建并配置 Hyperdrive 以连接到 Cloudflare Tunnel

要限制 Cloudflare Tunnel 的访问为 Hyperdrive,须配置 Cloudflare Access 应用Policy,要求请求包含有效的 Service Auth 令牌

Cloudflare 仪表板可自动创建并配置底层 Cloudflare Access 应用Service Auth 令牌Policy。也可手动创建 Access 应用并配置 Policy。

自动创建

2.1.(自动)在 Cloudflare 仪表板中创建 Hyperdrive 配置

在 Cloudflare 仪表板中创建 Hyperdrive 配置,以自动配置 Hyperdrive 连接到 Cloudflare Tunnel。

  1. Cloudflare 仪表板 中,前往 Storage & Databases(存储和数据库) > Hyperdrive 并点击 Create configuration(创建配置)
  2. 选择 Private database(私有数据库)
  3. Networking details(网络详细信息) 部分,选择要连接的 tunnel。
  4. Networking details(网络详细信息) 部分,选择与 tunnel 关联的主机名。若数据库没有主机名,返回步骤 1.2. 使用公网主机名连接数据库
  5. Access Service Authentication Token(Access 服务身份验证令牌) 部分,选择 Create new (automatic)(新建(自动))
  6. Access Application(Access 应用程序) 部分,选择 Create new (automatic)(新建(自动))
  7. Database connection details(数据库连接详细信息) 部分,输入数据库 name(名称)user(用户)password(密码)

手动创建

2.1.(手动)创建服务令牌

服务令牌将用于限制对 tunnel 的请求,下一步需要此令牌。

  1. Cloudflare 仪表板 中,前往 Zero Trust > Access controls(访问控制) > Service credentials(服务凭据) > Service Tokens(服务令牌)

  2. 选择 Create Service Token(创建服务令牌)

  3. 为服务令牌命名。名称便于在日志中识别与该令牌相关的事件,并单独撤销令牌。

  4. Service Token Duration(服务令牌有效期) 设为 Non-expiring(永不过期)。这可防止服务令牌过期,确保可在 Hyperdrive 配置生命周期内使用。

  5. 选择 Generate token(生成令牌)。将看到生成的 Client ID(客户端 ID)Client Secret(客户端密钥) 及其各自的请求头。

  6. 复制 Access Client ID 和 Access Client Secret。创建 Hyperdrive 配置时将使用这些值。

2.2.(手动)创建 Access 应用以保护 tunnel

Cloudflare Access 将验证对 tunnel 的请求是否来自 Hyperdrive,并使用上面创建的服务令牌。

  1. Cloudflare 仪表板 中,前往 Zero Trust > Access controls(访问控制) > Applications(应用程序)

  2. 选择 Create new application(创建新应用程序)

  3. 选择 Self-hosted and private(自托管和私有)

  4. 选择 Add public hostname(添加公共主机名) 并输入先前为 tunnel 应用设置的子域和域。

  5. 选择 Create new policy(创建新策略)

  6. 输入 Policy name(策略名称) 并将 Action(操作) 设为 Service Auth

  7. 创建 Include(包含) 规则。将 Selector(选择器) 指定为 Service TokenValue(值) 指定为步骤 2. 创建服务令牌 中创建的服务令牌。

  8. 保存 policy。

  9. Identity providers(身份提供商) 中,关闭 Accept all available identity providers(接受所有可用的身份提供商) 并清除所有身份提供商。

  10. Session Duration(会话持续时间) 中,选择 No duration, expires immediately(无持续时间,立即过期)

  11. (可选)前往 Additional settings(其他设置)。关闭 Show application in App Launcher(在 App Launcher 中显示应用程序)

  12. 选择 Create(创建)

2.3.(手动)创建 Hyperdrive 配置

要为私有数据库创建 Hyperdrive 配置,创建时须指定 Access 应用和 Cloudflare Tunnel 信息。

# wrangler v3.65 and above required
npx wrangler hyperdrive create <NAME-OF-HYPERDRIVE-CONFIGURATION-FOR-DB-VIA-TUNNEL> --host=<HOSTNAME-FOR-THE-TUNNEL> --user=<USERNAME-FOR-YOUR-DATABASE> --password=<PASSWORD-FOR-YOUR-DATABASE> --database=<DATABASE-TO-CONNECT-TO> --access-client-id=<YOUR-ACCESS-CLIENT-ID> --access-client-secret=<YOUR-SERVICE-TOKEN-CLIENT-SECRET>
resource "cloudflare_hyperdrive_config"  "<TERRAFORM_VARIABLE_NAME_FOR_CONFIGURATION>" {
  account_id = "<YOUR_ACCOUNT_ID>"
  name       = "<NAME_OF_HYPERDRIVE_CONFIGURATION>"
  origin     = {
    host     = "<HOSTNAME_OF_TUNNEL>"
    database = "<NAME_OF_DATABASE>"
    user     = "<NAME_OF_DATABASE_USER>"
    password = "<DATABASE_PASSWORD>"
    scheme   = "postgres"
    access_client_id     = "<ACCESS_CLIENT_ID>"
    access_client_secret = "<ACCESS_CLIENT_SECRET>"
  }
  caching = {
    disabled = false
  }
}

这将使用常规数据库信息(数据库名称、数据库主机、数据库用户和数据库密码)创建 Hyperdrive 配置。

此外,还将设置 Service Token 的 Access Client ID 和 Access Client Secret。Hyperdrive 向 tunnel 发送请求时,Access 将拦截请求并使用 Service Token 的凭据进行验证。

3. 从 Worker 查询 Hyperdrive 配置(可选)

要测试通过 Cloudflare Tunnel 和 Access 连接到数据库的 Hyperdrive 配置,在 Worker 中使用 Hyperdrive 配置 ID 并部署。

3.1. 创建 Hyperdrive 绑定

你必须在 Wrangler 配置文件 中创建绑定,Worker 才能连接 Hyperdrive 配置。绑定(binding) 使 Worker 能够访问 Cloudflare 开发者平台上的资源(如 Hyperdrive)。

要将 Hyperdrive 配置绑定到 Worker,请在 Wrangler 文件末尾添加以下内容:

{
	"hyperdrive": [
		{
			"binding": "HYPERDRIVE",
			"id": "<YOUR_DATABASE_ID>" // the ID associated with the Hyperdrive you just created
		}
	]
}
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "<YOUR_DATABASE_ID>"

具体说明:

  • binding(绑定名称)设置的值(字符串)将在 Worker 中引用此数据库。本教程中将绑定命名为 HYPERDRIVE
  • 绑定必须是有效的 JavaScript 变量名。例如 binding = "hyperdrive"binding = "productionDB" 均为有效名称。
  • 绑定在 Worker 中可通过 env.<BINDING_NAME> 访问。

若开发时使用本地数据库,可在 Hyperdrive 配置中添加 localConnectionString,填入数据库连接字符串:

{
	"hyperdrive": [
		{
			"binding": "HYPERDRIVE",
			"id": "<YOUR_DATABASE_ID>", // the ID associated with the Hyperdrive you just created
			"localConnectionString": "<LOCAL_DATABASE_CONNECTION_URI>"
		}
	]
}
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "<YOUR_DATABASE_ID>"
localConnectionString = "<LOCAL_DATABASE_CONNECTION_URI>"

3.2. 查询数据库

验证能否从 Workers 连接到数据库并执行查询。

使用 node-postgrespg)发送测试查询以验证连接是否成功。

安装 node-postgres 驱动:

npm i pg@>8.16.3

若使用 TypeScript,安装类型包:

npm i -D @types/pg

wrangler.jsonc 中添加所需的 Node.js 兼容性标志和 Hyperdrive 绑定:

wrangler.jsonc 中添加 Node.js 兼容性标志和 Hyperdrive 绑定(binding):

{
	// required for database drivers to function
	"compatibility_flags": [
		"nodejs_compat"
	],
	// Set this to today's date
	"compatibility_date": "2026-08-17",
	"hyperdrive": [
		{
			"binding": "HYPERDRIVE",
			"id": "<your-hyperdrive-id-here>"
		}
	]
}
compatibility_flags = [ "nodejs_compat" ]
# Set this to today's date
compatibility_date = "2026-08-17"

[[hyperdrive]]
binding = "HYPERDRIVE"
id = "<your-hyperdrive-id-here>"

创建新的 Client 实例并传入 Hyperdrive connectionString

// filepath: src/index.ts
import { Client } from "pg";

export default {
	async fetch(
		request: Request,
		env: Env,
		ctx: ExecutionContext,
	): Promise<Response> {
		// Create a new client instance for each request. Hyperdrive maintains the
		// underlying database connection pool, so creating a new client is fast.
		const client = new Client({
			connectionString: env.HYPERDRIVE.connectionString,
		});

		try {
			// Connect to the database
			await client.connect();

			// Perform a simple query
			const result = await client.query("SELECT * FROM pg_tables");

			return Response.json({
				success: true,
				result: result.rows,
			});
		} catch (error: any) {
			console.error("Database error:", error.message);

			return new Response("Internal error occurred", { status: 500 });
		}
	},
};

现在,部署 Worker:

npx wrangler deploy

访问已部署 Worker 时若成功收到数据库的 pg_tables 列表,Hyperdrive 已配置为使用 Cloudflare TunnelCloudflare Access 安全连接到私有数据库。

使用 mysql2 发送测试查询以验证连接是否成功。

安装 mysql2 驱动:

npm i mysql2@>3.13.0

wrangler.jsonc 中添加所需的 Node.js 兼容性标志和 Hyperdrive 绑定:

wrangler.jsonc 中添加 Node.js 兼容性标志和 Hyperdrive 绑定(binding):

{
	// required for database drivers to function
	"compatibility_flags": [
		"nodejs_compat"
	],
	// Set this to today's date
	"compatibility_date": "2026-08-17",
	"hyperdrive": [
		{
			"binding": "HYPERDRIVE",
			"id": "<your-hyperdrive-id-here>"
		}
	]
}
compatibility_flags = [ "nodejs_compat" ]
# Set this to today's date
compatibility_date = "2026-08-17"

[[hyperdrive]]
binding = "HYPERDRIVE"
id = "<your-hyperdrive-id-here>"

创建新的 connection 实例并传入 Hyperdrive 参数:

// mysql2 v3.13.0 or later is required
import { createConnection } from "mysql2/promise";

export default {
	async fetch(request, env, ctx): Promise<Response> {
		// Create a new connection on each request. Hyperdrive maintains the underlying
		// database connection pool, so creating a new connection is fast.
		const connection = await createConnection({
			host: env.HYPERDRIVE.host,
			user: env.HYPERDRIVE.user,
			password: env.HYPERDRIVE.password,
			database: env.HYPERDRIVE.database,
			port: env.HYPERDRIVE.port,

			// Required to enable mysql2 compatibility for Workers
			disableEval: true,
		});

		try {
			// Sample query
			const [results, fields] = await connection.query("SHOW tables;");

			// Return result rows as JSON
			return Response.json({ results, fields });
		} catch (e) {
			console.error(e);
			return Response.json(
				{ error: e instanceof Error ? e.message : e },
				{ status: 500 },
			);
		}
	},
} satisfies ExportedHandler<Env>;

现在,部署 Worker:

npx wrangler deploy

访问已部署 Worker 时若成功收到数据库的表列表,Hyperdrive 已配置为使用 Cloudflare TunnelCloudflare Access 安全连接到私有数据库。

故障排除

设置通过 tunnel 连接私有数据库的 Hyperdrive 配置时若遇到问题,除 Hyperdrive 常规故障排除步骤 外,可考虑以下常见解决方案:

  • 确保数据库配置为使用 TLS (SSL)。Hyperdrive 需要 TLS (SSL) 才能连接。

这篇文档对您有帮助吗?