使用 Azure CLI 通过路由表路由网络流量

默认情况下,Azure 自动在虚拟网络中的所有子网之间路由流量。 可以创建自己的路由来覆盖 Azure 的默认路由。 创建自定义路由的功能非常有用,例如,可以通过网络虚拟设备 (NVA) 在子网之间路由流量。 在本文中,学习如何:

  • 创建路由表
  • 创建路由
  • 创建包含多个子网的虚拟网络
  • 将路由表关联到子网
  • 创建从 Ubuntu VM 路由流量的基本 NVA
  • 将虚拟机 (VM) 部署到不同子网
  • 通过 NVA 将从一个子网的流量路由到另一个子网

如果没有 Azure 试用版订阅,请在开始前创建一个试用版订阅

先决条件

  • 如需在本地运行 CLI 参考命令,请安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行 Azure CLI。 有关详细信息,请参阅如何在 Docker 容器中运行 Azure CLI

    • 如果使用的是本地安装,请使用 az login 命令登录到 Azure CLI。 若要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅使用 Azure CLI 登录

    • 出现提示时,请在首次使用时安装 Azure CLI 扩展。 有关扩展详细信息,请参阅使用 Azure CLI 的扩展

    • 运行 az version 以查找安装的版本和依赖库。 若要升级到最新版本,请运行 az upgrade

  • 本文需要 Azure CLI 2.0.28 或更高版本。

注意

在可以在由世纪互联运营的 Microsoft Azure 中使用 Azure CLI 之前,请先运行 az cloud set -n AzureChinaCloud 来更改云环境。 若要切换回 Azure 公有云,请再次运行 az cloud set -n AzureCloud

创建路由表

在创建路由表之前,请使用 az group create 针对本文中创建的所有资源创建一个资源组。

# Create a resource group.
az group create \
  --name test-rg \
  --location chinaeast

使用 az network route-table create 创建路由表。 以下示例创建名为 route-table-public 的路由表

# Create a route table
az network route-table create \
  --resource-group test-rg \
  --name route-table-public

创建路由

使用 az network route-table route create 在路由表中创建路由。

az network route-table route create \
  --name to-private-subnet \
  --resource-group test-rg \
  --route-table-name route-table-public \
  --address-prefix 10.0.1.0/24 \
  --next-hop-type VirtualAppliance \
  --next-hop-ip-address 10.0.2.4

将路由表关联到子网

将路由表关联到子网之前,必须先创建虚拟网络和子网。 使用 az network vnet create 创建包含一个子网的虚拟网络。

az network vnet create \
  --name vnet-1 \
  --resource-group test-rg \
  --address-prefix 10.0.0.0/16 \
  --subnet-name subnet-public \
  --subnet-prefix 10.0.0.0/24

使用 az network vnet subnet create 再创建两个子网。

# Create a private subnet.
az network vnet subnet create \
  --vnet-name vnet-1 \
  --resource-group test-rg \
  --name subnet-private \
  --address-prefix 10.0.1.0/24

# Create a DMZ subnet.
az network vnet subnet create \
  --vnet-name vnet-1 \
  --resource-group test-rg \
  --name subnet-dmz \
  --address-prefix 10.0.2.0/24

使用 az network vnet subnet update 将 route-table-subnet-public 路由表关联到 subnet-public 子网

az network vnet subnet update \
  --vnet-name vnet-1 \
  --name subnet-public \
  --resource-group test-rg \
  --route-table route-table-public

创建 NVA

NVA 是执行网络功能(如路由、防火墙或 WAN 优化)的 VM。 我们从常规用途 Ubuntu VM 创建一个基本的 NVA,以用于演示目的。

使用 az vm create 在 subnet-dmz 子网中创建要用作 NVA 的 VM。 创建 VM 时,Azure 默认会创建网络接口 vm-nvaVMNic 和 subnet-public IP 地址并将其分配到该 VM。 --public-ip-address "" 参数指示 Azure 不要创建 subnet-public IP 地址并将其分配到该 VM,因为不需要从 Internet 连接到该 VM。

