Snowflake DCP 私有数据接入指南
DataHot 速览
本文介绍 Snowflake 为 Openflow 推出的 Data Connectivity Proxy(DCP)部署方式。DCP 是部署在客户自有网络内的轻量容器化代理,通过单一出站 443 端口与 Snowflake 代理端点建立 HTTPS 隧道,使 Openflow 连接器可接入防火墙后、私有子网乃至本地部署的数据库、API 和 Kafka。该方案无需入站防火墙规则、公网 IP 或 PrivateLink 基础设施,且 Enterprise 版客户无需升级到 Business Critical 即可实现私有连接。
为什么值得关注:对需要把本地或私有 VPC 数据接入云数仓的数据团队而言,本文给出了免入站端口、十几分钟即可完成部署的私有连通方案,直接影响数据集成架构与合规设计。
本文目录 37 节
- 为 Openflow 部署 Snowflake 数据连接代理 (DCP) 的指南。
- 支持的用例
- 架构
- 前提条件
- Snowflake 账户
- 网络(客户侧)
- 基础设施(DCP 主机)
- 数据源
- 分步设置指南
- A 部分:Snowflake 侧配置
- 步骤 1 — 创建网络规则
- 步骤 2 — 创建外部访问集成 (EAI)
- 步骤 3 — 创建 DCP 代理对象
- 第 4 步 — 为你的账户启用 snowflake.com 子域名的 TLS 证书
- 第 5 步 — 生成 Bootstrap Token(JWT)
- Part B:在 Linux EC2 上部署 DCP Proxy(Docker)
- 第 1 步 — 安装 Docker(如果尚未安装)
- 第 2 步 — 存储 Bootstrap Token
- 第 3 步 — 启动 DCP Proxy
- 第 4 步 — 验证连接
- 第 5 步 — 验证 Proxy 健康状况
- 第 6 步 — 配置 Openflow 以使用隧道
- 使用当前设置添加新的数据源
- 第 1 步:为你的目标添加 DNS 条目
- 第 2 步:修改网络规则以包含新数据源
- 第 3 步:添加/配置新连接器
- 数据摄取验证 (Snowflake 侧)
- 保持隧道健康:Bootstrap Token 卫生
- 日志记录与监控
- 需要关注的关键指标
- —— —— 1. 整体健康状况:每分钟事件数及错误/警告计数
- —— —— 2. 最近的错误(如有)
- —— —— 3. DCP 隧道 / 代理连接性
- —— —— 4. 运行时心跳(确认运行时处于存活状态)
- Docker 日志
- 结论
- 额外福利:致 Kubernetes 爱好者
译文
AI 逐段翻译为 Openflow 部署 Snowflake 数据连接代理 (DCP) 的指南。
如果你能让 Openflow 访问你的数据库——那些位于防火墙之后、私有子网中,甚至本地部署的数据库——而无需在网络边界安全上打开任何一个(入站)端口,会怎么样?
没有入站防火墙规则。没有入站安全组条目。没有公网 IP (针对私有数据源)。无需构建 PrivateLink 基础设施。只需一个容器、一个令牌,以及不到十五分钟的设置时间。
这正是数据连接代理 (DCP) 所做的。
DCP 是一个轻量级、容器化的代理,部署在你自己的网络内部。与 Snowflake 主动接入你的环境(传统连接模型配合 SPCS 和 PrivateLink 的工作方式)不同,DCP 颠覆了这一模式:你的代理通过单个出站端口 (443) 主动连接 Snowflake 的代理端点,建立安全的 HTTPS 隧道。一旦该安全隧道建立,Snowflake 的 Openflow 连接器就可以从你的私有数据源——数据库、API、Kafka broker——摄取数据,就像它们在同一网络上一样。
DCP 负责建立安全网络路径,而特定于连接器的协议处理仍留在连接器内部;客户端代理与连接器类型无关,仅以 TCP 级别的透传方式转发流量。
而以下这一点将改变游戏规则: Snowflake Enterprise 客户现在可以从 Openflow 建立到其私有数据源的私有连接——无需仅仅为了解锁 PrivateLink 而升级到 Business Critical 版本。
支持的用例
在深入了解 DCP 工作原理之前,先看看它在哪些场景下表现出色:
- 位于企业防火墙后的本地数据库 → 仅出站模式意味着本地零入站规则;DCP 代理可运行在任何可联网的 Linux 主机上。
- 无入站互联网访问的云 VPC → DCP 代理部署在同一 VPC 中;只需出站 443 连接到 Snowflake。
- 监管/合规:数据必须留在客户网络边界内 → DCP 通过隧道中继加密流量——你的数据绝不会经过不受控的路径。
- 通过单一集成实现多源连接 → 一个 DCP 代理对象 + 一个 EAI 即可覆盖多个 host:port 条目。
- 快速开发/测试连接 → 基于 JWT 的引导意味着几分钟即可完成设置;通过禁用代理对象即可拆除。
- 需要私有连接的 Enterprise 版本账户 → PrivateLink 需要 Business Critical——而 DCP 在 Standard、Enterprise 和 Business Critical 上均可使用。
架构
在这篇博文中,我将基于以下架构逐步介绍设置 DCP 的步骤;

