Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
这些故障排除步骤适用于使用 Azure DocumentDB 迁移扩展或Azure门户中Azure 数据库迁移服务体验创建的基于Azure 数据库迁移服务的迁移。
Azure 数据库迁移服务(DMS)运行迁移,并管理源环境和 Azure Cosmos DB 之间的网络连接。 迁移作业失败时,请使用以下步骤跟踪网络连接中断的位置。 对于私有迁移,DMS 将为每个迁移作业创建专用临时虚拟网络,并在作业完成或失败时清除。 之后无法检查 DMS 虚拟网络,因此可以重现其网络位置来隔离故障。
验证先决条件
| 工具 | Purpose |
|---|---|
Azure CLI (az) |
查询Azure网络资源 |
| PowerShell 或 Bash | 运行验证脚本 |
nc (netcat) 或 Test-NetConnection |
测试 TCP 连接 |
| 网络参与者或读者 RBAC 角色 | 在相关虚拟网络上读取访问权限 |
公共连接验证
在公共模式下,DMS 使用迁移向导显示的静态 IP 通过公共 Internet 连接到源和目标。
验证源防火墙
查看源 MongoDB 防火墙配置,并确认它是否允许迁移向导中显示的每个 DMS 静态 IP 地址。
以下命令用于测试是否可从您的计算机访问该源终结点。 它们不会验证源防火墙是否允许 DMS 静态 IP 地址,因为连接源自计算机的出口地址。
# PowerShell
Test-NetConnection -ComputerName <SOURCE_PUBLIC_IP_OR_HOSTNAME> -Port 27017
# Bash / Linux
nc -zv <SOURCE_PUBLIC_IP_OR_HOSTNAME> 27017
预期:TcpTestSucceeded : True 或 Connection succeeded。
验证目标防火墙
列出 Azure DocumentDB 防火墙规则,并确认它们是否允许迁移向导中显示的每个 DMS 静态 IP 地址:
az documentdb mongocluster firewall-rule list \
--cluster-name "<CLUSTER_NAME>" \
--resource-group "<RESOURCE_GROUP>" \
--output table
以下命令测试是否可以从您的计算机连通目标终结点。 它不会验证来自 DMS 静态 IP 地址的连通性。
Test-NetConnection -ComputerName <DOCUMENTDB_HOSTNAME> -Port 10260
验证 DNS 解析
Resolve-DnsName <SOURCE_HOSTNAME>
Resolve-DnsName <DOCUMENTDB_HOSTNAME>
验证这两个主机名是否解析为 公共 IP。 私有 IP 响应表明存在私有 DNS 覆盖。
公共连接清单
| # | 检查 | 命令 | 预期 |
|---|---|---|---|
| 1 | 源防火墙允许 DMS IP | 查看源防火墙配置 | 每个 DMS IP 都位于允许列表中 |
| 2 | 目标防火墙允许 DMS IP 地址 | az documentdb mongocluster firewall-rule list |
每个 DMS IP 都位于允许列表中 |
| 3 | DNS 解析到公网 IP 地址 | Resolve-DnsName <hostname> |
返回的公网 IP |
| 4 | 可从您的计算机访问该源 | Test-NetConnection <source> -Port 27017 |
成功 |
| 5 | 可从您的计算机连接到目标 | Test-NetConnection <target> -Port 10260 |
成功 |
专用连接验证
专用连接验证有四个阶段:验证基础结构、生成模拟环境、测试模拟的连接以及清理。
阶段 1:验证基础结构
Azure中的源
验证源终结点和目标专用终结点:
# Check source private endpoints
az network private-endpoint list \
--subscription "<SUBSCRIPTION>" -g "<SOURCE_RG>" \
--query "[].{Name:name,Subnet:subnet.id,Status:privateLinkServiceConnections[0].privateLinkServiceConnectionState.status}" \
-o table
# Check target private endpoints
az network private-endpoint list \
--subscription "<SUBSCRIPTION>" -g "<TARGET_RG>" \
--query "[].{Name:name,Subnet:subnet.id,Status:privateLinkServiceConnections[0].privateLinkServiceConnectionState.status}" \
-o table
预期: 两者的状态均 = Approved。
检查虚拟网络与 DMS CIDR 之间的 CIDR 重叠情况:
echo "=== Source VNet ==="
az network vnet show --subscription "<SUB>" -g "<SOURCE_RG>" -n "<SOURCE_VNET>" \
--query "addressSpace.addressPrefixes" -o tsv
echo "=== Target VNet ==="
az network vnet show --subscription "<SUB>" -g "<TARGET_RG>" -n "<TARGET_VNET>" \
--query "addressSpace.addressPrefixes" -o tsv
预期: 在向导中选择的 DMS CIDR 不得与任一虚拟网络重叠。
标识与每个源和目标子网关联的 NSG:
az network vnet subnet show \
--subscription "<SUB>" -g "<SOURCE_RG>" \
--vnet-name "<SOURCE_VNET>" -n "<SOURCE_SUBNET>" \
--query "networkSecurityGroup.id" -o tsv
az network vnet subnet show \
--subscription "<SUB>" -g "<TARGET_RG>" \
--vnet-name "<TARGET_VNET>" -n "<TARGET_SUBNET>" \
--query "networkSecurityGroup.id" -o tsv
列出两个资源组中的 NSG,并检查上述命令返回的 NSG 的规则:
az network nsg list \
--subscription "<SUB>" -g "<SOURCE_RG>" \
--query "[].{Name:name,Rules:securityRules[?direction=='Inbound'].{Rule:name,Priority:priority,Access:access,Source:sourceAddressPrefix,Port:destinationPortRange}}" \
-o json
az network nsg list \
--subscription "<SUB>" -g "<TARGET_RG>" \
--query "[].{Name:name,Rules:securityRules[?direction=='Inbound'].{Rule:name,Priority:priority,Access:access,Source:sourceAddressPrefix,Port:destinationPortRange}}" \
-o json
验证: 没有 Deny 规则阻止 MongoDB 端口(默认 27017)或 DocumentDB 端口(默认为 10260)上的 DMS 虚拟网络 CIDR。
验证专用 DNS 区域配置:
# Check private DNS zones
az network private-dns zone list \
--subscription "<SUB>" \
--query "[?contains(name,'mongo') || contains(name,'cosmos') || contains(name,'documentdb')].{Zone:name,RecordSets:numberOfRecordSets}" \
-o table
# Verify DNS zone is linked to relevant VNets
az network private-dns link vnet list \
--subscription "<SUB>" -g "<DNS_ZONE_RG>" -z "<ZONE_NAME>" \
--query "[].{Link:name,VNet:virtualNetwork.id,AutoReg:registrationEnabled}" \
-o table
Azure 到 Azure 清单:
| # | 检查 | 预期 |
|---|---|---|
| 1 | 源专用终结点状态 | Approved |
| 2 | 目标专用终结点状态 | Approved |
| 3 | 虚拟网络与 DMS CIDR 之间没有 CIDR 重叠 | 不同的地址范围 |
| 4 | NSG 允许在所需端口上使用 DMS CIDR | 无阻止 Deny 规则 |
| 5 | 链接到你的虚拟网络的专用 DNS 区域 | 区域已关联,记录可解析 |
本地或其他云的源
验证 VPN/ExpressRoute 隧道:
# For VPN Gateway
az network vpn-connection list \
--subscription "<SUB>" -g "<GATEWAY_RG>" \
--query "[].{Name:name,Status:connectionStatus,IngressBytes:ingressBytesTransferred,EgressBytes:egressBytesTransferred}" \
-o table
预期:connectionStatus = Connected,字节数随时间增加。
# For ExpressRoute
az network express-route show \
--subscription "<SUB>" -g "<GATEWAY_RG>" -n "<ER_CIRCUIT_NAME>" \
--query "{Name:name,State:serviceProviderProvisioningState,PeeringState:peerings[0].state}" \
-o table
必须将 DMS 虚拟网络 CIDR 通告到远程网络,并验证 BGP 路由通告:
az network vnet-gateway list-advertised-routes \
--subscription "<SUB>" -g "<GATEWAY_RG>" -n "<VPN_GATEWAY_NAME>" \
--peer <REMOTE_BGP_PEER_IP> -o table
验证 DMS 虚拟网络 CIDR 是否显示在输出中。 如果未设置,请在网关虚拟网络对等互连中设置 allowGatewayTransit=true。
根据拓扑验证路由:
-
单个虚拟网络(无中心辐射): 在虚拟网络对等互连上验证
allowGatewayTransit=true。 - 中心直接: 与单个虚拟网络相同,但检查中心虚拟网络对等互连。
- TCP 代理:如果 DMS 只能与某个辐射网络建立对等互连,且无法直接与中心网络建立对等互连,请在与 DMS 对等互连的虚拟网络中部署 MongoDB 迁移代理 虚拟机。 代理通过现有的 VPN/ExpressRoute 路径将来自 DMS 的流量转发到源 MongoDB 服务器。 将 DMS 迁移作业配置为使用代理 VM 的私有 IP 和监听端口作为源端点。
# Check VNet peering configuration
az network vnet peering list \
--subscription "<SUB>" -g "<YOUR_VNET_RG>" --vnet-name "<YOUR_VNET>" \
--query "[].{Name:name,State:peeringState,AllowGatewayTransit:allowGatewayTransit}" \
-o table
Important
虚拟网络对等互连不具有传递性。 如果 DMS 与辐射型虚拟网络建立对等互连,则它无法自动连接到中心的 VPN 网关。 若要使 DMS 流量到达本地或其他云中的源,您需要具备以下两者之一:直接与中心虚拟网络对等互连(这样 DMS 就可以通过 useRemoteGateways 原生使用 VPN 网关),或者在与 DMS 对等互连的虚拟网络中部署一个 TCP 代理,通过您现有的网络路径将流量转发到源。
本地或其他云网络必须具有 DMS 虚拟网络 CIDR 的返回路由,验证远程返回路由。 对于 AWS:
aws ec2 describe-route-tables --region <REGION> \
--route-table-ids <ROUTE_TABLE_ID> \
--query "RouteTables[0].Routes[?GatewayId!=null && starts_with(GatewayId,'vgw')].{Destination:DestinationCidrBlock,Gateway:GatewayId,State:State}" \
--output table
对于本地路由器,请验证 DMS CIDR 是否显示在 BGP 路由表中。
远端还必须允许来自 DMS 虚拟网络 CIDR 的 入站 流量通过所需端口(默认情况下,MongoDB 为 27017)。
DMS 为每个迁移作业创建一个具有动态 CIDR 的新虚拟网络。 配置远程防火墙规则时,请使用迁移向导中显示的特定 DMS CIDR。
本地/其他云清单:
| # | 检查 | 预期 |
|---|---|---|
| 1 | VPN/ExpressRoute 隧道状态 |
Connected、字节流动 |
| 2 | Azure通过 BGP 播发 DMS CIDR | 通告路由中的 DMS CIDR |
| 3 | 虚拟网络对等互连允许网关传输 | allowGatewayTransit=true |
| 4 | 远程端具有 DMS CIDR 的返回路由 | 路由表中存在的路由 |
| 5 | 远程防火墙/SG 允许 DMS CIDR | 所需端口上的入站规则 |
| 6 | 目标专用终结点状态 | Approved |
阶段 2:生成模拟环境
DMS 为每个迁移作业创建一个临时虚拟网络,并在作业完成或失败时将其删除。 若要从 DMS 网络所在位置测试连通性,请创建一个具有相同 CIDR 的用于模拟的虚拟网络,将其与您的各个网络建立对等互连,并部署一台测试 VM。
从现有网关或辐射型虚拟网络中的 VM 进行测试,只能确认 VPN 可正常工作。 它并不证明源自 DMS CIDR 的流量可以正确路由。 模拟虚拟网络复制 DMS 的确切网络位置,因此来自它的连接测试反映实际迁移流量。
创建测试虚拟网络
在 DMS 迁移向导中,使用您已提供(或计划提供)的相同 CIDR:
SUBSCRIPTION="<YOUR_SUBSCRIPTION>"
TEST_RG="dms-network-test-rg"
LOCATION="<SAME_REGION_AS_DMS>"
DMS_CIDR="<DMS_CIDR_FROM_WIZARD>"
TEST_VNET="dms-test-vnet"
TEST_SUBNET="default"
TEST_SUBNET_CIDR="<SUBNET_WITHIN_DMS_CIDR>"
az group create --subscription "$SUBSCRIPTION" -n "$TEST_RG" -l "$LOCATION"
az network vnet create --subscription "$SUBSCRIPTION" \
-g "$TEST_RG" -n "$TEST_VNET" \
--address-prefix "$DMS_CIDR" \
--subnet-name "$TEST_SUBNET" --subnet-prefix "$TEST_SUBNET_CIDR" \
-l "$LOCATION"
与测试虚拟网络建立对等互连
创建与 DMS 所执行操作相对应的对等互连。 选择符合您的拓扑的对等互连。
对于单个虚拟网络或中心直连(VPN/ExpressRoute 场景):
HUB_RG="<HUB_OR_SINGLE_VNET_RESOURCE_GROUP>"
HUB_VNET="<HUB_OR_SINGLE_VNET_NAME>"
TEST_VNET_ID=$(az network vnet show --subscription "$SUBSCRIPTION" \
-g "$TEST_RG" -n "$TEST_VNET" --query id -o tsv)
HUB_VNET_ID=$(az network vnet show --subscription "$SUBSCRIPTION" \
-g "$HUB_RG" -n "$HUB_VNET" --query id -o tsv)
# Gateway VNet → Test VNet
az network vnet peering create --subscription "$SUBSCRIPTION" \
-g "$HUB_RG" --vnet-name "$HUB_VNET" \
-n "hub-to-dms-test" --remote-vnet "$TEST_VNET_ID" \
--allow-vnet-access true --allow-forwarded-traffic true --allow-gateway-transit true
# Test VNet → Gateway VNet
az network vnet peering create --subscription "$SUBSCRIPTION" \
-g "$TEST_RG" --vnet-name "$TEST_VNET" \
-n "dms-test-to-hub" --remote-vnet "$HUB_VNET_ID" \
--allow-vnet-access true --allow-forwarded-traffic true --use-remote-gateways true
对于Azure中的源(无需 VPN):
SOURCE_RG="<SOURCE_RESOURCE_GROUP>"
SOURCE_VNET="<SOURCE_VNET_NAME>"
SOURCE_VNET_ID=$(az network vnet show --subscription "$SUBSCRIPTION" \
-g "$SOURCE_RG" -n "$SOURCE_VNET" --query id -o tsv)
TEST_VNET_ID=$(az network vnet show --subscription "$SUBSCRIPTION" \
-g "$TEST_RG" -n "$TEST_VNET" --query id -o tsv)
az network vnet peering create --subscription "$SUBSCRIPTION" \
-g "$SOURCE_RG" --vnet-name "$SOURCE_VNET" \
-n "source-to-dms-test" --remote-vnet "$TEST_VNET_ID" \
--allow-vnet-access true --allow-forwarded-traffic true
az network vnet peering create --subscription "$SUBSCRIPTION" \
-g "$TEST_RG" --vnet-name "$TEST_VNET" \
-n "dms-test-to-source" --remote-vnet "$SOURCE_VNET_ID" \
--allow-vnet-access true --allow-forwarded-traffic true
与源虚拟网络不同时,与目标虚拟网络对等互连:
如果源和目标使用相同的虚拟网络,请跳过此块。 源对等互连已将公共虚拟网络连接到测试虚拟网络,Azure不允许同一虚拟网络对之间的第二个对等互连。
TARGET_RG="<TARGET_RESOURCE_GROUP>"
TARGET_VNET="<TARGET_VNET_NAME>"
TARGET_VNET_ID=$(az network vnet show --subscription "$SUBSCRIPTION" \
-g "$TARGET_RG" -n "$TARGET_VNET" --query id -o tsv)
az network vnet peering create --subscription "$SUBSCRIPTION" \
-g "$TARGET_RG" --vnet-name "$TARGET_VNET" \
-n "target-to-dms-test" --remote-vnet "$TEST_VNET_ID" \
--allow-vnet-access true --allow-forwarded-traffic true
az network vnet peering create --subscription "$SUBSCRIPTION" \
-g "$TEST_RG" --vnet-name "$TEST_VNET" \
-n "dms-test-to-target" --remote-vnet "$TARGET_VNET_ID" \
--allow-vnet-access true --allow-forwarded-traffic true
验证对等互连
az network vnet peering list --subscription "$SUBSCRIPTION" \
-g "$TEST_RG" --vnet-name "$TEST_VNET" \
--query "[].{Name:name,State:peeringState,UseRemoteGateways:useRemoteGateways}" \
-o table
预期: 所有对等互连都显示 peeringState = Connected。
部署测试 VM
az vm create --subscription "$SUBSCRIPTION" \
-g "$TEST_RG" -n "dms-test-vm" \
--image Ubuntu2204 --size Standard_B2s \
--vnet-name "$TEST_VNET" --subnet "$TEST_SUBNET" \
--admin-username azureuser --generate-ssh-keys \
--public-ip-address "" --no-wait
VM 没有公共 IP。 通过 Azure Bastion、串行控制台或 az vm run-command invoke 访问它。
阶段 3:测试模拟 VM 的连接
在测试 VM 中使用 az vm run-command invoke 运行以下命令。
测试 DNS 解析
az vm run-command invoke --subscription "$SUBSCRIPTION" \
-g "$TEST_RG" -n "dms-test-vm" \
--command-id RunShellScript \
--scripts "nslookup <SOURCE_HOSTNAME> && echo '---' && nslookup <TARGET_DOCUMENTDB_HOSTNAME>"
预期结果: 两者都解析为 私有 IP。 如果任一 IP 解析为公共 IP,请将专用 DNS 区域链接到测试虚拟网络。
测试 TCP 连接
# Source MongoDB
az vm run-command invoke --subscription "$SUBSCRIPTION" \
-g "$TEST_RG" -n "dms-test-vm" \
--command-id RunShellScript \
--scripts "nc -zv -w 10 <SOURCE_PRIVATE_IP_OR_HOSTNAME> 27017 2>&1"
# Target DocumentDB
az vm run-command invoke --subscription "$SUBSCRIPTION" \
-g "$TEST_RG" -n "dms-test-vm" \
--command-id RunShellScript \
--scripts "nc -zv -w 10 <TARGET_DOCUMENTDB_HOSTNAME> 10260 2>&1"
预期:Connection … succeeded,两者均为。
使用 mongosh 进行测试
通过Azure Bastion或其他安全管理连接以交互方式连接到测试 VM。 不要在 az vm run-command 脚本中传递凭据,因为 Azure 可以在调用日志中记录脚本及其参数。
在测试 VM 上安装 mongosh:
sudo apt-get update -qq && sudo apt-get install -y -qq gnupg curl
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
sudo gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg
echo 'deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse' | \
sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt-get update -qq && sudo apt-get install -y -qq mongosh
为每个连接字符串提示输入凭据,以便凭据不会存储在 shell 历史记录中。 使用启用 TLS 并验证服务器证书的连接字符串。 不要添加 tlsAllowInvalidCertificates=true。
read -rsp "Source MongoDB connection string: " SOURCE_URI
echo
mongosh "$SOURCE_URI" --eval 'db.runCommand({ping:1})'
unset SOURCE_URI
read -rsp "Target Azure DocumentDB connection string: " TARGET_URI
echo
mongosh "$TARGET_URI" --eval 'db.runCommand({ping:1})'
unset TARGET_URI
预期:{ ok: 1 },两者均为。 如果 nc 成功但 mongosh 失败,则网络正常运行,问题可能与身份验证凭据或 TLS 配置相关。
解读结果
| Result | Meaning | Action |
|---|---|---|
对等互连状态 = Disconnected |
CIDR 重叠或虚拟网络配置问题 | 检查是否存在重叠的地址空间 |
nc 到源超时 |
流量被阻止或未路由 | 检查防火墙规则、返回路由、NSG |
nc 成功, mongosh TLS 错误 |
TLS/证书不匹配 | 检查 tls=true 和证书设置 |
nc 成功, mongosh 身份验证错误 |
凭据错误 | 验证用户名/密码和身份验证数据库 |
| DNS 解析为公共 IP | 专用 DNS 区域未链接 | 将 DNS 区域链接到测试虚拟网络 |
源 CIDR 的有效路由显示None |
无到源的路由 | 检查 VPN 网关/对等互连配置 |
如果所有测试都通过,但迁移作业仍然失败,则问题可能在于 DMS 管理的组件,而不是基础结构。 请联系 Azure 技术支持,并提供这些测试结果,以便加快故障排除过程。
阶段 4:清理
Important
在重试迁移作业 之前 清理模拟虚拟网络和 VM。 如果它们仍然存在,则 DMS 由于 IP 地址冲突而无法创建自己的虚拟网络和 VM。
# Remove the test resource group (includes the test VNet and VM)
az group delete --subscription "$SUBSCRIPTION" -n "$TEST_RG" --yes
# Remove peerings on your existing VNets
az network vnet peering delete --subscription "$SUBSCRIPTION" \
-g "<HUB_RG>" --vnet-name "<HUB_VNET>" -n "hub-to-dms-test" 2>/dev/null
az network vnet peering delete --subscription "$SUBSCRIPTION" \
-g "<SOURCE_RG>" --vnet-name "<SOURCE_VNET>" -n "source-to-dms-test" 2>/dev/null
az network vnet peering delete --subscription "$SUBSCRIPTION" \
-g "<TARGET_RG>" --vnet-name "<TARGET_VNET>" -n "target-to-dms-test" 2>/dev/null
常见连接问题
| Issue | 症状 | 解决方案 |
|---|---|---|
| DMS CIDR 未通过 BGP 通告 | VPN 已启动,但迁移报告连接错误 | 在网关虚拟网络对等互连上启用 allowGatewayTransit=true |
| 远程防火墙阻止 DMS CIDR | 其他 Azure 虚拟网络可以访问源,但 DMS 连接超时 | 将向导中的 DMS CIDR 添加到远端防火墙规则中 |
| 代理 NSG 阻止 DMS CIDR | 代理可以访问源端,但 DMS 向代理发出的请求会超时 | 在与代理 VM 网络接口或子网关联的 NSG 中,添加允许从迁移向导中提供的 DMS CIDR 到代理侦听端口的 TCP 流量的入站规则 |
| 缺少返回路由 | 流量离开Azure但永远不会返回;连接超时 | 在远程路由表上启用路由传播,或为 DMS CIDR 添加静态路由 |
| 专用终结点未获批准 | DNS 解析但连接被拒绝 | 在门户或 CLI 中批准专用终结点连接 |
| DNS 无法正确解析 | 主机名解析为公共 IP 而不是专用 IP | 将专用 DNS 区域链接到用于迁移的虚拟网络 |
| CIDR 重叠 | 虚拟网络对等互连失败或一直处于 Disconnected |
选择不与现有虚拟网络冲突的 DMS CIDR |
| 资源锁阻止对等互连清理 | 使用相同 CIDR 的新迁移任务会失败,因为之前作业中的源到 DMS 或目标到 DMS 的对等连接仍然存在 | 从源虚拟网络或目标虚拟网络中删除锁,或者从任一资源组中删除锁,删除残留的对等互连,然后重试迁移 |
| 用于多个专用作业的单个虚拟网络 | 第二个任务失败或干扰第一个任务 | 为每个并发迁移作业使用不同的虚拟网络 |