适用于 Google API 的 Private Service Connect

1. 简介

通过 Private Service Connect,您可以使用 VPC 网络中的全局内部 IP 地址创建专用端点,以访问 Google API。您可以使用有意义的名称(例如 storage-pscendpoint.p.googleapis.com 和 bigtable-adsteam.p.googleapis.com)将 DNS 名称分配给这些内部 IP 地址。您可以将请求发送到 VPC 网络内部的 Private Service Connect 端点,而不是将 API 请求发送到 storage.googleapis.com 等公共服务端点。

这些名称和 IP 地址在 VPC 网络内部,以及通过 Cloud VPN 隧道或 Cloud Interconnect 连接 (VLAN) 连接到的任何本地网络。

您可以控制要将哪些流量引导至哪个端点,并且可以证明流量保留在 Google Cloud 中。

学习内容

  • Private Service Connect 应用场景
  • 网络要求
  • 支持的 API
  • 创建 Private Service Connect 端点
  • 创建 Cloud Storage 存储桶
  • 创建和更新 Cloud DNS 专用可用区
  • 创建 NAT 网关以访问公共 googleapis
  • 创建和更新 BOTO 配置文件
  • 对 VM1 执行 gsutil list,该命令会针对您的 PSC 服务端点进行解析
  • 对 VM2 执行 gsutil list,解析为公共 googleapis.com
  • 使用 Tcpdump 验证 DNS 解析

所需条件

  • 了解 DNS、nano 或 vi 编辑器

2. Private Service Connect 使用情形

您可以在同一 VPC 网络中创建多个 Private Service Connect 端点。特定端点没有带宽限制。由于 Private Service Connect 端点使用全球内部 IP 地址,因此 VPC 网络中的任何资源都可以使用这些端点。

通过多个端点,您可以使用 Cloud Router 和防火墙规则指定不同的网络路径。

  • 您可以创建防火墙规则,以阻止某些虚拟机通过 Private Service Connect 端点访问 Google API,但允许其他虚拟机访问。
  • 您可以在虚拟机实例上配置禁止流向互联网的所有流量的防火墙规则;发送到 Private Service Connect 端点的流量仍然到达 Google。
  • 如果您的本地主机使用 Cloud VPN 隧道或 Cloud Interconnect 互连连接 (VLAN) 连接到 VPC,则您可以在发送其他请求时通过隧道或 VLAN 发送一些请求。公共互联网。此配置可以让您绕过专用 Google 访问通道不支持的服务(例如 Google 图书)的隧道或 VLAN。如需创建此配置,请创建一个 Private Service Connect 端点,使用 Cloud Router 自定义路由通告通告 Private Service Connect 端点 IP 地址,并启用 Cloud DNS 入站转发政策。应用可以使用 Private Service Connect 端点的名称通过 Cloud VPN 隧道或 Cloud Interconnect 互连连接 (VLAN) 发送一些请求,而使用默认 DNS 名称通过互联网发送另一些请求。
  • 如果您使用多个 Cloud Interconnect 互连连接 (VLAN) 将本地网络连接到 VPC 网络,则可以通过一个 VLAN 从本地发送部分流量,其余流量通过其他 VLAN 发送,如图 2 所示。这样,您可以使用自己的广域网络而不是 Google 的网络,还可以控制数据移动以满足地理位置要求。如需创建此配置,请创建两个 Private Service Connect 端点。在管理第一个 VLAN 的 Cloud Router 的 BGP 会话上为第一个端点创建自定义路由通告,并在管理第二个 VLAN 的 Cloud Router 的 BGP 会话上为第二个端点创建不同的自定义路由通告。配置为使用 Private Service Connect 端点名称的本地主机会通过相应的 Cloud Interconnect 互连连接 (VLAN) 发送流量。
  • 您还可以在主动/主动拓扑中使用多个 Cloud Interconnect 连接 (VLAN)。如果您在管理 VLAN 的 Cloud Router 上使用自定义路由通告为 BGP 会话发布相同的 Private Service Connect 端点 IP 地址,则从本地系统发送到端点的数据包将使用 ECMP 跨 VLAN 路由。

