创建具有多个网络接口的实例

本页面介绍了如何配置具有多个网络接口的虚拟机 (VM) 实例。

默认情况下,VPC 网络中的每个实例都有一个网络接口。您可以按照如下说明来创建额外的网络接口。每个接口都连接到不同的 VPC 网络,让该实例可访问 Google Cloud 中的不同 VPC 网络。您不能将多个网络接口连接到同一个 VPC 网络。

如果您不需要额外的网络接口,请按照创建和启动实例中的说明进行操作。

如需详细了解多个网络接口及其具体工作方式,请参阅多个网络接口

规格

要求

  • 您只能在创建实例时配置网络接口。

  • 在单个实例中配置的每个网络接口都必须连接到不同的 VPC 网络,并且每个接口都必须属于 IP 范围不与任何其他接口的子网重叠的子网内。连接的网络可以是独立的 VPC 网络,也可以是共享 VPC 网络。

  • 在创建实例之前,必须已有将作为多个接口连接目标的额外 VPC 网络。如需了解如何创建额外的 VPC 网络,请参阅使用 VPC 网络

  • 如果不删除实例,就无法删除网络接口。

  • 每个实例必须至少有一个网络接口。每个实例最多可有 8 个网络接口,具体取决于相应实例的机器类型。

    • nic0 是必需的,必须在创建实例时配置。
    • nic1nic7 是可选的,但也必须在创建实例时配置。
    • 如需了解详情,请参阅接口数量上限
  • 每个接口都可以有一个外部 IP 地址(可选)。

  • Google Cloud 的 DHCP 服务器仅向默认 NIC nic0 发送默认路由(RFC 3442,“无类静态路由”)。如果另一个 NIC 需要默认路由,则必须在实例中进行配置。在实例中更改默认路由时,请使用串行控制台,以防与虚拟机断开连接。

  • 所有虚拟机接口都必须连接到与虚拟机位于同一项目中的网络或与项目共享的共享 VPC。

限制

  • 您无法将网络接口添加到现有虚拟机或将其从现有虚拟机中移除。
  • IP 转发在虚拟机级层启用,不能应用于个别接口。

权限、IAM 和具有多个网络接口的实例

要创建具有多个网络接口的实例,您必须具有以下角色之一:

  • 项目 Owner 或 Editor 角色
  • compute.instanceAdmin.v1 角色

在不使用共享 VPC 环境的项目中创建和删除具有多个接口的实例和实例模板:如果用户具有项目级层的 OWNER、EDITOR 或 compute.instanceAdmin.v1 角色,则可以创建具有多个接口的实例,这些接口与属于同一项目的 VPC 网络和子网关联。

在共享 VPC 环境中创建和删除具有多个接口的实例和实例模板:如果用户具有项目级层的 OWNER、EDITOR 或 compute.instanceAdmin.v1 角色,则可以创建具有多个接口的实例。如果其中任何接口与共享 VPC 宿主项目内的子网关联,则还必须具有共享 VPC 宿主项目级层或共享 VPC 子网级层的 compute.networkUser 角色。

如需详细了解权限,请参阅 Compute Engine IAM 文档

使用具有不同 VPC 网络类型的多个网络接口

  • 旧版网络不支持多个网络接口。
  • 配置多个网络接口时,请将每个接口连接到自动模式 VPC 网络或自定义模式 VPC 网络。

网络接口 IP 地址分配

  • 您必须使用分配自某子网的主要 IP 地址范围内的主要内部 IP 地址来配置每个网络接口。
    • 分配给单个实例中各接口的主要内部地址不得相同。
  • 您可以选择为每个虚拟接口 (NIC) 配置一个唯一的外部 IP 地址。外部地址可以是临时地址,也可以是预留地址。

网络接口数上限

虚拟网络接口数量根据 vCPU 数量扩缩,最小 2 个,最多 8 个。

您可以参照下表,确定可以将多少个网络接口连接到一个实例:

vCPU 的数量 vNIC 的数量
2 或更少 2
2 至 8 2 至 8
8 或更多 8

创建具有多个网络接口的虚拟机实例

创建具有一个接口的实例的方法保持未变。有关如何创建实例的整体说明,请参阅创建和启动实例