以下示例将创建 VM 并添加用户帐户。 --generate-ssh-keys 参数会导致 CLI 在 ~/.ssh 中查找可用的 ssh 密钥。 如果找到一个,则使用此密钥。 否则,将会生成一个密钥并存储在 ~/.ssh 中。 最后,我们将部署最新的 Ubuntu 22.04 映像。

az vm create \
  --resource-group test-rg \
  --name vm-nva \
  --image Ubuntu2204 \
  --public-ip-address "" \
  --subnet subnet-dmz \
  --vnet-name vnet-1 \
  --generate-ssh-keys

创建 VM 需要几分钟时间。 在 Azure 完成创建 VM 并返回有关 VM 的输出之前,请不要继续下一步。

要使网络接口 vm-nvaVMNic 能够转发发送给它的而不是发往其自身 IP 地址的网络流量,必须为该网络接口启用 IP 转发。 使用 az network nic update 为网络接口启用 IP 转发。

az network nic update \
  --name vm-nvaVMNic \
  --resource-group test-rg \
  --ip-forwarding true

在 VM 中,VM 中运行的操作系统或应用程序也必须能够转发网络流量。 我们使用 sysctl 命令使 Linux 内核能够转发数据包。 若要在不登录到 VM 的情况下运行此命令,我们使用自定义脚本扩展 az vm extension set

az vm extension set \
  --resource-group test-rg \
  --vm-name vm-nva \
  --name customScript \
  --publisher Microsoft.Azure.Extensions \
  --settings '{"commandToExecute":"sudo sysctl -w net.ipv4.ip_forward=1"}'

执行该命令最长可能需要花费一分钟时间。 此更改在 VM 重启后不会保留,因此,如果 NVA VM 出于任何原因重新启动,则需要重复该脚本。

创建虚拟机

在虚拟网络中创建两个 VM,使你可在后续步骤中验证来自 subnet-public 子网的流量是否通过 NVA 路由到 subnet-private 子网。

使用 az vm create 在 subnet-public 子网中创建一个 VM。 --no-wait 参数支持 Azure 在后台中执行命令,因此可以继续执行下一个命令。

以下示例将创建 VM 并添加用户帐户。 --generate-ssh-keys 参数会导致 CLI 在 ~/.ssh 中查找可用的 ssh 密钥。 如果找到一个,则使用此密钥。 否则,将会生成一个密钥并存储在 ~/.ssh 中。 最后,我们将部署最新的 Ubuntu 22.04 映像。

az vm create \
  --resource-group test-rg \
  --name vm-public \
  --image Ubuntu2204 \
  --vnet-name vnet-1 \
  --subnet subnet-public \
  --admin-username azureuser \
  --generate-ssh-keys \
  --no-wait

在 subnet-private 子网中创建一个 VM

az vm create \
  --resource-group test-rg \
  --name vm-private \
  --image Ubuntu2204 \
  --vnet-name vnet-1 \
  --subnet subnet-private \
  --admin-username azureuser \
  --generate-ssh-keys

创建 VM 需要几分钟时间。 创建 VM 之后,Azure CLI 将显示类似于以下示例的信息:

{
  "fqdns": "",
  "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Compute/virtualMachines/vm-private",
  "location": "chinaeast",
  "macAddress": "00-0D-3A-23-9A-49",
  "powerState": "VM running",
  "privateIpAddress": "10.0.1.4",
  "publicIpAddress": "203.0.113.24",
  "resourceGroup": "test-rg"
}

为虚拟机启用 Microsoft Entra ID 登录

以下代码示例安装该扩展,为 Linux VM 启用 Microsoft Entra ID 登录。 VM 扩展是小型应用程序,可在 Azure 虚拟机上提供部署后配置和自动化任务。

az vm extension set \
    --publisher Microsoft.Azure.ActiveDirectory \
    --name AADSSHsign-inForLinux \
    --resource-group test-rg \
    --vm-name vm-private
az vm extension set \
    --publisher Microsoft.Azure.ActiveDirectory \
    --name AADSSHsign-inForLinux \
    --resource-group test-rg \
    --vm-name vm-public