5e142c2fbf6f010e.png

图 1. 通过配置 Private Service Connect、Cloud Router 和本地主机,您可以控制使用哪个 Cloud Interconnect 互连连接 (VLAN) 将流量发送到 Google API。

3. 网络要求

如需使用 Private Service Connect,没有外部 IP 地址的虚拟机 (VM) 实例必须在主要启用专用 Google 访问通道的子网中的主要接口。

无论是否具有子网的专用 Google 访问通道,具有外部 IP 地址的虚拟机均可使用 Private Service Connect 端点访问 Google API 和服务。到 Private Service Connect 端点的连接仍在 Google 的网络中。

无法从对等互连的 VPC 网络访问 Private Service Connect 端点。

支持的 API

创建 Private Service Connect 端点时,您需要选择需要访问哪个 API 软件包:all-apis 还是 vpc-sc。

API 软件包提供对通过专用 Google 访问通道 VIP 提供的 API 的访问权限。

  • all-apis 软件包提供与 private.googleapis.com 相同的 API 访问权限。
  • vpc-sc 软件包提供与 restricted.googleapis.com 相同的 API 访问权限。

4. Codelab 拓扑和使用场景

2ac275eb86f26338.png

图 1 - Codelab 拓扑

Codelab 使用场景 -

我们的客户需要混合使用专用 (interconnect) 和公共 googleapis 访问权限来传输 Cloud Storage 数据。为了满足客户的要求,我们将部署 Private Service Connect,其中包含唯一的 /32 地址、BOTO 配置和 DNS 记录更新。虚拟机 1 将利用 PSC 来访问云端存储分区;相比之下,虚拟机 2 将通过 NAT 网关使用公共 googleapis.com IP 范围。

实验的所有方面都部署在 Google Cloud Platform 中,但相同的用例适用于需要流量分离的混合云部署。

5. 设置和要求

自定进度的环境设置

  1. 登录 Cloud 控制台,然后创建一个新项目或重复使用现有项目。 如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

请记住项目 ID,它在所有 Google Cloud 项目中都是唯一的名称(上述名称已被占用,您无法使用,抱歉!)。它稍后将在此 Codelab 中被称为 PROJECT_ID

  1. 接下来,您需要在 Cloud 控制台中启用结算功能,才能使用 Google Cloud 资源。

运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。请务必按照“清理”部分中的所有说明操作,该部分介绍了如何关停资源,以免产生超出本教程范围的结算费用。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。

启动 Cloud Shell

虽然可以通过笔记本电脑对 Google Cloud 进行远程操作,但在此 Codelab 中,您将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。

在 GCP 控制台中,点击右上角工具栏上的 Cloud Shell 图标:

bce75f34b2c53987.png

预配和连接到环境应该只需要片刻时间。完成后,您应该会看到如下内容:

f6ef2b5f13479f3a.png

这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证功能。只需一个浏览器,即可完成本实验中的所有工作。

6. 准备工作

启用 API

在 Cloud Shell 中,确保项目 ID 已设置

gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
projectname=YOUR-PROJECT-NAME
echo $projectname

启用所有必要的服务

gcloud services enable compute.googleapis.com
gcloud services enable servicedirectory.googleapis.com
gcloud services enable dns.googleapis.com

7. 创建 VPC 网络

VPC 网络

从 Cloud Shell

gcloud compute networks create psc-lab --subnet-mode custom

创建子网

从 Cloud Shell

gcloud compute networks subnets create psclab-subnet \
--network psc-lab --range 10.0.0.0/24 --region us-central1 --enable-private-ip-google-access

创建防火墙规则

如需允许 IAP 连接到您的虚拟机实例,请创建一个防火墙规则,该规则应:

  • 适用于您希望使用 IAP 可访问的所有虚拟机实例。
  • 允许来自 IP 范围 35.235.240.0/20 的入站流量。此范围包含 IAP 用于 TCP 转发的所有 IP 地址。

