跳至主要内容

GCP 私有服务连接

私有服务连接

私有服务连接 (PSC) 是 Google Cloud 网络功能,允许消费者在其虚拟私有云 (VPC) 网络内私下访问托管服务。类似地,它允许托管服务提供商在其自己的独立 VPC 网络中托管这些服务,并为其消费者提供私有连接。

服务提供商通过创建私有服务连接服务将其应用程序发布给消费者。服务消费者通过以下私有服务连接类型之一直接访问这些私有服务连接服务。

Overview of PSC

信息

默认情况下,即使 PSC 连接已获批准并建立,ClickHouse 服务也无法通过私有服务连接访问;您需要在实例级别通过完成步骤显式添加 PSC ID 到允许列表。

注意

GCP 私有服务连接只能在 ClickHouse Cloud 生产服务上启用

不支持跨区域连接。生产者和消费者区域应相同。如果您在 PSC 级别启用全局访问,则可以从 VPC 中的其他区域进行连接(请参见下文)。

该过程分为四个步骤

  1. 获取 GCP 私有服务连接的服务附件。
  2. 创建服务端点。
  3. 将端点 ID 添加到 ClickHouse Cloud 组织。
  4. 将端点 ID 添加到服务允许列表。
注意

在下面的示例中,我们将使用

  • GCP 区域:us-central1
  • GCP 项目(客户 GCP 项目):my-gcp-project
  • 客户 GCP 项目中的 GCP 私有 IP 地址:10.128.0.2
  • 客户 GCP 项目中的 GCP VPC:default

以下提供了代码示例,以说明如何在 ClickHouse Cloud 服务中设置私有服务连接。

开始之前

您需要检索有关 ClickHouse Cloud 服务的信息。您可以通过 ClickHouse Cloud 控制台或 ClickHouse API 执行此操作。如果您要使用 ClickHouse API,请在继续之前设置以下环境变量

export REGION=us-central1
export PROVIDER=gcp
export KEY_ID=<Key ID>
export KEY_SECRET=<Key secret>
export ORG_ID=<ClickHouse organization ID>
export INSTANCE_ID=$(curl --silent --user ${KEY_ID:?}:${KEY_SECRET:?} "https://api.clickhouse.cloud/v1/organizations/${ORG_ID:?}/services" | jq ".result[] | select (.region==\"${REGION:?}\" and .provider==\"${PROVIDER:?}\") | .id " -r | head -1)
注意
  • 您可以从 ClickHouse 控制台(组织 -> 组织详细信息)检索您的组织 ID。
  • 您可以创建新的密钥或使用现有密钥。

获取 GCP 私有服务连接的服务附件和 DNS 名称

选项 1:ClickHouse Cloud 控制台

在 ClickHouse Cloud 控制台中,打开您希望通过私有服务连接连接的服务,然后打开“设置”菜单。单击“设置私有端点”按钮。记下“服务名称”(endpointServiceId)和“DNS 名称”(privateDnsHostname)。您将在后续步骤中使用它们。

Private Endpoints

选项 2:API

注意

您需要在该区域部署至少一个实例才能执行此步骤。

获取 GCP 私有服务连接的服务附件和 DNS 名称

curl --silent --user ${KEY_ID:?}:${KEY_SECRET:?} "https://api.clickhouse.cloud/v1/organizations/${ORG_ID:?}/services/${INSTANCE_ID:?}/privateEndpointConfig" | jq  .result 
{
"endpointServiceId": "projects/.../regions/us-central1/serviceAttachments/production-us-central1-clickhouse-cloud",
"privateDnsHostname": "xb164akwxw.us-central1.p.gcp.clickhouse.cloud"
}

记下endpointServiceIdprivateDnsHostname。您将在后续步骤中使用它们。

创建服务端点

在本节中,我们将创建一个服务端点。

添加私有服务连接

首先,我们将创建一个私有服务连接。

选项 1:使用 Google Cloud 控制台

在 Google Cloud 控制台中,导航到“网络服务 -> 私有服务连接”。

Open PSC

通过单击“连接端点”按钮打开私有服务连接创建对话框。

  • **目标**:使用“已发布服务”
  • **目标服务**:使用来自获取 GCP 私有服务连接的服务附件步骤的“endpointServiceId”。
  • **端点名称**:为 PSC “端点名称”设置一个名称。
  • **网络/子网/IP 地址**:选择要用于连接的网络。您需要为私有服务连接端点创建一个 IP 地址或使用现有 IP 地址。在我们的示例中,我们预先创建了一个名为“your-ip-address”的地址并分配了 IP 地址10.128.0.2
  • 要使端点可从任何区域访问,您可以启用“启用全局访问”复选框。

Enable Global Access

要创建 PSC 端点,请使用“添加端点”按钮。

连接获得批准后,“状态”列将从“待处理”更改为“已接受”。

Accepted

复制“PSC 连接 ID”,我们将在后续步骤中将其用作“端点 ID”。

选项 2:使用 Terraform

provider "google" {
project = "my-gcp-project"
region = "us-central1"
}

variable "region" {
type = string
default = "us-central1"
}