前提条件
在开始之前,请核实以下四个方面:
Snowflake 账户
- 版本: Standard、Enterprise 或 Business Critical
- 权限: 创建 DCP 对象的角色需要在账户上具有 CREATE DATA CONNECTIVITY PROXY 权限(使用 ACCOUNTADMIN 角色)
网络(客户侧)
运行 DCP 代理的机器必须能够通过 443 端口出站访问以下 Snowflake 端点:
注意: 代理使用标准公共 DNS 解析 Snowflake 端点主机名。不要将这些名称覆盖为 PrivateLink 主机名或 PrivateLink IP 地址。不支持通过 PrivateLink 端点连接 DCP 代理。
- dcp.myorg-myaccount.us-east-1.aws.snowflake.com — 主控制平面
- dcp-proxy.myorg-myaccount.us-east-1.aws.snowflake.com — 中继(数据路径)
- dcp-proxy-fallback.myorg-myaccount.us-east-1.aws.snowflake.com — 回退路径。
(三者均为通过 443 端口的仅出站连接。无需打开入站防火墙端口)。
基础设施(DCP 主机)
注意: DCP 可以使用 Docker 或 Kubernetes 进行部署/配置。在这篇博文中,我使用 Docker 部署 DCP。
- 一台能够访问你的数据源的 Linux EC2 实例(或任何 Linux 主机)。
- DCP 代理容器应至少具有 1 个 vCPU 和 512MB 内存。
- 已安装并运行 Docker(DCP 代理镜像为 snowflakedb/dcp-client:latest)。
- DCP 代理主机必须能够解析你的数据源的私有 DNS 名称。
数据源
- DCP 主机必须能够通过其标准端口访问数据源(使用 nc -zv <host> <port> 验证)。
- 你需要确切的 DNS 主机名和端口(例如,database-1.ckruivapkcw1.us-east-1.rds.amazonaws.com:5432)。
分步设置指南
注意: 这篇博文不涵盖 Openflow 部署步骤——它假设 Openflow 部署和运行时已配置了适当的角色和权限。有关设置详情,请参阅 Snowflake Openflow 文档。
本节分两部分引导你完成完整部署:首先是 Snowflake 侧的配置,然后是在你的 EC2 实例上部署 DCP 代理。
A 部分:Snowflake 侧配置
这些步骤创建定义你的 DCP 集成的 Snowflake 对象。请使用具有 CREATE DATA CONNECTIVITY PROXY 权限的角色按顺序运行它们。
步骤 1 — 创建网络规则
网络规则告诉 Snowflake 你的 Openflow 连接器可以通过 DCP 隧道访问哪些私有目标。
CREATE NETWORK RULE IF NOT EXISTS DCP_TEST_NETWORK_RULE
MODE = DATA_CONNECTIVITY_PROXY_EGRESS
TYPE = HOST_PORT
VALUE_LIST =
('database-1.ckruivapkcw1.us-east-1.rds.amazonaws.com:5432');--Private FQDN
of my RDS PostGreSQL instance.提示: 如果你需要通过同一隧道访问多个数据源,可以用逗号分隔列出多个 host:port 条目。仅支持 DNS 名称——VALUE_LIST 中不接受原始 IP 地址。
步骤 2 — 创建外部访问集成 (EAI)
EAI 将你的网络规则打包成一个集成,并附加到 Openflow 运行时。
CREATE EXTERNAL ACCESS INTEGRATION IF NOT EXISTS DCP_TEST_EAI
ALLOWED_NETWORK_RULES = (DCP_TEST_NETWORK_RULE)
ENABLED = TRUE;将 EAI 与 Openflow 运行时关联所需的 RBAC:将 DCP 外部访问集成的 USAGE 权限授予与运行时关联的 execute-as 角色:
GRANT USAGE ON INTEGRATION DCP_TEST_EAI TO ROLE OPENFLOW_<RUNTIME_NAME>_EXECUTE_AS_RL;注意: 这些角色会在 Openflow 部署过程中配置。有关 RBAC 设置详情,请参阅 Snowflake Openflow 文档。
要允许用户将 DCP 外部访问集成与运行时关联,请将 USAGE 权限授予用户用于创建或更新运行时的角色:
GRANT USAGE ON INTEGRATION DCP_TEST_EAI TO ROLE <OPENFLOW_ADMIN>;步骤 3 — 创建 DCP 代理对象
此对象告知 Snowflake 控制平面将有一个 DCP 代理为此账户注册。
CREATE DATA CONNECTIVITY PROXY IF NOT EXISTS DCP_TEST
EXTERNAL_ACCESS_INTEGRATIONS = (DCP_TEST_EAI)
ENABLED = TRUE;验证其已创建:
SHOW DATA CONNECTIVITY PROXIES LIKE 'DCP_TEST';
如果由于某种原因,你在上述 SQL 的输出中没有看到 enable “true”,请运行以下命令;
ALTER DATA CONNECTIVITY PROXY DCP_TEST SET ENABLED = TRUE;第 4 步 — 为你的账户启用 snowflake.com 子域名的 TLS 证书
SELECT SYSTEM$ISSUE_PER_ACCOUNT_CERTIFICATES();这将为在你的 Snowflake 账户中运行的服务(例如 DCP 控制平面)启用 TLS 证书的生成和轮换。
注意:调用成功会返回 Certificates will be issued. Issuance is asynchronous. 在账户中首次调用后,至少等待 30 分钟再启动 agent。再次调用该函数不会有额外效果。
第 5 步 — 生成 Bootstrap Token(JWT)
bootstrap JWT 是一种短期凭证,仅用于初始的 mTLS 证书握手。在 DCP proxy 完成引导后,所有后续隧道认证都使用由 Snowflake 管理的 mTLS 证书(自动轮换)。
立即复制该 token 值——它仅显示一次。在 Part B 中部署 DCP proxy 时你会需要它。
重要: 不接受以 PAT_(Personal Access Tokens)开头的 token 格式。这必须是通过运行以下 SQL 专门生成的 Snowflake Access JWT;
SELECT SYSTEM$GENERATE_DATA_CONNECTIVITY_PROXY_BOOTSTRAP_TOKEN('DCP_TEST', 90);
--Maximum validity is 90 days (7 days recommended)Part B:在 Linux EC2 上部署 DCP Proxy(Docker)
现在 Snowflake 侧已准备就绪,让我们在 EC2 实例上部署 DCP proxy。
第 1 步 — 安装 Docker(如果尚未安装)
Amazon Linux 2 / RHEL
sudo yum install -y docker
sudo systemctl start docker
sudo systemctl enable docker第 2 步 — 存储 Bootstrap Token
创建 secrets 目录,并写入你之前从 Part A 复制的 JWT。
sudo mkdir -p /etc/dcp-agent/secrets将 JWT 值粘贴到引号之间;
echo "yJraWQiOiI1OTMxNDc4NzQ3NTA0NzAiL….." | sudo tee /etc/dcp-agent/secrets/dcp-bootstrap-token > /dev/nullagent 在启动时以及证书轮换期间读取此文件。agent 在每次证书轮换周期都会重新读取此文件。你可以在不重启 agent 的情况下更新该 token
sudo chmod 600 /etc/dcp-agent/secrets/dcp-bootstrap-token注意: 在生产环境中,请将 JWT token 存储在密钥管理器中,例如 AWS Secrets Manager、Microsoft Azure Key Vault、Google Cloud Secret Manager 或 HashiCorp Vault,然后将其写入 agent 挂载的 credentials 路径。请参阅 data-connectivity-proxy-setup
第 3 步 — 启动 DCP Proxy
docker run -d \
--name snowflake-dcp-agent \
--restart unless-stopped \
--add-host database-1.ckruivapkcw1.us-east-1.rds.amazonaws.com:172.16.92.88 \
-v /etc/dcp-agent/secrets:/etc/dcp-agent/secrets:ro \
-p 9092:9092 \
snowflakedb/dcp-client:latest \
--sf-bootstrap-credentials /etc/dcp-agent/secrets/dcp-bootstrap-token \
--metrics-addr 0.0.0.0:9092提示: --add-host 标志会将 DNS 映射直接注入容器的 /etc/hosts,当主机级别的 /etc/hosts 条目未被 Docker 继承时,这非常有用。你可以使用任一方式——主机级别或 --add-host——但不要两者都跳过。
验证新添加的 DNS 条目已生效:
getent hosts database-1.ckruivapkcw1.us-east-1.rds.amazonaws.com注意: 请使用 getent hosts 而不是 nslookup——后者仅查询 DNS 服务器,无法看到 /etc/hosts 条目。
DCP proxy 将:
- 读取 bootstrap JWT。
- 通过 443 端口连接到 dcp.myorg-myaccount.region.cloud.snowflake.com。
- 完成 mTLS 证书握手。
- 建立安全隧道并开始监听 Openflow 流量。
第 4 步 — 验证连接
运行这些检查,以确认你的 DCP proxy 在你的 Snowflake 账户中运行正常;
DESCRIBE DATA CONNECTIVITY PROXY DCP_TEST;
DESCRIBE DATA CONNECTIVITY PROXY "DCP_TEST";
第 5 步 — 验证 Proxy 健康状况
运行这些检查,以确认你的 DCP proxy 在 DCP 上运行正常;
- 检查 1: Bootstrap JWT 已加载
curl -s http://localhost:9092/metrics | grep dcp_agent_bootstrap_jwt_expires_at_seconds
--Expected: non-zero Unix timestamp in the future- 检查 2: 验证 DCP proxy 主机可以访问你的数据源
nc -zv database-1.ckruivapkcw1.us-east-1.rds.amazonaws.com 5432
--Expected: "open" or "succeeded" 第 6 步 — 配置 Openflow 以使用隧道
1. 在 Openflow UI 中,将 DCP_TEST_EAI 分配给你托管连接器的 Openflow Runtime。