从 Cloud Shell

gcloud compute firewall-rules create psclab-ssh \
    --network psc-lab --allow tcp:22 --source-ranges=35.235.240.0/20

创建 Cloud NAT 实例

创建 Cloud Router

从 Cloud Shell

gcloud compute routers create crnat \
    --network psc-lab \
    --asn 65000 \
    --region us-central1

创建 Cloud NAT

从 Cloud Shell

gcloud compute routers nats create cloudnat \
    --router=crnat \
    --auto-allocate-nat-external-ips \
    --nat-all-subnet-ip-ranges \
    --enable-logging \
    --region us-central1

8. 创建 Private Service Connect 端点

配置 Private Service Connect 端点 IP <pscendpointip> 时,您需要提供 VPC 中未定义的唯一 IP 地址。

从 Cloud Shell

gcloud compute addresses create psc-ip \
    --global \
    --purpose=PRIVATE_SERVICE_CONNECT \
    --addresses=192.168.255.250 \
    --network=psc-lab

在实验期间存储“pscendpointip”

pscendpointip=$(gcloud compute addresses list --filter=name:psc-ip --format="value(address)")

echo $pscendpointip

创建转发规则以将端点连接到 Google API 和服务。

从 Cloud Shell

gcloud compute forwarding-rules create pscendpoint \
    --global \
    --network=psc-lab \
    --address=psc-ip \
    --target-google-apis-bundle=all-apis

列出已配置的 Private Service Connect 端点

从 Cloud Shell

gcloud compute forwarding-rules list  \
--filter target="(all-apis OR vpc-sc)" --global

描述已配置的 Private Service Connect 端点

从 Cloud Shell

gcloud compute forwarding-rules describe \
    pscendpoint --global

9. 创建存储分区

创建一个 Cloud Storage 存储分区,并将 BUCKET_NAME 替换为您偏好的全局唯一名称。

从 Cloud Shell

gsutil mb  -l us-central1 -b on gs://BUCKET_NAME

在实验期间存储“BUCKET_NAME”

BUCKET_NAME=YOUR BUCKET NAME
echo $BUCKET_NAME

10. DNS 配置

创建 Private Service Connect 端点时,Service Directory 会为使用该端点提供的 API 和服务生成 DNS 记录。

DNS 记录指向您的 Private Service Connect 端点 IP 地址,格式为:SERVICE-ENDPOINT.p.googleapis.com。

您可以在 API 请求中使用这些 DNS 名称,以便将请求定向到您的 Private Service Connect 端点。您也可以在请求的 Host 标头中使用这些 DNS 名称。

如果您要通过访问 Google API 和服务的客户端或应用使用 Private Service Connect 端点,请更新您的客户端或应用以使用 p.googleapis.com DNS 名称。

如需了解详情,请参阅客户端或客户端库的相关文档。例如:

  • Python:您可以在 google-api-core 软件包中的客户端选项类中配置 api_endpoint。
  • Go:您可以在 api 软件包中的客户端选项软件包中配置 WithEndpoint。
  • gcloud: You can configure api_endpoint_overrides using this command. gcloud config set api_endpoint_overrides/SERVICE ENDPOINT_URL

例如:gcloud config set api_endpoint_overrides/storage https://storage-xyz.p.googleapis.com/storage/v1/

如果您无法将客户端或应用配置为使用其他端点,请创建 DNS 记录以匹配默认 DNS 名称。例如,storage.googleapis.com。请参阅使用默认 DNS 名称创建 DNS 记录

验证 DNS 记录

在云控制台中,验证在“网络服务”→“Cloud DNS”下生成的 DNS 条目。记下生成的 DNS 名称“p.googleapis.com”。

11. 创建虚拟机

创建用于验证 Private Service Connect 的虚拟机 (psc-instance-1)

