设置 Snowflake Connector for PostgreSQL 代理容器¶
备注
使用 Snowflake Connector for PostgreSQL 需遵守 Connector 条款。
本主题介绍设置 Snowflake Connector for PostgreSQL 代理容器的过程。数据库连接器代理是一个容器化的应用程序,运行在基础设施内部,直接连接到您的数据库和 Snowflake。
配置 Snowflake Connector for PostgreSQL 代理的过程包括以下任务:
查看先决条件并选择编排系统¶
查看并完成所有先决条件,然后继续 配置并运行代理。
选择容器编排系统¶
代理打包为标准 Docker 容器映像,可在支持该标准的任何编排系统上运行。这可以是独立的 Docker (https://www.docker.com/) 实例、Kubernetes (https://kubernetes.io/)、RedHat OpenShift (https://www.redhat.com/en/technologies/cloud-computing/openshift)、云托管解决方案(如 AWS Fargate (https://aws.amazon.com/fargate/))等。您的组织通常会有一个首选的现有系统供您使用。
请注意本文档中的代理配置部分,因为不同的编排系统会有不同的限制。您的系统或特定设置可能不允许您挂载可写卷(代理的主要配置选项要求挂载)。
后面的示例将重点介绍最流行的编排系统 Kubernetes。其他系统中的方法通常也类似,您需要根据自己的设置调整示例。
确认所需系统资源¶
代理是内存密集型应用程序,至少需要 6GB RAM 才能正常运行。
最佳 CPUs 数量为 4。更少 CPUs 会降低性能。更多 CPUs 并不会提高性能。
设置连接¶
代理需要连接到您打算从中读取数据的每个源数据库。配置您的网络和防火墙,以确保可以建立直接连接,并且可以访问 PostgreSQL 客户端端口。通常,这个端口是 5432
。有关更多信息,请参阅 PostgreSQL 的连接设置文档 (https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-PORT)。
如果您的源数据库位于隔离的网络中,且无法通过单个代理进行连接,您将需要安装额外的连接器本地应用程序实例,每个实例配备独立的代理。此功能目前处于非公开预览阶段。如需请求访问权限,请联系 Snowflake 支持部门。
该代理还直接连接到您的 Snowflake 部署。有关哪些主机名需要可用的信息,请参阅 允许主机名。
如果代理的任何连接需要经过代理服务器,您将需要为代理提供额外的配置。请参阅 查看可选的配置环境变量。
配置并运行代理¶
配置并运行代理包括以下步骤:
为代理准备代理配置 文件或环境变量,并启动代理
根据需要,设置 PrivateLink 连接
[可选] 获取并准备源数据库的 SSL 证书¶
果您打算在代理和源数据库之间使用 SSL 连接,则需要获取 PostgreSQL 实例的根证书,并将其挂载到代理容器中的 /home/agent/.postgresql/root.crt
路径下。
准备代理配置¶
代理可以通过容器挂载的 JSON 文件、环境变量或混合两者的方式进行配置。用于连接 Snowflake 的访问密钥可以从主机的文件系统挂载、作为容器机密提供,或作为环境变量提供。
以下部分介绍不同的配置选项(从最简单到最全面)。根据基础设施的具体情况选择合适的配置方式。
配置代理的最简单方法是,在运行时将两个 JSON 文件挂载到容器中:
snowflake.json
包含供代理连接到 Snowflake 账户的配置。您可以在连接器设置过程结束时,通过 Snowsight 中提供的向导下载此文件。
datasources.json
包含代理需要连接的源数据库列表。您需要自己准备这个文件。
在下载后,snowflake.json
会包含一个临时的私钥,用于代表代理的 Snowflake 服务账户。首次启动代理时,代理会自动用新的永久密钥集替换临时密钥,并将其输出到容器内的路径 /home/agent/.ssh/
下。您必须将 snowflake.json
和 /home/agent/.ssh/
下的路径挂载为可写路径,代理才能启动。
或者,您可以为代理的服务账户提供自己的私钥。有关需要传递的环境变量,请参阅 查看可选的配置环境变量。
小心
如果代理发现已有的私钥(无论是作为挂载的文件还是环境变量提供),它将忽略 snowflake.json
中可能仍存在的临时密钥。
通过复制并填写以下模板来准备 datasources.json
文件:
{
"<data_source_name_1>": {
"url": "jdbc:postgresql://<host>:<port>/<databaseName>[?<key1>=<value1>[&<key2>=<value2>]]",
"username": "<postgresql_db_username>",
"password": "<postgresql_db_password>",
"publication": "<postgresql_db_publication>",
"ssl": false
},
"<data_source_name_2>": {
"url": "jdbc:postgresql://<host>:<port>/<databaseName>[?<key1>=<value1>[&<key2>=<value2>]]",
"username": "<postgresql_db_username>",
"password": "<postgresql_db_password>",
"publication": "<postgresql_db_publication>",
"ssl": false
}
}
创建文件时:
您必须至少添加一个数据源,并指定一个 URL,否则代理将无法启动。
您可以根据需要添加多个数据源,只要代理能够直接连接到所有这些数据源即可。
您输入的数据源名称将成为以后调用连接器本地应用程序和启用复制时所需的标识符。每个数据源的名称必须是唯一的。
数据源的名称只能包含字母和数字。任何小写字母将由代理自动转换为大写字母。
如果通过将
ssl
参数设置为true
来启用 SSL 连接,您还需要将源数据库的根证书挂载到容器中。请参阅 [可选] 获取并准备源数据库的 SSL 证书。
准备好这两个 JSON 文件、一个输出新密钥集的目录,并准备好根 SSL 证书(可选)后,就可以启动容器。
docker run -d \
--restart unless-stopped \
--name database-connector-agent \
--volume </path/to/ssh/keys/directory>:/home/agent/.ssh \
--volume </path/to/snowflake.json>:/home/agent/snowflake.json \
--volume </path/to/datasources.json>:/home/agent/datasources.json \
--volume </path/to/root.crt>:/home/agent/.postgresql/root.crt \
-m 6g \
snowflakedb/database-connector-agent:latest
通过 snowflake.json
和 datasources.json
传递的配置选项也可以通过环境变量提供。
重要
环境变量优先于通过 JSON 文件提供的设置。
环境变量名称遵循与两个 JSON 文件中的路径相同的结构。嵌套的键必须用下划线 _
分隔,每个变量名必须以 SNOWFLAKE_
为前缀,数组项则以整数索引为前缀。
例如下面的脚本:
docker run \
-e SNOWFLAKE_USERNAME="POSTGRESQL_AGENT_USER" \
-e SNOWFLAKE_APPLICATION_NAME="SNOWFLAKE_CONNECTOR_FOR_POSTGRESQL" \
-e SNOWFLAKE_ALLOWLIST_0_HOST="example_account.us-west-2.aws.snowflakecomputing.cn" \
-e SNOWFLAKE_ALLOWLIST_0_PORT=443 \
-e SNOWFLAKE_ALLOWLIST_0_TYPE="SNOWFLAKE_DEPLOYMENT" \
...
等同于:
{
"userName": "POSTGRESQL_AGENT_USER",
"applicationName": "SNOWFLAKE_CONNECTOR_FOR_POSTGRESQL",
"allowlist": [
{
"host": "example_account.us-west-2.aws.snowflakecomputing.cn",
"port": 443,
"type": "SNOWFLAKE_DEPLOYMENT"
}
]
}
您不需要复制 allowList
或 allowlistPrivatelink
数组中的所有条目。只需要找到 allowList
中 type
为 SNOWFLAKE_DEPLOYMENT
的条目,并使用该 URL 来设置环境变量 SNOWFLAKE_ENFORCEDURL
,如:
docker run \
-e SNOWFLAKE_USERNAME="POSTGRESQL_AGENT_USER" \
-e SNOWFLAKE_APPLICATION_NAME="SNOWFLAKE_CONNECTOR_FOR_POSTGRESQL" \
-e SNOWFLAKE_ENFORCEDURL="example_account.us-west-2.aws.snowflakecomputing.cn:443" \
...
数据源会采用类似的结构,并以 SNOWFLAKE_DATASOURCES_
作为前缀。
例如:
docker run \
-e SNOWFLAKE_DATASOURCES_POSTGRESQLDS1_URL="jdbc:postgresql://example.internal:5432/", \
-e SNOWFLAKE_DATASOURCES_POSTGRESQLDS1_USERNAME="example_user" \
-e SNOWFLAKE_DATASOURCES_POSTGRESQLDS1_PASSWORD="example_password" \
-e SNOWFLAKE_DATASOURCES_POSTGRESQLDS1_PUBLICATION="example_publication" \
-e SNOWFLAKE_DATASOURCES_POSTGRESQLDS1_SSL="false" \
...
等同于:
{
"POSTGRESQLDS1": {
"url": "jdbc:postgresql://example.internal:5432/",
"username": "example_user",
"password": "example_password",
"publication": "example_publication",
"ssl": false
}
}
查看可选的配置环境变量¶
代理支持以下可选设置,这些设置可以通过在容器中设置额外的环境变量来启用:
SNOWFLAKE_PRIVATEKEYPATH
指定包含代理用户私钥的文件的绝对路径。当您将自己的私钥挂载到容器中时(通常通过编排系统的密钥),会使用此路径。
SNOWFLAKE_PRIVATEKEYPASSWORD
指定代理用户私钥的密码。如果您让代理生成密钥,此密码将会用于保护私钥。如果您重用现有的密钥,密码将用于访问现有的私钥。
SNOWFLAKE_PRIVATEKEY
指定代理用户私钥的内容。当无法将私钥作为文件挂载到容器中时,可以设置此选项。
SNOWFLAKE_ENFORCEDURL
指定连接 Snowflake 的 URL,覆盖代理自身的发现机制。此设置主要用于连接 PrivateLink 部署。
JAVA_OPTS
指定将传递给代理进程的附加 Java 设置或属性。
最常用的选项包括:
-Xmx
选项,用于设置最大 Java 堆大小。Snowflake 建议将此值设置为容器可用内存大小减去 1GB。例如,如果容器有 6GB 的 RAM 可用,您应该设置如下:
JAVA_OPTS=-Xmx5g
如果代理与 Snowflake 的连接需要通过代理服务器,设置如下:
JAVA_OPTS=-Dhttp.useProxy=true -Dhttp.proxyHost=<proxy-host> -Dhttp.proxyPort=<proxy-port>
要绕过某些主机或 IP 地址(例如源数据库)的代理,请设置附加的
http.nonProxyHosts
属性。使用竖线符号 (|
) 分隔多个主机名。使用星号 (*
) 作为通配符。JAVA_OPTS=-Dhttp.useProxy=true -Dhttp.proxyHost=<proxy-host> -Dhttp.proxyPort=<proxy-port> -Dhttp.nonProxyHosts='*.my_company.com|localhost|myorganization-myaccount.snowflakecomputing.cn|192.168.91.*'
要为代理传递凭据,请设置
http.proxyUser
和http.proxyPassword
系统属性。JAVA_OPTS=-Dhttp.useProxy=true -Dhttp.proxyHost=<proxy-host> -Dhttp.proxyPort=<proxy-port> -Dhttp.proxyUser=<proxy-user> -Dhttp.proxyPassword=<proxy-pass>
设置 PrivateLink 连接¶
如果您要连接到 PrivateLink 部署,必须通过设置 SNOWFLAKE_ENFORCEDURL
环境变量来显式提供代理连接的 URL。
要确定您账户的 PrivateLink URL,您可以选择以下方法之一:
打开在配置过程中获得的
snowflake.json
文件。找到名为allowlistPrivatelink
的数组,然后查找type
为SNOWFLAKE_DEPLOYMENT
的条目。
了解 Snowflake 访问密钥¶
代理通过一组访问密钥作为服务账户向 Snowflake 进行身份验证(该账户是在 Snowsight 中由连接器的设置向导创建的)。设置向导会创建临时访问密钥,并将 私 钥添加到 snowflake.json
文件中的 temporaryPrivateKey
字段。
在首次启动时,代理会通过以下步骤替换这些临时密钥:
生成一组新的访问密钥,并将其存储在容器内的
/home/agent/.ssh
目录中,文件名为database-connector-agent-app-private-key.p8
和database-connector-agent-app-public-key.pub
。这个目录应挂载为容器的外部可写卷,以便在容器关闭时密钥仍然存在。修改服务账户以使用新生成的密钥。
从
snowflake.json
文件中移除temporaryPrivateKey
字段。
初始密钥更换后,代理将不再轮换访问密钥。
您可以使用代理生成的密钥。或者您可以创建自己的密钥集、修改服务账户,然后将私钥提供给代理。
代理的私钥发现顺序如下:
使用
SNOWFLAKE_PRIVATEKEY
环境变量传递的任何密钥。如果找到了这个值,连接器将忽略snowflake.json
中的临时密钥。在挂载的卷中的
/home/agent/.ssh/database-connector-agent-app-private-key.p8
文件中找到的密钥。如果找到该文件,连接器将忽略snowflake.json
中的临时密钥。来自
snowflake.json
文件中temporaryPrivateKey
字段的值。
使用 Kubernetes 配置编排¶
备注
本部分主要介绍 Kubernetes,但连接器可以在任何容器编排系统中启动。配置语法通常相似。有关详细信息,请参阅系统的文档。
使用 Kubernetes 时,通常不会选择挂载可写卷。因此,代理将无法自动替换其 Snowflake 用户账户的密钥。您必须手动创建一组密钥,更改用户,然后将私钥提供给运行代理的容器,通常是作为挂载密钥。有关为 Snowflake 用户设置密钥对的详细信息,请参阅 配置密钥对身份验证。
我们建议您将密钥存储在安全的存储库中,例如 HashiCorp Vault。这些存储库通常已与 Kubernetes 集成,例如,Vault 提供专门的运算符 (https://developer.hashicorp.com/vault/tutorials/kubernetes/vault-secrets-operator)。集成详细信息将根据容器编排系统和安全存储库的具体情况而定。有关详细信息,请参阅其各自的文档。
Kubernetes 通常在多节点集群中运行,无法从主机挂载文件。为了向代理的容器提供配置 JSON 文件,您可以创建一个 Kubernetes ConfigMap (https://kubernetes.io/docs/concepts/configuration/configmap/) 来存储这三个文件。
以下是在 Kubernetes 中配置代理的基本示例。
创建一个 ConfigMap,用于存储
snowflake.json
和 SSL 根证书(可选):kubectl create configmap database-connector-config \ --from-file=snowflake.json=</path/to/snowflake.json> \ --from-file=root.crt=</path/to/root.crt>
创建一个密钥,用于存储代理用户的私钥和
datasources.json
的内容:kubectl create secret generic database-connector-secrets \ --from-file=private-key=</path/to/private/key/file> \ --from-file=datasources.json=</path/to/datasources.json>
配置代理的 Pod,将配置文件和私钥挂载为卷:
apiVersion: v1 kind: Pod metadata: name: database-connector-agent spec: restartPolicy: Always containers: - name: database-connector-agent image: snowflakedb/database-connector-agent:latest resources: requests: memory: "6Gi" limits: memory: "8Gi" volumeMounts: - name: config mountPath: /home/agent/snowflake.json subPath: snowflake.json - name: config mountPath: /home/agent/.postgresql/root.crt subPath: root.crt - name: secrets mountPath: /home/agent/datasources.json subPath: datasources.json - name: secrets mountPath: /etc/private-key/private-key subPath: private-key env: - name: SNOWFLAKE_PRIVATEKEYPATH value: /etc/private-key/private-key volumes: - name: config configMap: name: database-connector-config - name: secrets secret: secretName: database-connector-secrets
将 Pod 的配置另存为 YAML 文件,例如
database-connector.yaml
,然后启动:kubectl apply -f database-connector.yaml
监视代理¶
代理的容器将日志输出到 stdout
,可以通过 Docker 访问这些日志。例如,如果容器名称为 database-connector-agent
,则用于查看日志的命令将为:
docker container logs database-connector-agent
这些日志也会流式传输到 Snowflake。有关如何访问这些日志的详细信息,请参阅 监控 Snowflake Connector for PostgreSQL。
访问运行状况检查端点¶
代理会公开一个包含运行状况信息的 HTTP 端点。在编排系统中运行代理时,您可以使用此端点来确定代理何时完全启动以及它是否正常。该端点的端口为 8080
,路径为 /actuator/health
。
若要将该端点用作 Kubernetes 的活动探针,请将以下内容添加到 Pod 配置:
apiVersion: v1
kind: Pod
spec:
containers:
- ...
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
后续步骤¶
完成以上过程后,请按照 为 Snowflake Connector for PostgreSQL 配置复制 中的步骤操作。