将容器实例部署到 Azure 虚拟网络

Azure 虚拟网络为 Azure 资源和本地资源提供安全的专用网络。 将容器组部署到 Azure 虚拟网络后,容器可与该虚拟网络中的其他资源安全通信。

本文演示如何在 Azure CLI 中使用 az container create 命令将容器组部署到新的虚拟网络或现有虚拟网络。

重要

  • 在使用虚拟网络之前,必须先委派子网
  • 在虚拟网络中部署容器组之前,建议先检查限制。 有关网络方案和限制,请参阅 Azure 容器实例的虚拟网络方案和资源
  • 虚拟网络中的容器组部署通常适用于大多数同时可使用 Azure 容器实例的区域中的 Linux 容器。 有关详细信息,请参阅 可用地区

重要

2021-07-01 API 版本起,网络配置文件已停用。 如果使用的是此版本或更新版本,请忽略与网络配置文件相关的任何步骤和操作。

本文中的示例已针对 Bash shell 设置了格式。 若要使用其他 shell(例如 PowerShell 或命令提示符),请相应地调整续行符。

先决条件

需要使用资源组来管理以下示例中使用的所有资源。 要创建资源组,请使用 az group create

az group create --name myResourceGroup --location chinaeast2

部署到新虚拟网络

注意

如果使用子网 IP 范围 /29,则只有 3 个 IP 地址。 建议始终高于一个范围(而绝不低于此范围)。 例如,使用子网 IP 范围 /28,这样每个容器组至少可以有 1 个或更多个 IP 缓冲区。 这样做可以避免容器处于卡滞、无法启动、重启,甚至无法停止的状态。

若要部署到新虚拟网络并让 Azure 自动创建网络资源,请在执行 az container create 时指定以下信息:

  • 虚拟网络名称
  • 采用 CIDR 格式的虚拟网络地址前缀
  • 子网名称
  • 采用 CIDR 格式的子网地址前缀

虚拟网络和子网地址前缀分别指定虚拟网络和子网的地址空间。 这些值以无类域间路由 (CIDR) 表示法表示,例如 10.0.0.0/16。 有关使用子网的详细信息,请参阅添加、更改或删除虚拟网络子网

使用此方法部署第一个容器组后,可以通过指定虚拟网络和子网名称或者 Azure 自动创建的网络配置文件,来部署到同一子网。 由于 Azure 将该子网委托给了 Azure 容器实例,因此只能将容器组部署到该子网。

示例

以下 az container create 命令指定新虚拟网络和子网的设置。 提供支持在虚拟网络中部署容器组的区域中创建的资源组的名称。 此命令将部署公共 Azure aci-helloworld 容器,该容器运行一个提供静态网页的小型 Node.js Web 服务器。 在下一部分,我们要将另一个容器组部署到同一子网,并测试这两个容器实例之间的通信。

az container create \
  --name appcontainer \
  --resource-group myResourceGroup \
  --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

使用此方法部署到新虚拟网络时,部署可能需要花费几分钟时间,因为在此期间需要创建网络资源。 完成初始部署后,对于同一子网的后续容器组部署可以更快地完成。

部署到现有虚拟网络

将容器组部署到现有虚拟网络:

  1. 在现有虚拟网络中创建子网,使用已在其中部署了容器组的现有子网,或使用已腾空了所有其他资源和配置的现有子网。用于容器组的子网只能包含容器组。 在将容器组部署到子网之前,必须在预配之前显式委托该子网。 委托后,该子网只可用于容器组。 如果尝试将除容器组以外的资源部署到委派的子网,该操作将会失败。
  2. 使用 az container create 部署容器组并指定以下信息之一:
    • 虚拟网络名称和子网名称
    • 虚拟网络资源 ID 和子网资源 ID,它允许使用其他资源组中的虚拟网络

示例

以下示例将第二个容器组部署到以前创建的同一子网,并验证两个容器实例之间的通信。

首先,获取部署的第一个容器组 appcontainer 的 IP 地址:

az container show --resource-group myResourceGroup \
  --name appcontainer \
  --query ipAddress.ip --output tsv

输出会显示专用子网中容器组的 IP 地址。 例如:

10.0.0.4

现在,请将 CONTAINER_GROUP_IP 设置为使用 az container show 命令检索到的 IP,并执行以下 az container create 命令。 这第二个容器 commchecker 运行基于 Alpine Linux 的映像,并针对第一个容器组的专用子网 IP 地址执行 wget

CONTAINER_GROUP_IP=<container-group-IP-address>