从 Cloud Shell

  gcloud compute instances create psc-instance-1 \
    --subnet psclab-subnet \
    --zone us-central1-a \
    --image=centos-7-v20210122 \
    --image-project=centos-cloud \
    --no-address \
    --metadata=startup-script=yum\ install\ tcpdump\ -y$'\n'yum\ install\ bind-utils\ -y$'\n'yum\ install\ nano\ -y 

登录到虚拟机实例 (psc-instance-1)

通过 Cloud Shell 使用 SSH 连接到虚拟机

gcloud compute ssh --zone "us-central1-a" "psc-instance-1" --project "$projectname"

点击 +(屏幕截图如下)三次,创建其他 Cloud Shell 终端。

69ea94e1527912bb.png

创建用于验证公共 Googleapis 的虚拟机 (psc-instance-2)

从标签页 2

  gcloud compute instances create psc-instance-2 \
    --subnet psclab-subnet \
    --zone us-central1-a \
    --image=centos-7-v20210122 \
    --image-project=centos-cloud \
    --no-address \
    --metadata=startup-script=yum\ install\ tcpdump\ -y$'\n'yum\ install\ bind-utils\ -y$'\n'yum\ install\ nano\ -y 

在标签页 2 中,通过 Cloud Shell 使用 SSH 连接到虚拟机

gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
projectname=YOUR-PROJECT-NAME
echo $projectname


gcloud compute ssh --zone "us-central1-a" "psc-instance-2" --project "$projectname"

从标签页 3 中,通过 Cloud Shell 使用 SSH 连接到 psc-instance-1

gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
projectname=YOUR-PROJECT-NAME
echo $projectname


gcloud compute ssh --zone "us-central1-a" "psc-instance-1" --project "$projectname"

从标签页 4 Shell 通过 Cloud Shell SSH 进入 psc-instance-2

gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
projectname=YOUR-PROJECT-NAME
echo $projectname


gcloud compute ssh --zone "us-central1-a" "psc-instance-2" --project "$projectname"

12. 验证现有 Gsutil 行为

从标签页 4 (psc-instance-2) 启动 tcpdump 并监控 DNS 流量

sudo tcpdump -vv -i eth0 port 53

从标签页 2 (psc-instance-2) 检查存储分区 DNS 查找

BUCKET_NAME=YOUR BUCKET NAME
echo $BUCKET_NAME
gsutil -D ls gs://$BUCKET_NAME

检查 gsutil 调试,HOST storage.googleapis.com 用于 DNS 解析

<snip>
send: 'GET /storage/v1/b/$BUCKET_NAME/o?delimiter=%2F&projection=noAcl&versions=False&fields=prefixes%2CnextPageToken%2Citems%2Fname&alt=json&maxResults=1000 HTTP/1.1\r\nHost: storage.googleapis.com\r\ncontent-length: 0\r\nauthorization: Bearer ya29.c.KpkB7wfaMjfc_WXEKCeNF4Md0fEHnfDU7tqBf3cd0u43yEmYXqj8fX_X5wWdNdDVH6k1EkjeAeIJDzKGvyjPOkf1Io2kVeUqYX69sDv53huW1NslffjAHKchbZ0CP3Cg83TS3Pa55jLcuE0TLbYycVrgSbD3H90LaapUGbWD3kj4IsJLf9J8R98Bqobu8HZwwqk92hlZ4zVzRqOM\r\naccept-encoding: gzip, deflate\r\naccept: application/json\r\nuser-agent: apitools Python/2.7.5 gsutil/4.57 (linux2) analytics/disabled interactive/True command/ls google-cloud-sdk/324.0.0\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
<snip>

在标签页 4 (psc-instance-2) 中,验证在访问存储分区时是否使用了 GoogleAPI.com 公共 DNS A 记录。

