为容器组的出站和入站流量配置单个公共 IP 地址

使用面向外部的 IP 地址设置容器组可以让外部客户端使用该 IP 地址访问组中的容器。 例如,浏览器可以访问在容器中运行的 Web 应用。 但在目前,容器组将另一 IP 地址用于出站流量。 此出口 IP 地址不以编程方式公开,这使得容器组监视与客户端防火墙规则配置变得更加复杂。

本文介绍如何通过相关步骤在集成了 Azure 防火墙虚拟网络中配置容器组。 通过设置通往容器组的用户定义的路由和防火墙规则,你可以路由并标识流入和流出该容器组的流量。 容器组入口和出口使用防火墙的公共 IP 地址。 在虚拟网络的子网(已委托到 Azure 容器实例)中部署的多个容器组可以使用单个出口 IP 地址。

本文使用 Azure CLI 为此方案创建资源:

  • 部署在虚拟网络的已委托子网中的容器组
  • 使用静态公共 IP 地址部署在网络中的 Azure 防火墙
  • 容器组的子网中的用户定义路由
  • 用于防火墙入口的 NAT 规则,以及用于出口的应用程序规则

然后通过防火墙验证示例容器组中的入口和出口。

如果没有 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

使用以下脚本通过其他订阅登录,将 <Subscription ID> 替换为 Azure 订阅 ID。 如果没有 Azure 试用版订阅,请在开始前创建一个试用版订阅

az cloud set -n AzureChinaCloud
az login

subscription="<subscriptionId>" # add subscription here

az account set -s $subscription # ...or use 'az login'

有关详细信息,请参阅设置有效的订阅登录

注意

若要下载完整脚本,请转到完整脚本

入门

本教程使用随机变量。 如果使用现有资源组,请相应地修改此变量的值。

resourceGroup=resourceGroup$RANDOM

Azure 资源组:如果你没有 Azure 资源组,请使用 az group create 命令创建一个资源组。 根据需要修改位置值。

az group create --name $resourceGroup --location chinaeast2

在虚拟网络中部署 ACI

通常情况下,你可能已经有一个要在其中部署容器组的 Azure 虚拟网络。 出于演示目的,在创建容器组后使用以下命令创建虚拟网络和子网。 此子网委托给 Azure 容器实例。

容器组从 aci-helloworld 映像运行小型 Web 应用。 如本文档中的其他文章所述,此映像会打包一个以 Node.js 编写的、可提供静态 HTML 页面的小型 Web 应用。

使用 az container create 命令创建容器组:

az container create \
  --name appcontainer \
  --resource-group $resourceGroup \
  --image mcr.microsoft.com/azuredocs/aci-helloworld \
  --vnet aci-vnet \
  --vnet-address-prefix 10.0.0.0/16 \
  --subnet aci-subnet \
  --subnet-address-prefix 10.0.0.0/24

提示

针对子网中你所需的 IP 地址空间调整 --subnet address-prefix 的值。 支持的最小子网为 /29,此子网提供八个 IP 地址。 某些 IP 地址已保留供 Azure 使用。

为了用于后面的步骤,请通过运行 [az container show][az-container-show] 命令获取容器组的专用 IP 地址:

aciPrivateIp="$(az container show --name appcontainer \
  --resource-group $resourceGroup \
  --query ipAddress.ip --output tsv)"

在网络中部署 Azure 防火墙

在以下部分,请使用 Azure CLI 在虚拟网络中部署 Azure 防火墙。 有关背景,请参阅教程:使用 Azure 门户部署和配置 Azure 防火墙

首先,使用 az network vnet subnet create 为防火墙添加名为 AzureFirewallSubnet 的子网。 AzureFirewallSubnet 是此子网的必需名称。

az network vnet subnet create \
  --name AzureFirewallSubnet \
  --resource-group $resourceGroup \
  --vnet-name aci-vnet   \
  --address-prefix 10.0.1.0/26

使用以下 Azure CLI 命令在子网中创建防火墙。

如果尚未安装,请使用 az extension add 命令将防火墙扩展添加到 Azure CLI:

az extension add --name azure-firewall

使用 az network firewall create 命令创建防火墙资源:

az network firewall create \
  --name myFirewall \
  --resource-group $resourceGroup \
  --location chinaeast2

az network public-ip create \
  --name fw-pip \
  --resource-group $resourceGroup \
  --location chinaeast2 \
  --allocation-method static \
  --sku standard

az network firewall ip-config create \
  --firewall-name myFirewall \
  --name FW-config \
  --public-ip-address fw-pip \
  --resource-group $resourceGroup \
  --vnet-name aci-vnet

使用 az network firewall update 命令更新防火墙配置:

az network firewall update \
  --name myFirewall \
  --resource-group $resourceGroup

使用 az network firewall ip-config list 命令获取防火墙的专用 IP 地址。 此专用 IP 地址在后面的命令中使用。

fwPrivateIp="$(az network firewall ip-config list \
  --resource-group $resourceGroup \
  --firewall-name myFirewall \
  --query "[].privateIpAddress" --output tsv)"

使用 az network public-ip show 命令获取防火墙的公共 IP 地址。 此公共 IP 地址在后面的命令中使用。

fwPublicIp="$(az network public-ip show \
  --name fw-pip \
  --resource-group $resourceGroup \
  --query ipAddress --output tsv)"

在 ACI 子网上定义用户定义的路由

