云企业网支持在地域内定义灵活的互通、隔离、引流策略。本文为您介绍如何通过云企业网实现相互隔离的VPC同时访问同一个共享服务。
背景信息
本文以下图场景为例。某企业在阿里云华东1(杭州)地域已经部署有三个VPC,其中VPC3为部署共享服务的VPC。企业希望VPC1和VPC2均能访问VPC3使用共享服务,而VPC1和VPC2之间不互通。
网络规划
为实现上述需求,结合云企业网自定义路由表、关联转发、路由学习等功能,对企业网段和路由规划如下:本文示例中,VPC1、VPC2、VPC3与转发路由器同属一个阿里云账号。如果共享服务VPC与业务VPC分属不同阿里云账号,本文的隔离策略机制同样适用,差异配置请参见下文的跨账号场景下的差异配置。
-
将VPC3连接到转发路由器时,开启自动关联至转发路由器的默认路由表和自动传播系统路由至转发路由器的默认路由表高级功能。
开启后,转发路由器系统路由表能自动学习到VPC3的系统路由,并且VPC3通过查询转发路由器的系统路由表进行流量转发。
-
将VPC1和VPC2连接到转发路由器时,均只开启自动传播系统路由至转发路由器的默认路由表一个高级配置,然后将VPC1和VPC2关联到转发路由器的自定义路由表,且在自定义路由表中,添加去往VPC3的自定义路由条目。
完成后,转发路由器系统路由表能学习到VPC1和VPC2的全部系统路由。VPC1和VPC2通过查询自定义路由表将流量转发到VPC3。此时,VPC1和VPC2之间不互通。
-
分别在VPC1、VPC2、VPC3的路由表中添加0.0.0.0/0,下一跳指向转发路由器的路由。
-
在华东1(杭州)地域创建三个VPC,并在指定可用区中创建交换机。VPC中的网段规划,如下表所示。
重要在您进行网段规划时,请确保VPC之间的网段没有重叠。
专有网络VPC
交换机
交换机可用区
网段规划
云服务器ECS
VPC1
主网段:192.168.0.0/16
交换机1
可用区A
192.168.0.0/24
ECS1地址:
192.168.0.224
交换机2
可用区B
192.168.1.0/24
VPC2
主网段:172.16.0.0/16
交换机3
可用区A
172.16.0.0/24
ECS2地址:
172.16.0.222
交换机4
可用区B
172.16.1.0/24
VPC3
主网段:10.0.0.0/16
交换机5
可用区A
10.0.0.0/24
ECS3地址:
10.0.0.112
交换机6
可用区B
10.0.1.0/24
操作步骤
本文提供控制台和Terraform两种配置方式,请按需选择。
控制台
步骤一:创建云企业网实例
在您连接网络实例前,您需要先创建一个云企业网实例。
登录云企业网管理控制台。
-
在云企业网实例页面,单击创建云企业网实例。
-
在创建云企业网实例对话框,根据以下信息配置云企业网实例,然后单击确认。
-
名称:云企业网实例的名称。
-
描述:云企业网实例的描述。
-
步骤二:创建VPC连接
-
在云企业网实例页面,单击目标实例ID。
-
在云企业网实例详情页面的基本信息页签,单击VPC下的
图标。 -
在连接网络实例页面,根据以下信息进行配置,然后单击确定创建。
-
实例类型:系统默认选择专有网络(VPC)。
-
地域:选择要连接的网络实例所在的地域。本示例选择华东1(杭州)。
-
转发路由器:系统自动为您在该地域创建转发路由器。
-
资源归属UID:选择要连接的网络实例所归属的账号类型。本示例使用默认值同账号。
-
付费方式:使用默认值按量付费。
-
连接名称:输入连接名称。
-
网络实例:选择要连接的VPC网络实例ID。本示例选择VPC3。
-
交换机:在转发路由器支持的可用区选择交换机实例。
在转发路由器支持多个可用区的地域,您需要在至少2个可用区中各选择一个交换机实例。在VPC和转发路由器流量互通的过程中,这2个交换机实例可以实现可用区级别的容灾。
推荐您在每个可用区中都选择一个交换机实例,以减少流量绕行,体验更低传输时延以及更高性能。
如果企业版转发路由器在当前地域仅支持一个可用区,则您需要在当前可用区选择一个交换机实例。
-
高级配置:系统默认帮您选中以下三种高级功能。本示例中VPC3只开启自动关联至转发路由器的默认路由表和自动传播系统路由至转发路由器的默认路由表高级功能。
自动关联至转发路由器的默认路由表
开启本功能后,VPC连接会自动关联至转发路由器的默认路由表,转发路由器通过查询默认路由表转发VPC实例的流量。
自动传播系统路由至转发路由器的默认路由表
开启本功能后,VPC实例会将自身的系统路由传播至转发路由器的默认路由表中,用于网络实例的互通。
自动为VPC的所有路由表配置指向转发路由器的路由
开启本功能后,系统将在VPC实例的所有路由表内自动配置10.0.0.0/8、172.16.0.0/12、192.168.0.0/16三条路由条目,其下一跳均指向VPC连接,用于引导VPC实例的IPv4流量进入转发路由器。转发路由器默认不向VPC实例传播路由。
-
-
VPC3连接创建完成后,单击继续创建连接。
-
VPC连接创建完成后,单击返回列表,返回到云企业网实例详情页面。
步骤三:VPC1和VPC2关联自定义路由表
-
在云企业网实例详情页面,找到已创建的转发路由器,单击其实例ID。
-
在转发路由器详情页面,单击转发路由器路由表页签。
-
在页签左侧区域,单击创建路由表。
-
在创建路由表对话框,根据以下信息进行配置,然后单击确定。
-
转发路由器:系统自动选择当前地域的转发路由器。
-
路由表名称:输入路由表名称。
-
路由表描述:输入路由表描述。
-
多地域等价路由:保持默认值。
-
-
单击返回路由表详情,返回到转发路由器路由表页签下。
-
在转发路由器路由表页签下,选择刚刚创建的自定义路由表,单击关联转发页签,然后单击创建关联转发。
-
在添加关联转发对话框,选择要关联至该自定义路由表的网络实例连接,然后单击确定。
本文示例中,分别将VPC1和VPC2关联至该自定义路由表。关联后,VPC1和VPC2将通过查询该路由表进行流量转发。
-
在自定义路由表详情页面,单击路由条目页签,然后单击创建路由条目。
-
在添加路由条目对话框,根据以下信息进行配置,然后单击确定。
-
路由表:系统默认选择当前自定义路由表。
-
所属转发路由器:系统默认选择当前地域的转发路由器。
-
路由条目名称:输入路由条目名称。
-
目的地址CIDR:输入要添加的路由目标网段。本示例输入10.0.0.0/16。
-
是否为黑洞路由:如果选择路由为黑洞路由后,所有去往该路由的流量均会被丢弃。本示例选择否。
-
下一跳连接:选择路由的下一跳连接。本示例选择VPC3连接。
-
路由条目描述:路由条目描述。
-
步骤四:为VPC添加默认路由条目
您需要在VPC控制台分别为VPC1、VPC2、VPC3添加网段为0.0.0.0/0,下一跳指向转发路由器的路由。
- 登录专有网络管理控制台。
-
在左侧导航栏,单击路由表。
-
在顶部菜单栏,选择路由表所属的地域。
-
在路由表页面,找到目标路由表,单击路由表的ID。
本示例选择VPC3的路由表。
-
在路由表实例详情页面,单击路由条目列表页签下的自定义路由条目,然后单击添加路由条目。
-
在添加路由条目面板,根据以下信息配置路由条目,然后单击确定。
-
名称:输入路由条目的名称。
-
目标网段:输入要添加的目标网段。本示例输入0.0.0.0/0。
-
下一跳类型:选择下一跳类型。本示例选择转发路由器。
-
转发路由器:选择网络实例连接。本示例选择VPC3连接。
更多参数说明,请参见使用自定义路由表进行网络流量管理。
-
-
请重复步骤4到步骤6,分别为VPC1、VPC2添加网段为0.0.0.0/0,下一跳指向转发路由器的路由。
在您完成配置后,您可以在云企业网控制台转发路由器详情页面查看VPC1、VPC2、VPC3以及转发路由器路由表的路由信息。
-
在转发路由器详情页面,单击网络实例路由信息,分别查看VPC1、VPC2和VPC3的路由。
-
在转发路由器详情页面,单击网络实例路由信息。
-
在网络实例后面,选择VPC1、VPC2或VPC3的实例ID,查看路由。
图 1. VPC1的路由

