使用 IPv6 静态路由下一个跃点实例(不带标记和带标记)、下一个跃点地址和下一个跃点网关

1. 简介

静态自定义路由会影响 VPC 中的默认路由行为。IPv6 自定义路由现在支持新的下一个跃点属性:next-hop-gateway、next-hop-instance 和 next-hop-address。此 Codelab 介绍了如何使用 IPv6 自定义路由以及这些新的下一个跃点选项,方法是使用由多 NIC 虚拟机实例连接的两个 VPC。您还将演示如何混合使用 ULA 和 GUA 寻址,以及如何使用新的自定义路由功能向公有互联网提供 ULA VPC 的可达性。

学习内容

  • 如何通过指定 ILB 的名称来创建具有 next-hop-ilb 下一个跃点的 IPv6 自定义路由
  • 如何通过指定 ILB 的 IPv6 地址来创建具有 next-hop-ilb 下一个跃点的 IPv6 自定义路由

所需条件

  • Google Cloud 项目

2. 准备工作

更新项目以支持 Codelab

此 Codelab 使用 $variables 来帮助在 Cloud Shell 中实现 gcloud 配置。

在 Cloud Shell 中,执行以下操作

gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
export projectname=$(gcloud config list --format="value(core.project)")

实验整体架构

5fc56288b4f8ae05.png

为了演示这两种类型的自定义路由下一个跃点,您将创建 2 个 VPC:使用 ULA 寻址的客户端和服务器 VPC。

为了让客户端 VPC 能够访问服务器,您将使用自定义路由,该路由使用 next-hop-ilb 指向位于一组多 NIC 网关实例前面的 ILB(使用 ILB 的名称),这些实例夹在两个 ILB 之间。为了提供返回到客户端实例的路由(在删除默认的 ::/0 路由后),您将使用自定义路由,该路由使用 next-hop-ilb(使用 ILB 的地址)指向 ILB。

3. 客户端 VPC 设置

创建客户端 VPC

在 Cloud Shell 中,执行以下操作:

gcloud compute networks create client-vpc \
    --project=$projectname \
    --subnet-mode=custom --mtu=1500 \
    --bgp-routing-mode=regional \
    --enable-ula-internal-ipv6

创建客户端子网

在 Cloud Shell 中,执行以下操作:

gcloud compute networks subnets create client-subnet  \
    --network=client-vpc \
    --project=$projectname \
    --range=192.168.1.0/24 \
    --stack-type=IPV4_IPV6 \
    --ipv6-access-type=internal \
    --region=us-central1

使用此命令在环境变量中记录分配的 IPv6 子网

export client_subnet=$(gcloud compute networks subnets \
    describe client-subnet \
    --project $projectname \
    --format="value(internalIpv6Prefix)" \
    --region us-central1)

启动客户端实例

在 Cloud Shell 中,执行以下操作:

gcloud compute instances create client-instance \
    --subnet client-subnet \
    --stack-type IPV4_IPV6 \
    --zone us-central1-a \
    --project=$projectname

为客户端 VPC 流量添加防火墙规则

在 Cloud Shell 中,执行以下操作:

gcloud compute firewall-rules create allow-gateway-client \
    --direction=INGRESS --priority=1000 \
    --network=client-vpc --action=ALLOW \
    --rules=tcp --source-ranges=$client_subnet \
    --project=$projectname 

添加防火墙规则以允许客户端实例的 IAP

在 Cloud Shell 中,执行以下操作:

gcloud compute firewall-rules create allow-iap-client \
    --direction=INGRESS --priority=1000 \
    --network=client-vpc --action=ALLOW \
    --rules=tcp:22 --source-ranges=35.235.240.0/20 \
    --project=$projectname 

确认对客户端实例的 SSH 访问

在 Cloud Shell 中,登录到 client-instance:

gcloud compute ssh client-instance \
    --project=$projectname \
    --zone=us-central1-a \
    --tunnel-through-iap

如果成功,您将看到客户端实例的终端窗口。退出 SSH 会话以继续完成 Codelab。

4. 服务器 VPC 设置

创建服务器 VPC

在 Cloud Shell 中,执行以下操作:

gcloud compute networks create server-vpc \
    --project=$projectname \
    --subnet-mode=custom --mtu=1500 \
    --bgp-routing-mode=regional \
    --enable-ula-internal-ipv6

创建服务器子网

在 Cloud Shell 中,执行以下操作:

gcloud compute networks subnets create server-subnet \
    --network=server-vpc \
    --project=$projectname \
    --range=192.168.0.0/24 \
    --stack-type=IPV4_IPV6 \
    --ipv6-access-type=internal \
    --region=us-central1

使用此命令在环境变量中记录分配的子网

export server_subnet=$(gcloud compute networks subnets \
    describe server-subnet \
    --project $projectname \
    --format="value(internalIpv6Prefix)" \
    --region us-central1)

启动服务器虚拟机

在 Cloud Shell 中,执行以下操作:

gcloud compute instances create server-instance \
    --subnet server-subnet \
    --stack-type IPV4_IPV6 \
    --zone us-central1-a \
    --project=$projectname

添加防火墙规则以允许从客户端访问服务器

在 Cloud Shell 中,执行以下操作:

gcloud compute firewall-rules create allow-client-server \
    --direction=INGRESS --priority=1000 \
    --network=server-vpc --action=ALLOW \
    --rules=tcp --source-ranges=$client_subnet \
    --project=$projectname 

添加防火墙规则以允许 IAP

在 Cloud Shell 中,执行以下操作:

gcloud compute firewall-rules create allow-iap-server \
    --direction=INGRESS --priority=1000 \
    --network=server-vpc --action=ALLOW \
    --rules=tcp:22 \
    --source-ranges=35.235.240.0/20 \
    --project=$projectname 

在 ULA 服务器实例中安装 Apache

在 Cloud Shell 中,登录到 client-instance:

gcloud compute ssh server-instance \
    --project=$projectname \
    --zone=us-central1-a \
    --tunnel-through-iap

在服务器虚拟机 shell 中,运行以下命令

sudo apt update && sudo apt -y install apache2

验证 Apache 是否正在运行

sudo systemctl status apache2

覆盖默认网页

echo '<!doctype html><html><body><h1>Hello World! From Server Instance!</h1></body></html>' | sudo tee /var/www/html/index.html

退出 SSH 会话以继续完成 Codelab。

5. 创建网关实例

创建多 NIC 网关实例模板

在 Cloud Shell 中,执行以下操作:

gcloud compute instance-templates create gateway-instance-template \
    --project=$projectname \
    --instance-template-region=us-central1 \
    --region=us-central1 \
--network-interface=stack-type=IPV4_IPV6,subnet=client-subnet,no-address \
--network-interface=stack-type=IPV4_IPV6,subnet=server-subnet,no-address \
    --can-ip-forward \
    --metadata=startup-script='#! /bin/bash 
sudo sysctl -w net.ipv6.conf.ens4.accept_ra=2
sudo sysctl -w net.ipv6.conf.ens5.accept_ra=2
sudo sysctl -w net.ipv6.conf.ens4.accept_ra_defrtr=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1'

创建多 NIC 网关实例组

在 Cloud Shell 中,执行以下操作:

gcloud compute instance-groups managed create gateway-instance-group \
    --project=$projectname \
    --base-instance-name=gateway-instance \
      --template=projects/$projectname/regions/us-central1/instanceTemplates/gateway-instance-template \
    --size=2 \
    --zone=us-central1-a

验证网关实例

确保我们的启动脚本已正确传递,并且 v6 路由表正确无误。通过 SSH 连接到其中一个网关实例

在 Cloud Shell 中,运行以下命令列出网关实例:

gcloud compute instances list \
    --project=$projectname \
    --zones=us-central1-a \
    --filter name~gateway \
    --format 'csv(name)'

记下其中一个实例名称,并在下一个命令中使用该名称通过 SSH 连接到该实例。

在 Cloud Shell 中,登录到其中一个网关实例

gcloud compute ssh gateway-instance-<suffix> \
    --project=$projectname \
    --zone=us-central1-a \
    --tunnel-through-iap

在网关虚拟机 shell 中,运行以下命令以检查 IPv6 转发

sudo sysctl net.ipv6.conf.all.forwarding

该命令应返回“1”值,表示已启用 IPv6 转发。

验证实例上的 IPv6 路由表

ip -6 route show

示例输出,显示 ULA 和 GUA 子网路由,默认路由指向 GUA 接口。