在 ACI 子网上定义用户定义的路由,以将流量转到 Azure 防火墙。 有关详细信息,请参阅路由网络流量

创建路由表

首先,运行以下 az network route-table create 命令以创建路由表。 在虚拟网络所在的区域中创建路由表。

az network route-table create \
  --name Firewall-rt-table \
  --resource-group $resourceGroup \
  --location chinaeast2 \
  --disable-bgp-route-propagation true

创建路由

运行 az network-route-table route create 以在路由表中创建一个路由。 若要将流量路由到防火墙,请将下一跃点类型设置为 VirtualAppliance,并将防火墙的专用 IP 地址作为下一个跃点地址进行传递。

az network route-table route create \
  --resource-group $resourceGroup \
  --name DG-Route \
  --route-table-name Firewall-rt-table \
  --address-prefix 0.0.0.0/0 \
  --next-hop-type VirtualAppliance \
  --next-hop-ip-address $fwPrivateIp

将路由表关联到 ACI 子网

运行 az network vnet subnet update 命令,以将路由表与委托给 Azure 容器实例的子网相关联。

az network vnet subnet update \
  --name aci-subnet \
  --resource-group $resourceGroup \
  --vnet-name aci-vnet \
  --address-prefixes 10.0.0.0/24 \
  --route-table Firewall-rt-table

在防火墙上配置规则

默认情况下,Azure 防火墙拒绝(阻止)入站和出站流量。

在 ACI 子网的防火墙上配置 NAT 规则

在防火墙上创建一项 NAT 规则,用于转换和筛选发往此前在网络中启动的应用程序容器的入站 Internet 流量。 有关详细信息,请参阅通过 Azure 防火墙 DNAT 筛选入站 Internet 流量

使用 az network firewall nat-rule create 命令创建 NAT 规则和集合:

az network firewall nat-rule create \
  --firewall-name myFirewall \
  --collection-name myNATCollection \
  --action dnat \
  --name myRule \
  --protocols TCP \
  --source-addresses '*' \
  --destination-addresses $fwPublicIp \
  --destination-ports 80 \
  --resource-group $resourceGroup \
  --translated-address $aciPrivateIp \
  --translated-port 80 \
  --priority 200

根据需要添加 NAT 规则,筛选发往子网中的其他 IP 地址的流量。 例如,子网中的其他容器组可以为入站流量公开 IP 地址,或者,其他内部 IP 地址可以在重启后分配给该容器组。

在防火墙上创建出站应用程序规则

运行以下 az network firewall application-rule create 命令,以在防火墙上创建出站规则。 此示例规则允许从委托给 Azure 容器实例的子网访问 FQDN checkip.dyndns.org。 稍后的步骤中将使用对该站点的 HTTP 访问来确认 Azure 容器实例中的出口 IP 地址。

az network firewall application-rule create \
  --collection-name myAppCollection \
  --firewall-name myFirewall \
  --name Allow-CheckIP \
  --protocols Http=80 Https=443 \
  --resource-group $resourceGroup \
  --target-fqdns checkip.dyndns.org \
  --source-addresses 10.0.0.0/24 \
  --priority 200 \
  --action Allow

通过防火墙测试容器组访问权限

以下部分验证委托给 Azure 容器实例的子网是否已在 Azure 防火墙后面正确配置。 前面的步骤已通过防火墙路由了发往子网的传入流量和来自子网的传出流量。

测试容器组的入口

通过浏览到防火墙的公共 IP 地址,测试对虚拟网络中运行的 appcontainer 的入站访问。 以前,你已在变量 $FW_PUBLIC_IP 中存储公共 IP 地址:

echo $fwPublicIp

输出类似于:

52.142.18.133

如果正确配置了防火墙上的 NAT 规则,则当你在浏览器中输入防火墙的公共 IP 地址时,会看到以下内容:

Browse to firewall's public IP address

测试容器组的出口

将以下示例容器部署到虚拟网络中。 它在运行时会将单个 HTTP 请求发送到 http://checkip.dyndns.org,后者会显示发送方的 IP 地址(出口 IP 地址)。 如果正确配置了防火墙上的应用程序规则,则会返回防火墙的公共 IP 地址。

az container create \
  --resource-group $resourceGroup \
  --name testegress \
  --image mcr.microsoft.com/azuredocs/aci-tutorial-sidecar \
  --command-line "curl -s http://checkip.dyndns.org" \
  --restart-policy OnFailure \
  --vnet aci-vnet \
  --subnet aci-subnet

查看容器日志以确认此 IP 地址是否与防火墙的公共 IP 地址相同。

az container logs \
  --sed 's/$RESOURCE_GROUP_NAME/$resourceGroup/g'
  --name testegress 

输出类似于:

<html><head><title>Current IP Check</title></head><body>Current IP Address: 52.142.18.133</body></html>

清理资源

如果不再需要资源组和所有相关资源,可以使用 az group delete 命令将其删除,如下所示。 --no-wait 参数会使光标返回提示符处,无需等待操作完成。 --yes 参数将确认是否希望删除资源,而不会有额外提示。

az group delete --name $resourceGroup --yes --no-wait

后续步骤

本文介绍了如何在 Azure 防火墙后面的虚拟网络中设置容器组。 此外,还说明了如何在防火墙上配置用户定义的路由、NAT 和应用程序规则。 通过使用此配置,可以为 Azure 容器实例的入口和出口设置单个静态 IP 地址。

若要详细了解如何管理流量和保护 Azure 资源,请参阅 Azure 防火墙文档。