Azure Hub-Spoke架构POC中VM间无法Ping通的问题排查求助
问题:Azure Hub-Spoke架构中跨Spoke虚拟机无法互Ping
我在Azure实验环境部署了Hub-Spoke架构POC,所有资源已部署完成,但部署在spoke1子网的vm1和spoke2子网的vm2之间无法互相Ping通。已在两台VM的NSG入向设置了通配符规则,以下是部署用的Terraform代码:
terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "3.115.0" } tls = { source = "hashicorp/tls" version = "~>4.0" } } } provider "azurerm" { features {} skip_provider_registration = true } data "azurerm_resource_group" "myrg" { name = "1-cace0afe-playground-sandbox" } # Hub VNet resource "azurerm_virtual_network" "hub_vnet" { name = "hub-vnet" address_space = ["10.0.0.0/16"] location = data.azurerm_resource_group.myrg.location resource_group_name = data.azurerm_resource_group.myrg.name } # Spoke 1 VNet resource "azurerm_virtual_network" "spoke1_vnet" { name = "spoke1-vnet" address_space = ["10.1.0.0/16"] location = data.azurerm_resource_group.myrg.location resource_group_name = data.azurerm_resource_group.myrg.name } # Spoke 2 VNet resource "azurerm_virtual_network" "spoke2_vnet" { name = "spoke2-vnet" address_space = ["10.2.0.0/16"] location = data.azurerm_resource_group.myrg.location resource_group_name = data.azurerm_resource_group.myrg.name } # Hub Subnet resource "azurerm_subnet" "hub_subnet" { name = "hub-subnet" resource_group_name = data.azurerm_resource_group.myrg.name virtual_network_name = azurerm_virtual_network.hub_vnet.name address_prefixes = ["10.0.1.0/24"] } # Spoke 1 Subnet resource "azurerm_subnet" "spoke1_subnet" { name = "spoke1-subnet" resource_group_name = data.azurerm_resource_group.myrg.name virtual_network_name = azurerm_virtual_network.spoke1_vnet.name address_prefixes = ["10.1.1.0/24"] } # Spoke 2 Subnet resource "azurerm_subnet" "spoke2_subnet" { name = "spoke2-subnet" resource_group_name = data.azurerm_resource_group.myrg.name virtual_network_name = azurerm_virtual_network.spoke2_vnet.name address_prefixes = ["10.2.1.0/24"] } resource "azurerm_virtual_network_peering" "hub_to_spoke1" { name = "hub-to-spoke1" remote_virtual_network_id = azurerm_virtual_network.spoke1_vnet.id virtual_network_name = azurerm_virtual_network.hub_vnet.name resource_group_name = data.azurerm_resource_group.myrg.name allow_virtual_network_access =true allow_gateway_transit = true allow_forwarded_traffic = true use_remote_gateways = false } resource "azurerm_virtual_network_peering" "spoke1_to_hub" { name = "spoke1-to-hub" remote_virtual_network_id = azurerm_virtual_network.hub_vnet.id virtual_network_name = azurerm_virtual_network.spoke1_vnet.name resource_group_name = data.azurerm_resource_group.myrg.name allow_virtual_network_access =true allow_gateway_transit = false allow_forwarded_traffic = true use_remote_gateways = false } resource "azurerm_virtual_network_peering" "hub_to_spoke2" { name = "hub-to-spoke2" remote_virtual_network_id = azurerm_virtual_network.spoke2_vnet.id virtual_network_name = azurerm_virtual_network.hub_vnet.name resource_group_name = data.azurerm_resource_group.myrg.name allow_virtual_network_access =true allow_gateway_transit = true allow_forwarded_traffic = true use_remote_gateways = false } resource "azurerm_virtual_network_peering" "spoke2_to_hub" { name = "spoke2-to-hub" remote_virtual_network_id = azurerm_virtual_network.hub_vnet.id virtual_network_name = azurerm_virtual_network.spoke2_vnet.name resource_group_name = data.azurerm_resource_group.myrg.name allow_virtual_network_access =true allow_gateway_transit = false allow_forwarded_traffic = true use_remote_gateways = false } resource "azurerm_public_ip" "pipip1" { allocation_method = "Static" location = data.azurerm_resource_group.myrg.location name = "pip1" resource_group_name = data.azurerm_resource_group.myrg.name } resource "azurerm_public_ip" "pipip2" { allocation_method = "Static" location = data.azurerm_resource_group.myrg.location name = "pip2" resource_group_name = data.azurerm_resource_group.myrg.name } resource "azurerm_network_interface" "nic1" { name = "nic1" resource_group_name = data.azurerm_resource_group.myrg.name location = data.azurerm_resource_group.myrg.location ip_configuration { name = "nic1-ip" private_ip_address_allocation = "Dynamic" subnet_id = azurerm_subnet.spoke1_subnet.id public_ip_address_id = azurerm_public_ip.pipip1.id } } resource "azurerm_network_interface" "nic2" { name = "nic2" resource_group_name = data.azurerm_resource_group.myrg.name location = data.azurerm_resource_group.myrg.location ip_configuration { name = "nic2-ip" private_ip_address_allocation = "Dynamic" subnet_id = azurerm_subnet.spoke2_subnet.id public_ip_address_id = azurerm_public_ip.pipip2.id } } resource "azurerm_linux_virtual_machine" "vm1" { name = "vm1" resource_group_name = data.azurerm_resource_group.myrg.name location = data.azurerm_resource_group.myrg.location size = "Standard_B2s" admin_username = "test" network_interface_ids = [ azurerm_network_interface.nic1.id, ] admin_ssh_key { username = "sharat" public_key = file("~/.ssh/id_rsa.pub") } os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "Canonical" offer = "0001-com-ubuntu-server-jammy" sku = "22_04-lts" version = "latest" } } resource "azurerm_linux_virtual_machine" "vm2" { name = "vm2" resource_group_name = data.azurerm_resource_group.myrg.name location = data.azurerm_resource_group.myrg.location size = "Standard_B2s" admin_username = "test" network_interface_ids = [ azurerm_network_interface.nic2.id, ] admin_ssh_key { username = "sharat" public_key = file("~/.ssh/id_rsa.pub") } os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "Canonical" offer = "0001-com-ubuntu-server-jammy" sku = "22_04-lts" version = "latest" } }
排查分析及解决方法
1. 跨Spoke通信的路由缺失
Azure VNet对等连接默认仅建立Hub与单个Spoke的通信路径,不会自动创建Spoke之间的路由。两个Spoke的虚拟机要互相通信,需要手动添加路由:
- 在spoke1的子网路由表中添加目标为
10.2.0.0/16(spoke2地址段)的路由,下一跳类型为VirtualNetworkPeering,指向Hub的VNet; - 在spoke2的子网路由表中添加目标为
10.1.0.0/16(spoke1地址段)的路由,下一跳类型同样为VirtualNetworkPeering,指向Hub的VNet。
2. 虚拟机内部防火墙限制
Ubuntu 22.04默认启用ufw防火墙,会拦截ICMP请求。可以通过以下命令临时关闭或开放ICMP:
# 关闭防火墙测试 sudo ufw disable # 或仅开放ICMP sudo ufw allow icmp
3. 对等连接配置验证
虽然现有对等连接的allow_forwarded_traffic已设为true,但需确保所有双向对等连接状态为已连接,可在Azure门户查看hub-to-spoke1、spoke1-to-hub、hub-to-spoke2、spoke2-to-hub这四个对等连接的状态,确认无配置错误。
修正后的Terraform配置示例
以下是添加路由表及关联的代码片段,可补充到现有Terraform配置中:
# Spoke1子网路由表及路由 resource "azurerm_route_table" "spoke1_rt" { name = "spoke1-rt" location = data.azurerm_resource_group.myrg.location resource_group_name = data.azurerm_resource_group.myrg.name } resource "azurerm_route" "spoke1_to_spoke2" { name = "spoke1-to-spoke2" resource_group_name = data.azurerm_resource_group.myrg.name route_table_name = azurerm_route_table.spoke1_rt.name address_prefix = "10.2.0.0/16" next_hop_type = "VirtualNetworkPeering" next_hop_in_ip_address = azurerm_virtual_network.hub_vnet.address_space[0] } resource "azurerm_subnet_route_table_association" "spoke1_subnet_rt" { subnet_id = azurerm_subnet.spoke1_subnet.id route_table_id = azurerm_route_table.spoke1_rt.id } # Spoke2子网路由表及路由 resource "azurerm_route_table" "spoke2_rt" { name = "spoke2-rt" location = data.azurerm_resource_group.myrg.location resource_group_name = data.azurerm_resource_group.myrg.name } resource "azurerm_route" "spoke2_to_spoke1" { name = "spoke2-to-spoke1" resource_group_name = data.azurerm_resource_group.myrg.name route_table_name = azurerm_route_table.spoke2_rt.name address_prefix = "10.1.0.0/16" next_hop_type = "VirtualNetworkPeering" next_hop_in_ip_address = azurerm_virtual_network.hub_vnet.address_space[0] } resource "azurerm_subnet_route_table_association" "spoke2_subnet_rt" { subnet_id = azurerm_subnet.spoke2_subnet.id route_table_id = azurerm_route_table.spoke2_rt.id }
内容的提问来源于stack exchange,提问作者Sharat Bhaskar
相关产品推荐
相关产品推荐