metadata.google.internal.domain > psc-instance-2.c.yourprojectname.internal.33973: [udp sum ok] 36442 q: A? storage.googleapis.com. 11/0/0 storage.googleapis.com. A 108.177.111.128, storage.googleapis.com. A 142.250.128.128, storage.googleapis.com. A 74.125.70.128, storage.googleapis.com. A 74.125.201.128, storage.googleapis.com. A 64.233.183.128, storage.googleapis.com. A 173.194.198.128, storage.googleapis.com. A 172.217.219.128, storage.googleapis.com. A 142.250.136.128, storage.googleapis.com. A 209.85.234.128, storage.googleapis.com. A 172.217.212.128, storage.googleapis.com. A 172.217.214.128

13. 修改 Gsutil 行为

请注意,在之前的步骤中,您创建了一个专用 DNS 区域和一条映射到 PSC 端点 IP 地址的 A 记录。在下一步中,我们将通过更新 psc-instance-1 上的虚拟机 BOTO 文件来控制 gsutil 的行为。

从标签页 1 (psc-instance-1) 的虚拟机实例终端查看默认 BOTO 配置

[psc-instance ~]$ more  /etc/boto.cfg

输出(您的 project_id 会有所不同)

[GSUtil]
default_project_id  = [your project number]
default_api_version = 2

[GoogleCompute]
service_account = default

使用 nano 或 VI 编辑器更新 BOTO 配置,确保复制并粘贴所有条目。

示例:sudo nano /etc/boto.cfg

示例:sudo vi /etc/boto.cfg

在虚拟机实例终端标签页 1(psc-instance-1) 中

[Credentials]
gs_host = storage-pscendpoint.p.googleapis.com
gs_host_header = storage.googleapis.com
gs_json_host = storage-pscendpoint.p.googleapis.com
gs_json_host_header = www.googleapis.com

验证配置,[凭据] 的顺序对于 DNS 查找至关重要

more /etc/boto.cfg
[Credentials]
gs_host = storage-pscendpoint.p.googleapis.com
gs_host_header = storage.googleapis.com
gs_json_host = storage-pscendpoint.p.googleapis.com
gs_json_host_header = www.googleapis.com

[GSUtil]
default_project_id  = [your project number
default_api_version = 2

[GoogleCompute]
service_account = default

14. 验证更新后的 gsutil 查找行为

在标签页 3 (psc-instance-1) 中,启动 tcpdump 并监控 DNS 流量

sudo tcpdump -vv -i eth0 port 53

检查来自标签页 1 (psc-instance-1) 的存储分区 gsutil 查找

BUCKET_NAME=YOUR BUCKET NAME
echo $BUCKET_NAME

gsutil -D ls gs://$BUCKET_NAME

调试日志确认可以通过 Private Service Connect 端点“pscendpoint”访问存储分区

输出:

<snip>
INFO 0131 22:14:18.795986 base_api.py] Making http GET to https://storage-pscendpoint.p.googleapis.com/storage/v1/b/$BUCKET_NAME/o?delimiter=%2F&projection=noAcl&versions=False&fields=prefixes%2CnextPageToken%2Citems%2Fname&alt=json&maxResults=1000
INFO 0131 22:14:18.796415 base_api.py] Headers: {u'Host': 'www.googleapis.com',
 'accept': 'application/json',
 'accept-encoding': 'gzip, deflate',
 'content-length': '0',
 'user-agent': 'apitools Python/2.7.5 gsutil/4.57 (linux2) analytics/disabled interactive/True command/ls google-cloud-sdk/324.0.0'}