variable "subnetwork" {
type = string
default = "https://www.googleapis.com/compute/v1/projects/my-gcp-project/regions/us-central1/subnetworks/default"
}

variable "network" {
type = string
default = "https://www.googleapis.com/compute/v1/projects/my-gcp-project/global/networks/default"
}

resource "google_compute_address" "psc_endpoint_ip" {
address = "10.128.0.2"
address_type = "INTERNAL"
name = "your-ip-address"
purpose = "GCE_ENDPOINT"
region = var.region
subnetwork = var.subnetwork
}

resource "google_compute_forwarding_rule" "clickhouse_cloud_psc" {
ip_address = google_compute_address.psc_endpoint_ip.self_link
name = "ch-cloud-${var.region}"
network = var.network
region = var.region
load_balancing_scheme = ""
# service attachment
target = "https://www.googleapis.com/compute/v1/$TARGET" # See below in notes
}

output "psc_connection_id" {
value = google_compute_forwarding_rule.clickhouse_cloud_psc.psc_connection_id
description = "Add GCP PSC Connection ID to allow list on instance level."
}
注意

TARGET - 使用来自获取 GCP 私有服务连接的服务附件步骤的“endpointServiceId”

设置 DNS

提供了两种选项,使用 Google Cloud 控制台和使用gcloud CLI。

选项 1:使用 Google Cloud 控制台

  • 从“支持的区域”创建私有 DNS 区域。
  • 打开“网络服务 -> Cloud DNS”。
  • 选择“创建区域”。

Create Zone

在“区域类型”对话框中,设置

  • 区域类型:**私有**
  • 区域名称:输入合适的区域名称。
  • DNS 名称:使用您所在区域的“支持的区域”表中的“私有 DNS 域名”列。
  • 网络:将 DNS 区域连接到您计划使用 PSC 连接到 ClickHouse Cloud 的网络。

Zone Type

在私有 DNS 区域中创建 DNS 记录

将其指向在添加私有服务连接步骤中创建的 IP 地址

DNS Record

选项 2:使用gcloud CLI

创建 DNS 区域

gcloud dns \
--project=my-gcp-project \
managed-zones create ch-cloud-us-central1 \
--description="Private DNS zone for PSC" \
--dns-name="us-central1.p.gcp.clickhouse.cloud." \
--visibility="private" \
--networks="https://www.googleapis.com/compute/v1/projects/my-gcp-project/global/networks/default"

创建 DNS 记录

gcloud dns \
--project=my-gcp-project \
record-sets create $DNS_RECORD \
--zone="ch-cloud-us-central1" \
--type="A" \
--ttl="300" \
--rrdatas="10.128.0.2"
注意

DNS_RECORD - 使用来自获取 GCP 私有服务连接的服务附件步骤的“privateDnsHostname”。

选项 3:使用 Terraform

variable "ch_dns_record" {
type = string
default = "$DNS_NAME" # See below in notes
}

resource "google_dns_managed_zone" "clickhouse_cloud_private_service_connect" {
description = "Private DNS zone for accessing ClickHouse Cloud using Private Service Connect"
dns_name = "${var.region}.p.gcp.clickhouse.cloud."
force_destroy = false
name = "clickhouse-cloud-private-service-connect-${var.region}"
visibility = "private"
}

resource "google_dns_record_set" "psc_dns_record" {
managed_zone = google_dns_managed_zone.clickhouse_cloud_private_service_connect.name
name = "${var.ch_dns_record}"
type = "A"
rrdatas = [google_compute_address.psc_endpoint_ip.address]
}
注意

DNS_NAME - 使用 获取 GCP 服务附件以用于私有服务连接 步骤中的 **privateDnsHostname**

验证 DNS 设置

DNS_RECORD - 使用 获取 GCP 服务附件以用于私有服务连接 步骤中的 **privateDnsHostname**

ping $DNS_RECORD

将端点 ID 添加到 ClickHouse Cloud 组织

选项 1:ClickHouse Cloud 控制台

要将端点添加到您的组织,请继续执行 将端点 ID 添加到服务允许列表 步骤。使用 ClickHouse Cloud 控制台将 PSC 连接 ID 添加到服务允许列表会自动将其添加到组织。

要删除端点,请打开 **组织详细信息 -> 私有端点** 并单击删除按钮以删除端点。

endpoints

选项 2:API

在运行任何命令之前,请设置这些环境变量

将下面的 ENDPOINT_ID 替换为 添加私有服务连接 步骤中 **端点 ID** 的值

要添加端点,请运行

cat <<EOF | tee pl_config_org.json
{
"privateEndpoints": {
"add": [
{
"cloudProvider": "gcp",
"id": "${ENDPOINT_ID:?}",
"description": "A GCP private endpoint",
"region": "${REGION:?}"
}
]
}
}
EOF

要删除端点,请运行

cat <<EOF | tee pl_config_org.json
{
"privateEndpoints": {
"remove": [
{
"cloudProvider": "gcp",
"id": "${ENDPOINT_ID:?}",
"region": "${REGION:?}"
}
]
}
}
EOF

将私有端点添加/删除到组织