::1 dev lo proto kernel metric 256 pref medium
2600:1900:4000:7a7f:0:1:: dev ens4 proto kernel metric 256 expires 83903sec pref medium
2600:1900:4000:7a7f::/65 via fe80::4001:c0ff:fea8:101 dev ens4 proto ra metric 1024 expires 88sec pref medium
fd20:3df:8d5c::1:0:0 dev ens5 proto kernel metric 256 expires 83904sec pref medium
fd20:3df:8d5c::/64 via fe80::4001:c0ff:fea8:1 dev ens5 proto ra metric 1024 expires 84sec pref medium
fe80::/64 dev ens5 proto kernel metric 256 pref medium
fe80::/64 dev ens4 proto kernel metric 256 pref medium
default via fe80::4001:c0ff:fea8:101 dev ens4 proto ra metric 1024 expires 88sec pref medium

退出 SSH 会话以继续完成 Codelab。

6. 创建负载平衡器组件

在两个 VPC 中创建路由之前,我们需要在网关实例的两端创建内部直通式负载平衡器,以转发流量。

在此 Codelab 中创建的负载平衡器包含以下组件:

  • 健康检查:在此 Codelab 中,我们将创建以端口 22 为目标的简单健康检查。请注意,健康检查在部署后将无法正常运行(这需要添加防火墙规则以允许健康检查,并在网关实例上创建特殊路由)。由于此 Codelab 专注于 IPv6 转发,因此当所有后端都运行状况不佳时,我们将依赖于内部直通式负载平衡器的默认 流量分配行为,即作为最后的补救措施转发到所有后端。
  • 后端服务:我们将使用协议 TCP 作为后端服务。但是,由于创建负载平衡器是为了实现路由,因此无论后端服务协议是什么,所有协议都会被转发。
  • 转发规则:我们为每个 VPC 创建一个转发规则。
  • 内部 IPv6 地址:在此 Codelab 中,我们将让转发规则自动从子网分配 IPv6 地址

创建健康检查

在 Cloud Shell 中,执行以下操作:

gcloud compute health-checks create tcp tcp-hc-22 \
    --project=$projectname \
    --region=us-central1 \
    --port=22

创建后端服务

在 Cloud Shell 中,执行以下操作:

gcloud compute backend-services create bes-ilb-clientvpc \
    --project=$projectname \
    --load-balancing-scheme=internal \
    --protocol=tcp \
    --network=client-vpc \
    --region=us-central1 \
    --health-checks=tcp-hc-22 \
    --health-checks-region=us-central1

gcloud compute backend-services create bes-ilb-servervpc \
    --project=$projectname \
    --load-balancing-scheme=internal \
    --protocol=tcp \
    --network=server-vpc \
    --region=us-central1 \
    --health-checks=tcp-hc-22 \
    --health-checks-region=us-central1

将实例组添加到后端服务

在 Cloud Shell 中,执行以下操作:

gcloud compute backend-services add-backend bes-ilb-clientvpc \
    --project=$projectname \
    --region=us-central1 \
    --instance-group=gateway-instance-group \
    --instance-group-zone=us-central1-a
gcloud compute backend-services add-backend bes-ilb-servervpc \
    --project=$projectname \
    --region=us-central1 \
    --instance-group=gateway-instance-group \
    --instance-group-zone=us-central1-a

创建转发规则

在 Cloud Shell 中,执行以下操作:

gcloud compute forwarding-rules create fr-ilb-clientvpc \
    --project=$projectname \
    --region=us-central1 \
    --load-balancing-scheme=internal \
    --network=client-vpc \
    --subnet=client-subnet \
    --ip-protocol=TCP \
    --ip-version=IPV6 \
    --ports=ALL \
    --backend-service=bes-ilb-clientvpc \
    --backend-service-region=us-central1

gcloud compute forwarding-rules create fr-ilb-servervpc \
    --project=$projectname \
    --region=us-central1 \
    --load-balancing-scheme=internal \
    --network=server-vpc \
    --subnet=server-subnet \
    --ip-protocol=TCP \
    --ip-version=IPV6 \
    --ports=ALL \
    --backend-service=bes-ilb-servervpc \
    --backend-service-region=us-central1

通过在 Cloud Shell 中发出以下命令来记录两个转发规则的 IPv6 地址:

export fraddress_client=$(gcloud compute forwarding-rules \
    describe fr-ilb-clientvpc \
    --project $projectname \
    --format="value(IPAddress)" \
    --region us-central1)

export fraddress_server=$(gcloud compute forwarding-rules \
    describe fr-ilb-servervpc \
    --project $projectname \
    --format="value(IPAddress)" \
    --region us-central1)

7. 创建并测试到负载平衡器的路由(使用负载平衡器地址)