图 2. VPC2的路由

图 3. VPC3的路由

-
-
您可以在转发路由器路由表页签下,查看转发路由器系统路由表已学习到的VPC1、VPC2、VPC3的路由。
-
在转发路由器详情页面,单击转发路由器路由表。
-
在转发路由器路由表页签下,查看路由表路由条目。
图 4. 系统路由表

图 5. 自定义路由表

-
-
步骤五:验证测试
完成上述配置后,您可以通过以下步骤,测试VPC1、VP2、VPC3之间的连通性。
在您执行以下步骤前,请您先了解您VPC1、VPC2、VPC3中的ECS实例所应用的安全组规则,确保安全组规则允许三个VPC中的ECS实例之间可以互通。具体操作,请参见查询安全组规则。
-
登录VPC1的ECS实例。具体操作,请参见选择ECS远程连接方式。
-
通过ping命令,ping VPC3下的ECS实例的IP地址,测试VPC1和VPC3之间的连通性。
经验证,VPC1和VPC3之间可以正常通信。

-
登录VPC2的ECS实例,通过ping命令,ping VPC3下的ECS实例的IP地址,测试VPC2和VPC3之间的连通性。
经验证,VPC2和VPC3之间可以正常通信。

-
登录VPC1的ECS实例,通过ping命令,ping VPC2下的ECS实例的IP地址,测试VPC1和VPC2之间的连通性。
经验证,VPC1和VPC2之间不能通信。