2. 在创建/编辑连接器时,将主机设置为纯 DNS 名称和端口,例如 database-1.ckruivapkcw1.us-east-1.rds.amazonaws.com 以及端口设置为 5432 —— Snowflake 会透明地将流量路由到 DCP 隧道。

使用当前设置添加新的数据源
现在我们将向当前的数据摄取设置中添加另一个数据源,它是一个运行在不同 VPC 中 EC2 VM 上的 PostgreSQL 数据库实例,如下图所示;

注意: 创建能与原始架构实现 IP 可达性的新 VPC 超出了本篇博客文章的范围。如果你的额外数据源位于部署 DCP 的 VPC 之外,你应联系你的云网络团队。
第 1 步:为你的目标添加 DNS 条目
将新数据源添加到 DCP proxy 主机上的 /etc/hosts 以进行名称解析(就像第一个数据源一样):
echo "172.16.2.49 ip-172-16-2-49.ec2.internal" | sudo tee -a /etc/hosts验证新添加的 DNS 条目已生效:
getent hosts ip-172-16-2-49.ec2.internal注意: 请使用 getent hosts 而不是 nslookup——后者仅查询 DNS 服务器,无法看到 /etc/hosts 条目。
第 2 步:修改网络规则以包含新数据源
在你的 Snowflake 账户中,修改当前网络规则,将新数据源添加到 VALUE_LIST:
ALTER NETWORK RULE DCP_TEST_NETWORK_RULE
SET VALUE_LIST = ('database-1.ckruivapkcw1.us-east-1.rds.amazonaws.com:5432',
'ip-172-16-2-49.ec2.internal:5432');---Private FQDNs第 3 步:添加/配置新连接器
在 Openflow UI 中,创建一个指向 ip-172–16–2–49.ec2.internal:5432(我的 PostgreSQL EC2 实例的私有 FQDN)的新连接器。由于它位于已附加 EAI 的同一 runtime 中,因此无需额外的基础设施更改。测试连接后即可完成。