az container create \
  --resource-group myResourceGroup \
  --name commchecker \
  --image alpine:3.5 \
  --command-line "wget $CONTAINER_GROUP_IP" \
  --restart-policy never \
  --vnet aci-vnet \
  --subnet aci-subnet

完成第二个容器的部署后,请提取其日志,以查看它执行的 wget 命令的输出:

az container logs --resource-group myResourceGroup --name commchecker

如果第二个容器与第一个容器成功通信,则输出应类似于:

Connecting to 10.0.0.4 (10.0.0.4:80)
index.html           100% |*******************************|  1663   0:00:00 ETA

日志输出应显示 wget 可以在本地子网中使用第一个容器的专用 IP 地址连接到该容器,并可从中下载索引文件。 两个容器组之间的网络流量保留在虚拟网络中。

示例 - YAML

还可以通过使用 YAML 文件、资源管理器模板或其他编程方法(例如使用 Python SDK)将容器组部署到现有虚拟网络。

例如,使用 YAML 文件时,可以部署到具有委派给了 Azure 容器实例的子网的虚拟网络。 指定以下属性:

  • ipAddress:容器组的专用 IP 地址设置。
    • ports:要打开的端口(如果有)。
    • protocol:打开的端口的协议(TCP 或 UDP)。
  • subnetIds:要部署到的子网的资源 ID
    • id:子网的资源 ID
    • name:子网的名称

此 YAML 会在虚拟网络中创建名为 appcontaineryaml 的容器组。

apiVersion: '2021-07-01'
location: chinaeast2
name: appcontaineryaml
properties:
  containers:
  - name: appcontaineryaml
    properties:
      image: mcr.microsoft.com/azuredocs/aci-helloworld
      ports:
      - port: 80
        protocol: TCP
      resources:
        requests:
          cpu: 1.0
          memoryInGB: 1.5
  ipAddress:
    type: Private
    ports:
    - protocol: tcp
      port: '80'
  osType: Linux
  restartPolicy: Always
  subnetIds:
    - id: <subnet-id>
      name: default
tags: null
type: Microsoft.ContainerInstance/containerGroups

使用 az container create 命令并在 --file 参数中指定 YAML 文件名,以部署容器组:

az container create --resource-group myResourceGroup \
  --file vnet-deploy-aci.yaml

完成部署后,运行 az container show 命令以显示部署状态。 示例输出:

Name              ResourceGroup    Status    Image                                       IP:ports     Network    CPU/Memory       OsType    Location
---------------- ---------------  -------- ------------------------------------------  ----------- ---------  --------------- --------  ----------
appcontaineryaml  myResourceGroup  Running   mcr.microsoft.com/azuredocs/aci-helloworld  10.0.0.5:80  Private    1.0 core/1.5 gb  Linux     chinaeast2

清理资源

删除容器实例

处理完所创建的容器实例后,使用以下命令将其删除:

az container delete --resource-group myResourceGroup --name appcontainer -y
az container delete --resource-group myResourceGroup --name commchecker -y
az container delete --resource-group myResourceGroup --name appcontaineryaml -y

删除网络资源

此功能当前需要执行几个其他命令才能删除前面创建的网络资源。 如果你在本文的前面几个部分中使用示例命令创建了虚拟网络和子网,则可以使用以下脚本来删除这些网络资源。 该脚本假定你的资源组包含具有单个网络配置文件的单个虚拟网络。

执行该脚本之前,请将 RES_GROUP 变量设置为包含所要删除的虚拟网络和子网的资源组的名称。 如果未使用之前建议的 aci-vnet 名称,请更新虚拟网络的名称。 此脚本已针对 Bash Shell 格式化。 若要使用其他 shell(例如 PowerShell 或命令提示符),需要相应地调整变量赋值和访问器。

警告

此脚本会删除资源! 它会删除虚拟网络及其包含的所有子网。 运行此脚本之前,请确认你不再需要该虚拟网络中的任何资源,包括其中的任何子网。 一旦删除,这些资源就不可恢复

# Replace <my-resource-group> with the name of your resource group
# Assumes one virtual network in resource group
RES_GROUP=<my-resource-group>

# Get network profile ID
# Assumes one profile in virtual network
NETWORK_PROFILE_ID=$(az network profile list --resource-group $RES_GROUP --query [0].id --output tsv)

# Delete the network profile
az network profile delete --id $NETWORK_PROFILE_ID -y

# Delete virtual network
az network vnet delete --resource-group $RES_GROUP --name aci-vnet

后续步骤