步骤六:跨账号场景下的差异配置
本文前述步骤以VPC1、VPC2、VPC3与转发路由器同属一个阿里云账号为例。如果共享服务VPC与业务VPC分属不同阿里云账号(例如共享服务VPC由独立的共享服务账号持有,业务VPC分属不同的业务账号),可参考以下说明完成跨账号部署。跨账号场景下,隔离策略的实现机制与同账号场景一致:VPC1、VPC2仅开启自动传播系统路由至转发路由器的默认路由表,并关联到转发路由器的自定义路由表,同时在自定义路由表中添加去往VPC3的路由,与网络实例归属哪个阿里云账号无关。
前置条件:完成跨账号实例授权
在创建跨账号的VPC连接前,需要由VPC所属账号先完成跨账号实例授权,将权限授予转发路由器所属账号。具体操作,请参见跨账号实例授权。
操作差异:选择「跨账号」并指定VPC所属账号
在步骤二:创建VPC连接中,配置资源归属UID时:如果待连接的VPC与转发路由器实例同属一个阿里云账号,选择同账号;如果待连接的VPC与转发路由器实例分属不同的阿里云账号,则选择跨账号,并输入该VPC所属的阿里云账号(主账号)ID。其余配置项与同账号场景一致。参数说明请参见创建VPC连接。
操作主体:按账号划分执行方
-
创建CEN实例、创建VPC连接、创建并配置自定义路由表及其路由条目(对应步骤一至步骤三)均在转发路由器所属账号下操作。
-
步骤四:为VPC添加默认路由条目需由各VPC所属的账号分别在自己的VPC控制台中操作:即业务VPC所属账号为自己的VPC添加指向转发路由器的默认路由,共享服务VPC所属账号为自己的VPC添加相应路由。
完成上述配置后,跨账号场景下VPC1、VPC2与VPC3之间的连通性验证方法与「步骤五:验证测试」一致。
跨账号 VPC 路由策略隔离配置
跨账号 VPC 接入云企业网后,默认与云企业网内其他 VPC 全互通。如果您需要在跨账号场景下选择性隔离部分 VPC 之间的互访,无需改造前述的自定义路由表和关联转发方案,可以在转发路由器路由表中配置路由策略(Route Map)实现。该方案与步骤六:跨账号场景下的差异配置中介绍的自定义路由表隔离机制是两种不同的实现方式,您可以根据需要选择使用。
工作原理
路由策略通过控制平面过滤路由通告来实现隔离,而不是在数据面直接阻断报文转发。也就是说,配置拒绝策略后,被拒绝一方的路由条目不会再被通告给对端,从而使双方无法学习到彼此的路由、无法互通。
前置条件
路由策略仅对配置完成后新产生的路由通告生效,对已经通告成功、已经存在于路由表中的路由条目不生效。因此,在配置路由策略前,需要先删除转发路由器路由表中双方已经学习到的、需要隔离的路由条目,否则隔离不会立即生效。
配置拒绝路由策略
登录云企业网控制台,在目标转发路由器详情页面的路由策略页签下创建路由策略(页签名称以控制台实际显示为准),并配置以下关键参数:
-
策略行为:选择拒绝(Deny)。
-
优先级:数值越小优先级越高。本示例设置为 20。
-
生效方向:选择出地域网关。
-
源实例 ID 列表:填写发起访问一方的跨账号 VPC 实例 ID。
-
目的实例 ID 列表:填写需要被隔离、拒绝访问的 VPC 实例 ID。
保存后,转发路由器将不再把目的实例的路由通告给源实例,双方之间的路由不可达。
已知问题:控制台源实例 ID 列表下拉框可能为空
如果 VPC 连接已经通过关联转发关联到路由表,控制台创建路由策略时的源实例 ID 列表下拉框可能显示无可选项,无法通过控制台直接完成配置。遇到此问题时,建议调用 CreateCenRouteMap API,并在请求参数中直接传入 vpc-xxx 格式的 VPC 实例 ID 创建路由策略,绕开控制台下拉框的限制。
验证隔离是否生效
完成路由策略配置后,登录跨账号 VPC 内的 ECS 实例,通过 ping 命令测试访问已配置隔离的目标 VPC 内 ECS 实例的 IP 地址。如果隔离配置生效,ping 请求应无法访问目标地址(100% 丢包)。
Terraform
您可以使用Terraform搭建本文示例环境,关于Terraform的安装和配置,请参考Install Terraform。
下面步骤以Linux主机运行Terraform v1.9.8为例进行介绍,操作前请确保您已经完成Authentication。
本教程示例包含的部分资源会产生一定费用,请在不需要时及时进行释放或退订。
第一步:创建资源
本文场景对应的Terraform代码:
variable "pname" {
description = "The prefix name for the resources"
type = string
default = "tf-CenSharedVpc"
}
variable "default_region" {
description = "Default region"
type = string
default = "cn-hangzhou"
}
variable "az_list" {
description = "List of availability zones to use"
type = list(string)
default = ["cn-hangzhou-j", "cn-hangzhou-k"]
}
variable "vpc_cidr_list" {
description = "List of VPC CIDR block"
type = list(string)
default = ["192.168.0.0/16", "172.16.0.0/16", "10.0.0.0/16"]
}
variable "vsw_cidr_list" {
description = "List of VSW CIDR block"
type = list(string)
default = [
"192.168.0.0/24", "192.168.1.0/24",
"172.16.0.0/24", "172.16.1.0/24",
"10.0.0.0/24", "10.0.1.0/24"
]
}
variable "ecs_ip_list" {
description = "List of ECS ip"
type = list(string)
default = ["192.168.0.124", "172.16.0.222", "10.0.0.112"]
}
provider "alicloud" {
region = var.default_region
}
# --- 3vpc 6vsw 3ecs
resource "alicloud_vpc" "vpc" {
count = length(var.vpc_cidr_list)
vpc_name = "${var.pname}-vpc${count.index + 1}"
cidr_block = var.vpc_cidr_list[count.index]
}
resource "alicloud_vswitch" "vsw" {
count = length(var.vsw_cidr_list)
vpc_id = alicloud_vpc.vpc[floor(count.index / length(var.az_list))].id
cidr_block = var.vsw_cidr_list[count.index]
zone_id = var.az_list[count.index % length(var.az_list)]
vswitch_name = "${var.pname}-vsw${count.index + 1}"
}
resource "alicloud_instance" "ecs" {
count = length(var.vpc_cidr_list)
instance_name = "${var.pname}-ecs${count.index + 1}"
instance_type = "ecs.e-c1m1.large"
security_groups = [alicloud_security_group.sg[count.index].id]
vswitch_id = alicloud_vswitch.vsw[count.index * length(var.az_list)].id
image_id = "aliyun_3_x64_20G_qboot_alibase_20230727.vhd"
system_disk_category = "cloud_essd"
private_ip = var.ecs_ip_list[count.index]
instance_charge_type = "PostPaid"
}
# --- 3 sg
resource "alicloud_security_group" "sg" {
count = length(var.vpc_cidr_list)
name = "${var.pname}-${count.index + 1}"
vpc_id = alicloud_vpc.vpc[count.index].id
}
resource "alicloud_security_group_rule" "allow_inbound_ssh" {
count = length(var.vpc_cidr_list)
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = alicloud_security_group.sg[count.index].id
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_security_group_rule" "allow_inbound_icmp" {
count = length(var.vpc_cidr_list)
type = "ingress"
ip_protocol = "icmp"
nic_type = "intranet"
policy = "accept"
port_range = "-1/-1"
priority = 1
security_group_id = alicloud_security_group.sg[count.index].id
cidr_ip = "0.0.0.0/0"
}
# --- cen and tr
resource "alicloud_cen_instance" "cen" {
cen_instance_name = "${var.pname}-cen1"
}
resource "alicloud_cen_transit_router" "tr" {
transit_router_name = "${var.pname}-tr"
cen_id = alicloud_cen_instance.cen.id
}
data "alicloud_cen_transit_router_route_tables" "tr" { # get tr sys table
transit_router_id = alicloud_cen_transit_router.tr.transit_router_id
transit_router_route_table_type = "System"
}
# 3 attach
resource "alicloud_cen_transit_router_vpc_attachment" "attach" {
count = length(var.vpc_cidr_list)
cen_id = alicloud_cen_instance.cen.id
transit_router_id = alicloud_cen_transit_router.tr.transit_router_id
vpc_id = alicloud_vpc.vpc[count.index].id
zone_mappings {
zone_id = var.az_list[0]
vswitch_id = alicloud_vswitch.vsw[count.index * length(var.az_list)].id
}
zone_mappings {
zone_id = var.az_list[1]
vswitch_id = alicloud_vswitch.vsw[count.index * length(var.az_list) + 1].id
}
transit_router_vpc_attachment_name = "attach${count.index + 1}"
}
# 3 propa
resource "alicloud_cen_transit_router_route_table_propagation" "propa" {
count = length(var.vpc_cidr_list)
transit_router_route_table_id = data.alicloud_cen_transit_router_route_tables.tr.tables[0].id
transit_router_attachment_id = alicloud_cen_transit_router_vpc_attachment.attach[count.index].transit_router_attachment_id
}
# 1 custom_table
resource "alicloud_cen_transit_router_route_table" "custom_table" { # create tr custom_table
transit_router_id = alicloud_cen_transit_router.tr.transit_router_id
transit_router_route_table_name = "custom_table"
}
resource "alicloud_cen_transit_router_route_entry" "tr_entry" {
transit_router_route_table_id = alicloud_cen_transit_router_route_table.custom_table.transit_router_route_table_id
transit_router_route_entry_destination_cidr_block = "10.0.0.0/16"
transit_router_route_entry_next_hop_type = "Attachment"
transit_router_route_entry_name = "entry1_name"
transit_router_route_entry_description = "entry1_desc"
transit_router_route_entry_next_hop_id = alicloud_cen_transit_router_vpc_attachment.attach[2].transit_router_attachment_id
}
# associate attach1\2 custom_table
resource "alicloud_cen_transit_router_route_table_association" "ass1" {
transit_router_route_table_id = alicloud_cen_transit_router_route_table.custom_table.transit_router_route_table_id
transit_router_attachment_id = alicloud_cen_transit_router_vpc_attachment.attach[0].transit_router_attachment_id
}
resource "alicloud_cen_transit_router_route_table_association" "ass2" {
transit_router_route_table_id = alicloud_cen_transit_router_route_table.custom_table.transit_router_route_table_id
transit_router_attachment_id = alicloud_cen_transit_router_vpc_attachment.attach[1].transit_router_attachment_id
}
# ass attach3 sys_table
resource "alicloud_cen_transit_router_route_table_association" "ass3" {
transit_router_route_table_id = data.alicloud_cen_transit_router_route_tables.tr.tables[0].id
transit_router_attachment_id = alicloud_cen_transit_router_vpc_attachment.attach[2].transit_router_attachment_id
}
# vpc entry
resource "alicloud_route_entry" "vpc_entry" {
count = length(var.vpc_cidr_list)
route_table_id = alicloud_vpc.vpc[count.index].route_table_id
destination_cidrblock = "0.0.0.0/0"
nexthop_type = "Attachment"
nexthop_id = alicloud_cen_transit_router_vpc_attachment.attach[count.index].transit_router_attachment_id
}
output "ecs1_login_address" {
value = "https://ecs-workbench.alibabacloud.com/?from=EcsConsole&instanceType=ecs®ionId=${var.default_region}&instanceId=${alicloud_instance.ecs[0].id}"
}
output "ecs2_login_address" {
value = "https://ecs-workbench.alibabacloud.com/?from=EcsConsole&instanceType=ecs®ionId=${var.default_region}&instanceId=${alicloud_instance.ecs[1].id}"
}
output "ecs3_login_address" {
value = "https://ecs-workbench.alibabacloud.com/?from=EcsConsole&instanceType=ecs®ionId=${var.default_region}&instanceId=${alicloud_instance.ecs[2].id}"
}
第二步:验证测试
您可以通过以下步骤,测试VPC1、VPC2、VPC3之间的连通性。
-
登录VPC1下的ECS1实例(实例名称为
tf-CenSharedVpc-ecs1)。您可以在Terraform的Outputs输出中,找到ECS1的登录地址并复制到浏览器打开,登录时注意认证方式选择临时SSH密钥认证。

-
通过ping命令,ping VPC3下的ECS3实例的IP地址,测试VPC1和VPC3之间的连通性。
ping 10.0.0.112经验证,VPC1和VPC3之间可以正常通信。

-
登录VPC2下的ECS2实例(实例名称为
tf-CenSharedVpc-ecs2),通过ping命令,ping VPC3下的ECS3实例的IP地址,测试VPC2和VPC3之间的连通性。ping 10.0.0.112经验证,VPC2和VPC3之间可以正常通信。

-
登录VPC1下的ECS1实例(实例名称为
tf-CenSharedVpc-ecs1),通过ping命令,ping VPC2下的ECS2实例的IP地址,测试VPC1和VPC2之间的连通性。ping 172.16.0.222经验证,VPC1和VPC2之间不能通信。

第三步:释放资源
验证完毕后,如果您不再使用资源,请执行以下命令释放资源,防止继续计费。
terraform destroy --auto-approve