数据摄取验证 (Snowflake 侧)
注意: PostgreSQL 连接器的连接器配置超出了本篇博客文章的范围。有关设置指南,请参阅 snowflake 文档。
现在连接器能够与两个 PostgreSQL 实例建立 TCP 握手和 JDBC 连接。

或者,你可以在你的 Snowflake 账户中运行此 SQL 进行验证;
SELECT COUNT(*) as row_count,
MIN("_SNOWFLAKE_INSERTED_AT") as earliest_insert,
MAX("_SNOWFLAKE_INSERTED_AT") as latest_insert
FROM postgres."tpcds"."customer";---Destination schema.table
保持隧道健康:Bootstrap Token 卫生
bootstrap JWT 具有有限的生命周期(我将其设置为 90 天)。轮换是无缝的——无需重启 DCP proxy。
SELECT SYSTEM$GENERATE_DATA_CONNECTIVITY_PROXY_BOOTSTRAP_TOKEN('DCP_TEST', 90);覆盖 EC2 主机上的 token 文件:
echo "eypKVGxOVVFVeE1JbjFkIiwidHlw...." | sudo tee /etc/dcp-agent/secrets/dcp-bootstrap-token > /dev/null
sudo chmod 600 /etc/dcp-agent/secrets/dcp-bootstrap-tokenDCP proxy 会在下一个证书续期周期获取新的 token。无需重启 docker。正在进行的隧道使用 mTLS 证书,而不是 JWT——因此轮换期间零停机。
建议的轮换频率: 每 7 天一次,或者如果你怀疑 JWT 已泄露,则立即轮换。
如果 token 在轮换前过期: agent 会继续使用其现有证书运行,直到控制平面指示的下一次轮换,届时轮换将失败并发出警告。不会断开任何活动连接。替换文件,下一个轮换周期就会成功。
日志记录与监控
DCP proxy 不是黑盒。它暴露了一个 /metrics 端点(Prometheus 格式,默认端口 9092),让你可以全面了解隧道状态、连接健康状况和 token 过期情况——可直接从你已在使用的任何监控工具中抓取。
需要关注的关键指标
- 隧道是否已启动?
agent_proxy_dial_path_used_total 按路径(direct/fallback)和结果(ok/error)标记的尝试次数
- 数据在流动吗?
agent_connections_active — 当前活跃的隧道连接数
agent_connections_total — 自启动以来的累计连接数
agent_destination_errors_total——连接到你的数据源失败的次数(认证问题、端口关闭等)
- 性能如何?
agent_handshake_duration_seconds — mTLS 握手延迟
agent_destination_connect_seconds — 通过隧道到达你的数据源所需的时间
- 信任链是否健康?
dcp_agent_bootstrap_jwt_expires_at_seconds — 你的 JWT 何时过期(提前 7 天告警)
agent_cert_rotation_total — 证书续期次数——确认 Snowflake 托管的 mTLS 正在按预期轮换
你还可以使用以下关键的 Snowflake 侧监控查询来了解 DCP 性能和指标等。
—— —— 1. 整体健康状况:每分钟事件数及错误/警告计数
SELECT
DATE_TRUNC('minute', TIMESTAMP) as time_bucket,
COUNT(*) as event_count,
COUNT(CASE WHEN RECORD:severity_text::STRING = 'ERROR' THEN 1 END) as errors,
COUNT(CASE WHEN RECORD:severity_text::STRING = 'WARN' THEN 1 END) as warnings
FROM OPENFLOW_SPCS.OPENFLOW.EVENTS -----Your Event Table Full Path
WHERE TIMESTAMP >= DATEADD(hour, -1, CURRENT_TIMESTAMP())
GROUP BY 1
ORDER BY 1 DESC;
—— —— 2. 最近的错误(如有)
SELECT TIMESTAMP,
SUBSTR(VALUE::STRING, 1, 500) as message
FROM OPENFLOW_SPCS.OPENFLOW.EVENTS-----Your Event Table Full Path
WHERE RECORD:severity_text::STRING = 'ERROR'
AND TIMESTAMP >= DATEADD(hour, -1, CURRENT_TIMESTAMP())
ORDER BY TIMESTAMP DESC
LIMIT 10;—— —— 3. DCP 隧道 / 代理连接性
SELECT TIMESTAMP,
SUBSTR(VALUE::STRING, 1, 400) as message
FROM OPENFLOW_SPCS.OPENFLOW.EVENTS---Your Event Table Full Path
WHERE TIMESTAMP >= DATEADD(hour, -1, CURRENT_TIMESTAMP())
AND (VALUE::STRING ILIKE '%egress%'
OR VALUE::STRING ILIKE '%proxy%'
OR VALUE::STRING ILIKE '%SocketTimeout%'
OR VALUE::STRING ILIKE '%ConnectionException%')
ORDER BY TIMESTAMP DESC
LIMIT 10;
—— —— 4. 运行时心跳(确认运行时处于存活状态)
SELECT TIMESTAMP,
SUBSTR(VALUE::STRING, 1, 200) as message
FROM OPENFLOW_SPCS.OPENFLOW.EVENTS -----Your Event Table Full Path
WHERE VALUE::STRING ILIKE '%Heartbeat%'
AND TIMESTAMP >= DATEADD(minute, -5, CURRENT_TIMESTAMP())
ORDER BY TIMESTAMP DESC
LIMIT 5;
Docker 日志
由于 DCP 代理镜像采用 distroless(容器内没有 shell),所有诊断输出都会进入标准 Docker 日志:
docker logs snowflake-dcp-agent --tail 100这是你排查启动问题、凭据错误或连接故障的第一站。
结论
Data Connectivity Proxy 代表了 Snowflake 连接私有数据方式的一次转变。你的私有数据源保持私有——DCP 代理向外拨号连接到 Snowflake,因此无需入站端口、无需公有 IP,也不会暴露你的内部基础设施。—— DCP 让你的网络按照自己的条件向外建立连接。
对于在零信任策略下运营、管理本地数据库或运行在 Snowflake Enterprise Edition 上的团队来说,DCP 消除了历来使私有数据源摄取成为一个耗时数周的基础设施项目的连接障碍。取而代之的是,你只需不到十五分钟的容器部署,以及一条安全、自动轮换的 mTLS 隧道,一切就此顺畅运行。
DCP 代理体量小,设置是线性的,其安全模型专为你不可避免要与信息安全团队进行的对话而构建:仅出站、双向认证、加密,并且对你的网络内部而言对 Snowflake 完全不透明。
如果你的数据源是私有的,而你的安全态势又不会妥协——DCP 就是你毫无妥协地连接两者的方式。
额外福利:致 Kubernetes 爱好者
更喜欢用 Pod 而不是 docker run?我们已为你准备好。
如果你的环境运行 Kubernetes,你可以将 DCP 代理部署为一个 Deployment,并在不同的故障域中设置 replicas: 2(或更多)以实现故障转移覆盖。
注意:当某个代理发生故障时,它正在处理的隧道会中断,工作负载的 TCP 连接会被拆除——DCP 不会保护应用程序免受这种重置的影响,因此请确保你的连接器配置了重连逻辑
以下是一个参考示例:
apiVersion: v1
kind: Secret
metadata:
name: dcp-bootstrap-secret
type: Opaque
data:
dcp-bootstrap-token: <base64-encoded-jwt>
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: snowflake-dcp-agent
spec:
replicas: 2
selector:
matchLabels:
app: snowflake-dcp-agent
template:
metadata:
labels:
app: snowflake-dcp-agent
spec:
containers:
- name: dcp-agent
image: snowflakedb/dcp-client:latest
ports:
- containerPort: 9092
env:
- name: DCP_METRICS_PORT
value: "9092"
volumeMounts:
- name: dcp-secret
mountPath: /etc/dcp-agent/secrets/dcp-bootstrap-token
subPath: dcp-bootstrap-token
readOnly: true
volumes:
- name: dcp-secret
secret:
secretName: dcp-bootstrap-secret私有数据,公有云——毫无妥协 最初发布于 Snowflake Builders Blog: Data Engineers, App Developers, AI, & Data Science 于 Medium,人们在那里通过高亮和回应这个故事来继续对话。
这篇内容对你有用吗?
反馈只用于改善内容筛选,不等同于收藏