您可以在创建实例时添加多个网络接口:

  • 在 Console 上,您可以在“网络”->“网络接口”部分的“创建实例”页面中添加网络接口。
  • 在 gcloud 命令行工具中,请使用 instances create 命令。为每个接口添加 --network-interface 标志,后接任意合适的网络密钥,例如 ([network | subnet], private-network-ip, address)

第一个接口始终创建为 nic0,并且始终是默认接口。这对于 Google Cloud 网络的其他方面十分重要。例如,Google Cloud 负载平衡器(内部 TCP/UDP 负载平衡除外)仅将流量分配到 nic0

控制台


  1. 转到 Google Cloud Console 中的“创建实例”页面。
    转到“创建实例”
  2. 填写实例名称、地区、机器类型和实例的其他基本信息。
  3. 填写管理磁盘标签中的字段。
  4. 网络标签上,点击添加网络接口
  5. 选择网络。
  6. 如果 VPC 网络中有多个子网,请选择一个子网。
  7. 要为该接口分配自定义内部 IP 地址,请在内部 IP 下拉菜单中选择自定义,然后输入 IP 地址。
  8. 要指明您不需要外部 IP 地址,请在外部 IP 下拉菜单中选择
  9. 要分配静态外部 IP 地址,请在外部 IP 下拉菜单中选择新建静态 IP (New static IP),输入名称说明,然后点击预留
  10. 如需启用 IP 转发,请在 IP 转发下拉菜单中选择开启
  11. 如需添加更多网络接口,请点击添加网络接口并按照上面的第 5-10 步进行操作。

gcloud

使用 instances create 命令在新实例上创建网络接口。为每个接口添加 --network-interface 标志,后接任意合适的网络密钥,例如 [network,subnet],private-network-ip,address)

此代码段仅展示了 --network-interface 标志,这是您在创建实例时可以指定的诸多可能参数之一。如需了解其他标志,请参阅 gcloud 参考中有关 instances create 命令的内容。查看网络接口数量上限表,了解哪些机器类型支持您需要的网络接口数量。

gcloud compute instances create INSTANCE_NAME \
    --zone [ZONE] \
    [--network-interface
        [network=NETWORK,subnet=SUBNET],
        [address=EXT_IP_NAME | no-address],
        [private-network-ip=INT_NETWORK_IP]
    ...]

请将占位符替换为有效值:

  • ZONE:实例创建所在的区域。
  • NETWORK:接口将连接到的网络。
  • SUBNET:接口将连接的子网。
  • EXT_IP_NAME:为接口分配指定的外部 IP 地址。您必须事先预留了外部地址。 如果您不希望接口具有外部 IP 地址,请指定“no-address”(而不是 address=EXT_IP_NAME)。如果您希望接口接收临时外部 IP 地址,请指定 address=''
  • INT_NETWORK_IP:您希望接口在目标子网中具有的内部 IP 地址。如果只希望具有分配的有效地址,请忽略。

API

创建具有多个网络接口的虚拟机实例。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances
{
  "networkInterfaces": [
    {
      "subnetwork": "SUBNET_URL"
    },
      for each interface, specify a network...
  ],
  other instance settings...
}

请将占位符替换为有效值:

  • SUBNET_URL 是网络接口所在的子网的网址。
  • PROJECT_ID 是将包含该实例的项目的 ID。
  • ZONE 是包含实例的可用区。

如需了解详情,请参阅 instances.insert 方法。

Terraform

您可以使用 Terraform 资源来创建具有多个网络接口的虚拟机实例。

Terraform 参数具有可以更改的示例值。

resource "google_compute_instance" "default" {
  project      = var.project_id # Replace with your project ID in quotes
  zone         = "us-central1-b"
  name         = "backend-instance"
  machine_type = "e2-medium"
  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }
  network_interface {
    subnetwork = var.subnet_1 # Replace with self link to a subnetwork in quotes
    network_ip = "10.0.0.14"
  }
  network_interface {
    subnetwork = var.subnet_2 # Replace with self link to a subnetwork in quotes
    network_ip = "10.10.20.14"
  }
}

示例