通过 NVA 路由流量

使用所选的 SSH 客户端连接到之前创建的 VM。 例如,可从命令行接口(如 适用于 Linux 的 Windows 子系统)使用以下命令创建与 vm-private VM 的 SSH 会话。 在前面的步骤中,我们为 VM 启用了 Microsoft Entra ID 登录。 可使用 Microsoft Entra ID 凭据登录到虚拟机,也可使用用于创建 VM 的 SSH 密钥。 在以下示例中,我们使用 SSH 密钥登录到 VM。

有关如何通过 SSH 连接到 Linux VM 并使用 Microsoft Entra ID 登录的详细信息,请参阅使用 Microsoft Entra ID 和 OpenSSH 登录到 Azure 中的 Linux 虚拟机


### Store IP address of VM in order to SSH

Run the following command to store the IP address of the VM as an environment variable:

```bash
export IP_ADDRESS=$(az vm show --show-details --resource-group test-rg --name vm-private --query publicIps --output tsv)
ssh -o StrictHostKeyChecking=no azureuser@$IP_ADDRESS

使用以下命令在 vm-private VM 上安装跟踪路由

sudo apt update
sudo apt install traceroute

使用以下命令测试从 vm-private VM 发往 vm-public VM 的网络流量的路由

traceroute vm-public

其响应类似于如下示例:

azureuser@vm-private:~$ traceroute vm-public
traceroute to vm-public (10.0.0.4), 30 hops max, 60 byte packets
 1  vm-public.internal.chinacloudapp.cn (10.0.0.4)  2.613 ms  2.592 ms  2.553 ms

可看到流量从 vm-private VM 直接路由到 vm-public VM。 Azure 的默认路由,直接在子网之间路由流量。 关闭与 vm-private VM 的 SSH 会话

存储 VM 的 IP 地址,以通过 SSH 进行连接

运行以下命令以将 VM 的 IP 地址存储为环境变量:

export IP_ADDRESS=$(az vm show --show-details --resource-group test-rg --name vm-public --query publicIps --output tsv)
ssh -o StrictHostKeyChecking=no azureuser@$IP_ADDRESS

使用以下命令在 vm-public VM 上安装跟踪路由

sudo apt update
sudo apt install traceroute

使用以下命令测试从 vm-public VM 发往 vm-private VM 的网络流量的路由

traceroute vm-private

其响应类似于如下示例:

azureuser@vm-public:~$ traceroute vm-private
traceroute to vm-private (10.0.1.4), 30 hops max, 60 byte packets
 1  vm-nva.internal.chinacloudapp.cn (10.0.2.4)  1.010 ms  1.686 ms  1.144 ms
 2  vm-private.internal.chinacloudapp.cn (10.0.1.4)  1.925 ms  1.911 ms  1.898 ms

可以看到,第一个跃点为 10.0.2.4,即 NVA 的专用 IP 地址。 第二个跃点为 10.0.1.4,即 vm-private VM 的专用 IP 地址。 添加到 route-table--public 路由表并关联到 subnet-public 子网的路由导致 Azure 通过 NVA 路由流量,而不是直接将流量路由到 subnet-private 子网

关闭与 vm-public VM 的 SSH 会话

清理资源

如果不再需要资源组及其包含的所有资源,可以使用 az group delete 将其删除。

az group delete \
    --name test-rg \
    --yes \
    --no-wait

后续步骤

在本文中,我们创建了一个路由表并将其关联到了某个子网。 还创建了一个简单 NVA,用于将流量从 subnet-public 子网路由到专用子网。 从 Azure 市场部署各种执行网络功能(例如防火墙和 WAN 优化)的预配置 NVA。 若要了解有关路由的详细信息,请参阅路由概述管理路由表

尽管可在一个虚拟网络中部署多个 Azure 资源,但无法将某些 Azure PaaS 服务的资源部署到虚拟网络。 不过,仍可以限制为只允许来自某个虚拟网络子网的流量访问某些 Azure PaaS 服务的资源。 若要了解如何操作,请参阅限制对 PaaS 资源的网络访问