INFO 0131 22:14:18.796502 base_api.py] Body: (none)
connect: (storage-pscendpoint.p.googleapis.com, 443)
send: 'GET /storage/v1/b/psc-bucket/o?delimiter=%2F&projection=noAcl&versions=False&fields=prefixes%2CnextPageToken%2Citems%2Fname&alt=json&maxResults=1000 HTTP/1.1\r\ncontent-length: 0\r\naccept-encoding: gzip, deflate\r\naccept: application/json\r\nuser-agent: apitools Python/2.7.5 gsutil/4.57 (linux2) analytics/disabled interactive/True command/ls google-cloud-sdk/324.0.0\r\nhost: www.googleapis.com\r\nauthorization: Bearer ya29.c.KpkB7wd3XWiYeRyTuth5_HPlNV-hPwc2Nn7RSIeMpzrpa_j4EsMPl2m_mDGKAcGHvYIgiC5bT2UVQirAPpSbbpToa6G6lkaBbH5SZwHwgNXYfisp5Ww1UjXe4rTa69a_Wp0WesafcwPNnYzDo3xf5VGh3iGhySA04kTXuyT--MgOU8U-XLII2LJQxUWlV8KEdrvyCuqRb-jsDdk_\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
<snip>

在标签页 3 (psc-instance-1) 中,验证您的 PSC 端点 IP 是否是尝试访问存储分区时使用的 DNS A 记录。

@psc-instance-1 ~]$ sudo tcpdump -vv -i eth0 port 53
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
05:02:33.936256 IP (tos 0x0, ttl 64, id 55416, offset 0, flags [DF], proto UDP (17), length 82)
    psc-instance-1.c.yourprojectname.internal.42296 > metadata.google.internal.domain: [bad udp cksum 0x5e4e -> 0xcceb!] 34796+ A? storage-pscendpoint.p.googleapis.com. (54)
05:02:33.936269 IP (tos 0x0, ttl 64, id 55417, offset 0, flags [DF], proto UDP (17), length 82)
    psc-instance-1.c.yourprojectname.internal.42296 > metadata.google.internal.domain: [bad udp cksum 0x5e4e -> 0x3ebd!] 5632+ AAAA? storage-pscendpoint.p.googleapis.com. (54)
05:02:33.944018 IP (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 98)
    metadata.google.internal.domain > psc-instance-1.c.yourprojectname.42296: [udp sum ok] 34796 q: A? storage-pscendpoint.p.googleapis.com. 1/0/0 storage-pscendpoint.p.googleapis.com. A 10.10.110.10 (70)
05:02:33.946005 IP (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 175)

验证 Private Service Connect 端点 IP 现在是否用于 DNS 解析

从 tab1

nslookup storage-pscendpoint.p.googleapis.com

输出

@psc-instance ~]$ nslookup storage-pscendpoint.p.googleapis.com
Server:         169.254.169.254
Address:        169.254.169.254#53

Non-authoritative answer:
Name:   storage-pscendpoint.p.googleapis.com
Address: <pscip>

15. 清理步骤

退出虚拟机实例(所有标签页)

exit

从单个 Cloud Shell 终端删除实验组件

gcloud compute routers nats delete cloudnat --router=crnat --region=us-central1 --quiet

gcloud compute routers delete crnat --region=us-central1 --quiet

gcloud compute forwarding-rules delete pscendpoint --global --quiet

gcloud compute addresses delete psc-ip --global --quiet

gsutil rm -r gs://$BUCKET_NAME

gcloud compute instances delete psc-instance-1 --zone=us-central1-a --quiet

gcloud compute instances delete psc-instance-2 --zone=us-central1-a --quiet

gcloud compute firewall-rules delete psclab-ssh --quiet

gcloud compute networks subnets delete psclab-subnet --region us-central1 --quiet

gcloud compute networks delete psc-lab --quiet

在控制台中,确保您查看的是正确的项目,然后依次选择“网络服务”→“Cloud DNS”

16. 恭喜!

恭喜您完成此 Codelab。

所学内容

  • Private Service Connect 应用场景
  • 网络要求
  • 支持的 API
  • 创建了 Private Service Connect 端点
  • 创建了 Cloud Storage 存储分区
  • 更新了 BOTO 配置文件
  • 创建了 NAT 网关
  • 在 VM1 上执行 gsutil list,该命令会针对您的 PSC 服务端点进行解析
  • 在解析为公共 googleapis.com 的 VM2 上执行 gsutil list
  • 使用 Tcpdump 验证 DNS 解析