在本部分中,您将通过使用负载平衡器的 IPv6 地址作为下一个跃点,向客户端和服务器 VPC 添加路由。

记下服务器地址

在 Cloud Shell 中,执行以下操作:

gcloud compute instances list \
   --project $projectname \
   --zones us-central1-a \
   --filter="name~server-instance" \
--format='value[separator=","](name,networkInterfaces[0].ipv6Address)'

这应输出服务器实例名称及其 IPv6 前缀。示例输出

server-instance,fd20:3df:8d5c:0:0:0:0:0

记下服务器地址,因为您稍后将在客户端实例的 curl 命令中使用该地址。遗憾的是,环境变量无法轻松用于存储这些地址,因为它们不会通过 SSH 会话传输。

从客户端向 ULA 服务器实例运行 curl 命令

查看添加任何新路由之前的行为。从客户端实例向 server-instance1 运行 curl 命令。

在 Cloud Shell 中,登录到 client-instance:

gcloud compute ssh client-instance \
    --project=$projectname \
    --zone=us-central1-a \
    --tunnel-through-iap

在客户端实例中,使用 server1 实例的 ULA IPV6 地址执行 curl(该命令设置了 5 秒的短超时时间,以避免 curl 等待时间过长)

curl -m 5.0 -g -6 'http://[ULA-ipv6-address-of-server1]:80/'

此 curl 命令应超时,因为客户端 VPC 尚没有指向服务器 VPC 的路由。

我们来尝试解决此问题!暂时退出 SSH 会话。

在客户端 VPC 中添加自定义路由

由于客户端 VPC 缺少指向 ULA 前缀的路由,我们现在来添加该路由,方法是创建一条按地址指向客户端 ILB 的路由。

注意:IPv6 内部直通式负载平衡器分配有 /96 地址。在将 /96 掩码传递给下一个命令之前,必须从地址中剥离该掩码。(下面使用了 bash 就地替换)

在 Cloud Shell 中,执行以下操作:

gcloud compute routes create client-to-server-route \
   --project=$projectname \
   --destination-range=$server_subnet \
   --network=client-vpc \
   --next-hop-ilb=${fraddress_client//\/96}

通过 SSH 连接回客户端实例:

gcloud compute ssh client-instance \
    --project=$projectname \
    --zone=us-central1-a \
    --tunnel-through-iap

在客户端实例中,再次尝试对服务器实例执行 curl。(该命令设置了 5 秒的短超时时间,以避免 curl 等待时间过长)

curl -m 5.0 -g -6 'http://[ULA-ipv6-address-of-server1]:80/'

此 curl 命令仍然超时,因为服务器 VPC 尚没有通过网关实例返回到客户端 VPC 的路由。

退出 SSH 会话以继续完成 Codelab。

在服务器 VPC 中添加自定义路由

在 Cloud Shell 中,执行以下操作:

gcloud compute routes create server-to-client-route \
   --project=$projectname \
   --destination-range=$client_subnet \
   --network=server-vpc \
  --next-hop-ilb=${fraddress_server//\/96}

通过 SSH 连接回客户端实例:

gcloud compute ssh client-instance \
    --project=$projectname \
    --zone=us-central1-a \
    --tunnel-through-iap

在客户端实例中,再次尝试对服务器实例执行 curl。

curl -m 5.0 -g -6 'http://[ULA-ipv6-address-of-server1]:80/'

此 curl 命令现在成功,表明您已从客户端实例到 ULA 服务器实例建立端到端可达性。现在,只有通过使用 IPv6 自定义路由(其中 next-hop-ilb 作为下一个跃点)才能实现此连接。

示例输出

<user id>@client-instance:~$ curl -m 5.0 -g -6 'http://[fd20:3df:8d5c:0:0:0:0:0]:80/'
<!doctype html><html><body><h1>Hello World! From Server Instance!</h1></body></html>

退出 SSH 会话以继续完成 Codelab。

8. 创建并测试到负载平衡器的路由(使用负载平衡器名称)

或者,next-hop-ilb 也可以引用负载平衡器的名称,而不是其 IPv6 地址。在本部分中,我们将介绍执行此操作的过程,并测试客户端和服务器之间是否仍建立了连接。

删除之前的路由

我们来删除使用实例名称的自定义路由,将环境恢复到添加任何自定义路由之前的状态。

在 Cloud Shell 中,执行以下操作:

gcloud compute routes delete client-to-server-route  --quiet --project=$projectname
gcloud compute routes delete server-to-client-route  --quiet --project=$projectname

从客户端向 ULA 服务器实例运行 curl 命令

为了确认之前的路由已成功删除,请从客户端实例向 server-instance1 运行 curl 命令。

在 Cloud Shell 中,登录到 client-instance:

gcloud compute ssh client-instance \
    --project=$projectname \
    --zone=us-central1-a \
    --tunnel-through-iap

在客户端实例中,使用 server1 实例的 ULA IPV6 地址执行 curl(该命令设置了 5 秒的短超时时间,以避免 curl 等待时间过长)

curl -m 5.0 -g -6 'http://[ULA-ipv6-address-of-server1]:80/'

此 curl 命令应超时,因为客户端 VPC 不再有指向服务器 VPC 的路由。

在客户端和服务器 VPC 中添加自定义路由

我们来重新添加客户端和服务器 VPC 中的自定义路由,但我们将在命令中使用 ILB 的名称和区域,而不是 ILB 的地址。

在 Cloud Shell 中,执行以下操作:

gcloud compute routes create client-to-server-route \
   --project=$projectname \
   --destination-range=$server_subnet \
   --network=client-vpc \
   --next-hop-ilb=fr-ilb-clientvpc \
   --next-hop-ilb-region=us-central1

gcloud compute routes create server-to-client-route \
   --project=$projectname \
   --destination-range=$client_subnet \
   --network=server-vpc \
   --next-hop-ilb=fr-ilb-servervpc \
   --next-hop-ilb-region=us-central1

通过 SSH 连接回客户端实例:

gcloud compute ssh client-instance \
    --project=$projectname \
    --zone=us-central1-a \
    --tunnel-through-iap

在客户端实例中,再次尝试对服务器实例执行 curl。(该命令设置了 5 秒的短超时时间,以避免 curl 等待时间过长)

curl -m 5.0 -g -6 'http://[ULA-ipv6-address-of-server1]:80/'

此 curl 命令现在成功,表明您已从客户端实例到 ULA 服务器实例建立端到端可达性。

9. 清理

清理自定义路由

在 Cloud Shell 中,执行以下操作:

gcloud compute routes delete client-to-server-route  --quiet --project=$projectname
gcloud compute routes delete server-to-client-route  --quiet --project=$projectname

清理 LB 组件

在 Cloud Shell 中,执行以下操作:

gcloud compute forwarding-rules delete fr-ilb-clientvpc --region us-central1 --quiet --project=$projectname
gcloud compute forwarding-rules delete fr-ilb-servervpc --region us-central1 --quiet --project=$projectname

gcloud compute backend-services delete bes-ilb-clientvpc --region us-central1 --quiet --project=$projectname
gcloud compute backend-services delete bes-ilb-servervpc --region us-central1 --quiet --project=$projectname

gcloud compute health-checks delete tcp-hc-22 --region us-central1 --quiet --project=$projectname

清理实例和实例模板

在 Cloud Shell 中,执行以下操作:

gcloud compute instances delete client-instance --zone us-central1-a --quiet --project=$projectname

gcloud compute instances delete server-instance --zone us-central1-a --quiet --project=$projectname


gcloud compute instance-groups managed delete gateway-instance-group --zone us-central1-a --quiet --project=$projectname

gcloud compute instance-templates delete gateway-instance-template --region us-central1 --quiet --project=$projectname

清理子网

在 Cloud Shell 中,执行以下操作:

gcloud compute networks subnets delete client-subnet --region=us-central1 --quiet --project=$projectname

gcloud compute networks subnets delete server-subnet --region=us-central1 --quiet --project=$projectname

清理防火墙规则

在 Cloud Shell 中,执行以下操作:

gcloud compute firewall-rules delete allow-iap-client  --quiet --project=$projectname
gcloud compute firewall-rules delete allow-iap-server  --quiet --project=$projectname
gcloud compute firewall-rules delete allow-gateway-client  --quiet --project=$projectname
gcloud compute firewall-rules delete allow-client-server  --quiet --project=$projectname

清理 VPC

在 Cloud Shell 中,执行以下操作:

gcloud compute networks delete client-vpc --quiet --project=$projectname
gcloud compute networks delete server-vpc --quiet --project=$projectname

10. 恭喜

您已成功使用静态自定义 IPv6 路由,并将下一个跃点设置为 next-hop-ilb。您还使用这些路由验证了端到端 IPv6 通信。

接下来怎么做?

查看下列 Codelab…

拓展阅读和视频

参考文档