curl --silent --user ${KEY_ID:?}:${KEY_SECRET:?} -X PATCH -H "Content-Type: application/json" https://api.clickhouse.cloud/v1/organizations/${ORG_ID:?} -d @pl_config_org.json

将端点 ID 添加到服务允许列表

您需要将端点 ID 添加到每个应使用私有服务连接访问的实例的允许列表中。

注意

此步骤无法对开发服务执行。

选项 1:ClickHouse Cloud 控制台

在 ClickHouse Cloud 控制台中,打开您希望通过私有服务连接连接的服务,然后导航到 **设置**。输入从 添加私有服务连接 步骤中检索到的 Endpoint ID。单击 **创建端点**。

注意

如果要允许来自现有私有服务连接的访问,请使用现有的端点下拉菜单。

Private Endpoints

选项 2:API

在运行任何命令之前,请设置这些环境变量

将下面的 **ENDPOINT_ID** 替换为 添加私有服务连接 步骤中 **端点 ID** 的值

对每个应使用私有服务连接访问的服务执行此操作。

要添加

cat <<EOF | tee pl_config.json
{
"privateEndpointIds": {
"add": [
"${ENDPOINT_ID}"
]
}
}
EOF

要删除

cat <<EOF | tee pl_config.json
{
"privateEndpointIds": {
"remove": [
"${ENDPOINT_ID}"
]
}
}
EOF
curl --silent --user ${KEY_ID:?}:${KEY_SECRET:?} -X PATCH -H "Content-Type: application/json" https://api.clickhouse.cloud/v1/organizations/${ORG_ID:?}/services/${INSTANCE_ID:?} -d @pl_config.json | jq

使用私有服务连接访问实例

每个配置了私有服务连接过滤器的实例都有两个端点:公共端点和私有端点。为了使用私有服务连接进行连接,您需要使用私有端点,请参阅使用 获取 GCP 服务附件以用于私有服务连接 步骤中的 **endpointServiceId**

注意

私有 DNS 主机名仅在您的 GCP VPC 中可用。请勿尝试从位于 GCP VPC 外部的机器解析 DNS 主机。

获取私有 DNS 主机名

选项 1:ClickHouse Cloud 控制台

在 ClickHouse Cloud 控制台中,导航到 **设置**。单击 **设置私有端点** 按钮。在打开的弹出窗口中,复制 **DNS 名称**。

Private Endpoints

选项 2:API

curl --silent --user $KEY_ID:$KEY_SECRET https://api.clickhouse.cloud/v1/organizations/$ORG_ID/services/$INSTANCE_ID/privateEndpointConfig | jq  .result 
{
...
"privateDnsHostname": "xxxxxxx.<region code>.p.gcp.clickhouse.cloud"
}

在此示例中,到 xxxxxxx.yy-xxxxN.p.gcp.clickhouse.cloud 主机名的连接将路由到私有服务连接。同时,xxxxxxx.yy-xxxxN.gcp.clickhouse.cloud 将通过互联网路由。

故障排除

测试 DNS 设置

DNS_NAME - 使用 获取 GCP 服务附件以用于私有服务连接 步骤中的 **privateDnsHostname**

nslookup $DNS_NAME
Non-authoritative answer:
...
Address: 10.128.0.2

连接被对端重置

测试连接性

如果您在使用 PSC 链接连接时遇到问题,请使用 openssl 检查您的连接性。确保私有服务连接端点状态为 Accepted

OpenSSL 应该能够连接(请参阅输出中的 CONNECTED)。errno=104 是预期的。

DNS_NAME - 使用 获取 GCP 服务附件以用于私有服务连接 步骤中的 **privateDnsHostname**

openssl s_client -connect ${DNS_NAME}:9440
CONNECTED(00000003)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 335 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)

检查端点过滤器

REST API

curl --silent --user ${KEY_ID:?}:${KEY_SECRET:?} -X GET -H "Content-Type: application/json" "https://api.clickhouse.cloud/v1/organizations/${ORG_ID:?}/services/${INSTANCE_ID:?}" | jq .result.privateEndpointIds
[
"102600141743718403"
]

连接到远程数据库

假设您尝试在 ClickHouse Cloud 中使用 MySQLPostgreSQL 表函数并连接到您托管在 GCP 中的数据库。无法使用 GCP PSC 安全地启用此连接。PSC 是一种单向连接。它允许您的内部网络或 GCP VPC 安全地连接到 ClickHouse Cloud,但它不允许 ClickHouse Cloud 连接到您的内部网络。

根据 GCP 私有服务连接文档

面向服务的架构:生产者服务通过负载均衡器发布,这些负载均衡器向消费者 VPC 网络公开单个 IP 地址。访问生产者服务的消费者流量是单向的,只能访问服务 IP 地址,而不是访问整个对等 VPC 网络。

为此,请配置您的 GCP VPC 防火墙规则以允许 ClickHouse Cloud 连接到您的内部/私有数据库服务。检查 ClickHouse Cloud 区域的默认出站 IP 地址 以及 可用的静态 IP 地址

更多信息

有关更详细的信息,请访问 cloud.google.com/vpc/docs/configure-private-service-connect-services