用于创建具有三个网络接口的实例的示例命令:

 gcloud compute instances create vm1 --machine-type=n1-standard-4 \
    --network-interface '' \
    --network-interface subnet=net1-subnet-a,private-network-ip=10.128.0.2,address=my-external-address \
    --network-interface subnet=net2-subnet-b,private-network-ip=10.129.0.2,no-address

这些接口的创建方式如下:

  • nic0,全部采用默认设置。与默认 VPC 网络相关联,具有自动分配的内部 IP 地址和临时外部 IP 地址
  • nic1 属于 net1-subnet-a,内部 IP 地址为 10.128.0.2,并且有静态外部 IP 地址。
  • nic2 属于 Net2-subnet-b,内部 IP 地址为 10.129.0.2,无外部 IP 地址

如需了解 gcloud compute instances create 命令和 --network-interface 标志的完整说明,请参阅该命令的相关文档

您可以使用您添加的 NIC 中的 IP 地址来设置 DNS 转发。如需详细了解如何配置 Cloud DNS 转发地区,请参阅转发地区

为实例组配置多个网络接口

托管实例组中的所有实例均限制为单个子网。用于负载平衡时,非托管实例组内的所有实例均限制为单个子网。如需了解详情,请参阅 VPC 网络负载平衡文档。

由于存在这些限制,每个实例仅有一个接口。Google Cloud 会根据与实例中唯一接口关联的子网执行验证。

在您为托管或非托管实例组中的实例配置多个接口时,Google Cloud 会继续为默认 nic0 接口验证这些条件。

创建具有多个接口的实例模板

创建每个实例使用一个接口的实例模板的过程没有任何变化,具体步骤请参阅 gcloud 参考中有关 instance-templates create 命令的内容。

如需为实例模板配置多个网络接口,请为要创建的每个网络接口设置 --network-interface 标志:


gcloud compute instance-templates create NAME [--description DESCRIPTION] \
    [--network-interface [network NETWORK; default="default" | subnet SUBNET][address ADDRESS| no-address] \
    [--network-interface [network NETWORK; default="default" | subnet SUBNET][address ADDRESS | no-address] \
    .....

您可以为每个接口分配下面的网络密钥:network, subnet, address

例如,如果您运行以下命令,则每个实例有三个网络接口:

gcloud compute instance-templates create template-1 \
    --network-interface subnet=net0-subnet-a \
    --network-interface subnet=net1-subnet-b,no-address \
    --network-interface subnet=net2-subnet-c,no-address \
    --region us-central1`

具体接口如下所示:

  • nic0 属于 net0-subnet-a,具有自动分配的外部 IP 地址
  • nic1 属于 Net1-subnet-b,无外部 IP 地址
  • nic2 属于 Net2-subnet-c,无外部 IP 地址

如需了解标志和语法的完整信息,请参阅 instance-templates create 命令

配置政策路由

对于 Google 支持的映像,在您需要次要网络接口(nic0 以外的接口)与不在次要接口关联子网的主要子网范围内的 IP 地址进行通信时,您需要配置政策路由,以确保出站数据包通过正确的接口传出。在本例中,您必须使用政策路由为各网络接口配置单独的路由表。

Linux

请按照以下步骤为具有多个接口、基于 Linux 的实例配置政策路由:

  1. 连接到配置了多个网络接口的实例:

    gcloud compute ssh multinic-vm
    
  2. 使用 ifconfig 为 nic1 配置政策路由。下面的示例假定 Google Cloud 已将内部 IP 地址 192.168.0.2 分配给 nic1,并且子网默认网关为 192.168.0.1。

    sudo ifconfig eth1 192.168.0.2 netmask 255.255.255.255 broadcast 192.168.0.2 mtu 1430
    echo "1 rt1" | sudo tee -a /etc/iproute2/rt_tables
    sudo ip route add 192.168.0.1 src 192.168.0.2 dev eth1 table rt1
    sudo ip route add default via 192.168.0.1 dev eth1 table rt1
    sudo ip rule add from 192.168.0.2/32 table rt1
    sudo ip rule add to 192.168.0.2/32 table rt1
    
  3. 为实例上的其他接口(nic2、nic3…nic7)重复执行第 2 步中的命令。

Ubuntu 18.04 或更高版本

从 Ubuntu 版本切换到 Netplan 作为从 Ubuntu 18.04 LTS 开始的默认网络配置实用程序,将不再预安装 ifconfig 软件包。此外,您对 Netplan 的网络配置文件所做的更改不会在 Compute Engine 虚拟机重新启动时保留。

有两种解决方法可用于为 Ubuntu 18.04 或更高版本中的每个网络接口配置路由表:

  1. 创建启动脚本,以便为虚拟机启动时的每个网络接口设置路由表。详细了解如何创建启动脚本

    如果您在虚拟机中装载文件共享,则启动脚本将不起作用,因为这些命令只有在装载分区后才会运行。这样,在启动脚本创建路由表之前,您的文件共享会一直装载在默认接口上。

  2. 如需通过次要网络(即 nic0 之外的接口)在虚拟机上装载文件共享,您必须配置客户端虚拟机的路由政策,以确保文件共享通过正确的方式装载网络接口。为此,请修改以下文件:

    • /etc/default/instance_configs.cfg 中,将 NetworkInterfacessetup 标志设置为 false
      [NetworkInterfaces]
      dhclient_script = /sbin/google-dhclient-script
      dhcp_command =
      ip_forwarding = true
          setup = false
      
    • /etc/network/interfaces 中,将以下几行代码添加到感兴趣的接口中:

      auto eth1
      iface eth1 inet dhcp
          up ip route add filestore-reserved-address-range via default-gateway-of-nic-to-filestore
      

    其中:

    • filestore-reserved-address-range 是 VPC 实例使用的预留地址范围。
    • default-gateway-of-nic-to-filestore 是连接到与 VPC 实例共享的 VPC 网络的 NIC 的默认网关 IP 地址。

    如需详细了解如何在虚拟机实例上装载文件共享,请参阅在 Compute Engine 上装载文件共享

问题排查

我无法创建具有多个接口的虚拟机

您可能会看到以下某条错误消息:

  • Invalid value for field 'resource': ''. Too many network interfaces. The maximum number of network interfaces allowed for this machine type is.

    如果您收到这条错误消息,则表示您尝试创建的接口数量超出了实例机器类型支持的接口数量上限。查看接口数量上限表。

  • Networks must be distinct for NICs attached to a VM.

    如果您收到这条消息,则表示您正尝试在同一网络中创建多个接口。每个网络接口都必须连接到不同的 VPC 网络。

  • Subnetwork CIDR ranges must be non-overlapping for NICs attached to a VM.

    如果您收到这条消息,则表示与您的虚拟机接口关联的 CIDR 范围存在重叠。这些 CIDR 范围包括与虚拟机接口关联的所有主要子网范围,以及用于别名 IP 范围的次要范围。每个接口都属于一个子网,每个子网都位于不同的 VPC 网络中,不得与其他接口的子网重叠。例如,如果您尝试在 us-west1 区域中创建实例,则可以使用以下命令或 Google Cloud Console 来检查子网的主要 CIDR 范围。

    gcloud compute networks subnets list --regions us-west1
    NAME                REGION    NETWORK          RANGE
    default             us-west1  default          10.138.0.0/20
    overlapping-subnet  us-west1  test-network     10.138.8.0/24
    

    如需检查次要子网 CIDR 范围,请使用以下命令或 Google Cloud Console

    gcloud compute networks subnets describe overlapping-subnet --region us-west1
    
    ...
    ipCidrRange: 10.128.8.0/24
    ...
    secondaryIpRanges:
    - ipCidrRange: 10.138.8.0/24
      rangeName: conflicting-range
    
  • Multiple network interfaces are not supported on legacy networks.

    如果您收到这条消息,则表示您正尝试在旧版网络中创建实例。旧版网络不支持具有多个接口的实例。您可以使用以下命令或 Google Cloud Console 来检查网络是否属于旧版网络。Mode 字段指示了网络的类型。

    gcloud compute networks list
    NAME             MODE    IPV4_RANGE     GATEWAY_IPV4
    default          auto
    legacy-network   legacy  10.240.0.0/16  10.240.0.1
    test-network     custom
    

  • Required 'compute.instances.create' permission for 'projects/PROJECT_ID/zones/ZONE/instances/test-inst'

    如果您收到这条消息,则您登录的帐号没有创建实例所必需的 IAM 权限。如需详细了解创建实例所需的角色,请参阅 IAM 权限。您可以检查与项目相关的 IAM 政策,确定其是否授予您以下任何角色:OWNEREDITORcompute.instanceAdmin.v1。如需在共享 VPC 中创建实例,您还需要具备 compute.networkUser 角色。在以下示例中,帐号 email2@gmail.com 没有创建实例所需的足够 IAM 权限。如需了解详细说明,请参阅授予、更改和撤消对资源的访问权限 IAM 指南。

    gcloud projects get-iam-policy PROJECT_ID
    bindings:
    - members:
      - user:email1@gmail.com
        role: roles/owner
    - members:
      - serviceAccount:our-project-123@appspot.gserviceaccount.com
      - serviceAccount:123456789012-compute@developer.gserviceaccount.com
        role: roles/editor
    - members:
      - user:email2@gmail.com
        role: roles/viewer
    etag: BwUjMhXbSPU=
    version: 1
    

    您可以要求您的项目 Owner 或 Editor 授予您 OWNEREDITORcompute.instanceAdmin.v1 角色。如果您将任何接口与属于共享 VPC 的子网关联,那么您还需要具备 compute.networkUser 角色。

    gcloud projects set-iam_policy --member user:email2@gmail.com --role roles/editor
    

我无法连接到次要接口的内部 IP

  • 检查防火墙规则,确定其是否允许连接到虚拟机次要接口。如需进行检查,您可以通过以下两种方式之一,查看连接到次要接口的网络的防火墙规则:您可以访问 Google Cloud Console 并点击相应的 VPC 网络;也可以使用以下 gcloud 命令。

    gcloud compute firewall-rules list --filter='network:NETWORK_NAME'
    
  • 检查您是否在尝试从互联网地址或次要接口网络外部连接到次要接口。您只能从一个接口所在的网络内连接到该接口的内部 IP。如果您需要从网络外部访问该接口,则可以为次要接口分配外部 IP 地址。

  • 检查您是否在尝试从次要接口所连接的子网外部连接到次要接口的内部 IP,比如说从相同网络的另一个子网连接,或者从对等互连网络连接。每个实例多个网络接口解释了 VPC 对等互连和具有多个接口的虚拟机实例之间的相互作用。如需从接口的子网外部访问次要接口,您可能需要在虚拟机上配置路由。如需详细了解 DHCP 如何配置虚拟机中的默认路由,请参阅使用多个网络接口的 DHCP 行为

我无法使用外部 IP 连接到次要接口

DHCP 服务器仅在虚拟机的主要网络接口上配置默认路由。如果您要使用外部 IP 地址连接到次要接口,那么有两种可选方案。如果仅需要通过次要网络接口连接到网络外部,则可以在该网络接口上设置默认路由。此外,您也可以参照配置政策路由,在虚拟机中使用基于来源的政策路由配置一个单独的路由表。

我在使用 /32 以外的网络掩码时遇到连接问题

默认情况下,实例元数据服务器仅响应默认网关的 ARP 请求。

如需使用 /32 以外的网络掩码配置接口,您应该使用 --guest-os-features MULTI_IP_SUBNET 标志创建映像,并使用该映像来创建实例。例如,如果您使用的是基于 debian-9 的映像,则可以使用如下命令创建映像:

gcloud compute images create debian-9-multi-ip-subnet \
     --source-disk debian-9-disk \
     --source-disk-zone us-west1-a \
     --guest-os-features MULTI_IP_SUBNET

如需查看映像中配置的客机功能,请在客机映像上运行 gcloud compute images describe 命令。

gcloud compute images describe debian-9-multi-ip-subnet

如需详细了解如何创建自定义映像,请参阅创建、删除和弃用自定义映像

使用串行控制台进行问题排查

在虚拟机上启用串行控制台来调试配置相关问题,这通常是一种不错的做法。按照与串行控制台互动中的步骤,即可启用串行控制台,执行交互式调试。