内部 DNS

GCP 上的 Virtual Private Cloud 网络具有一项内部 DNS 服务,允许同一网络内的实例使用内部 DNS 名称彼此访问。内部 DNS 记录在一个 .internal 地区内创建。在您管理虚拟机实例时,GCP 会自动创建、更新和移除内部 DNS 记录。

举例来说,如果您删除了一个虚拟机,GCP 会自动移除该虚拟机的内部 DNS 记录。如果您创建了一个同名新虚拟机,GCP 将为替换虚拟机创建一条新记录。

关于内部 DNS

内部 DNS 名称具有以下规范:

  • 虚拟机实例的内部 DNS 名称只会解析为其主要内部 IP 地址。内部 DNS 名称不能用于连接到实例的外部 IP 地址。

  • 无法通过配置使内部 DNS 名称解析为辅助别名 IP

  • 只能通过位于同一项目且使用同一 VPC 或旧版网络的其他虚拟机解析内部 DNS 名称。无法使用内部 DNS 访问其他网络中的实例,即便对于同属一个项目的实例也是如此。

内部 DNS、Cloud DNS 和自定义主机名

内部 DNS 和 Cloud DNS 是不同的产品。 内部 DNS 名称由 GCP 自动创建。如果您需要为虚拟机创建自定义 DNS 名称,可以使用 Cloud DNS 专用地区

此外,您还可以在创建虚拟机时为其指定自定义主机名。内部 DNS 不会解析以此方式分配的自定义主机名,您仍然需要在适当的地区创建相应的 DNS 记录(例如,使用 Cloud DNS)。如需了解详情,请参阅创建具有自定义主机名的虚拟机实例

内部 DNS 名称的类型

GCP 有两种类型的内部 DNS 名称。默认内部 DNS 类型根据启用 Compute Engine API 的时间设置。

内部 DNS 类型 完全限定域名 (FQDN) 项目的默认类型
地区 DNS [INSTANCE_NAME].[ZONE].c.[PROJECT_ID].internal 2018 年 9 月 6 日之后启用了 Compute Engine API 的所有组织或独立项目均默认使用此类型。
全局(项目范围)DNS [INSTANCE_NAME].c.[PROJECT_ID].internal 2018 年 9 月 6 日之前启用了 Compute Engine API 的所有组织或独立项目均默认使用此类型。

其中:

  • [INSTANCE_NAME] 是实例的名称。
  • [ZONE] 是实例所在的地区。
  • [PROJECT_ID] 是实例所属的项目。

您可以在项目或实例级控制使用哪种类型的内部 DNS 名称。请参阅为项目或实例配置 DNS 名称

内部 DNS 名称和共享 VPC

即使 IP 地址位于宿主项目中的共享 VPC 网络中,您也可以使用内部 DNS 名称来指代虚拟机的内部 IP 地址。对于共享 VPC,地区或全局(项目范围)内部 DNS 名称中的项目 ID 部分是服务项目的 ID。

确定虚拟机的内部 DNS 名称

按照以下过程读取已经分配给虚拟机的内部 DNS 名称。内部 DNS 名称的真实来源是其元数据服务器

  1. 连接到实例
  2. 通过实例元数据查看主机名:

    curl "http://metadata.google.internal/computeMetadata/v1/instance/hostname" \
    -H "Metadata-Flavor: Google"
    

主机名的格式表示虚拟机使用的内部 DNS 名称的类型

通过内部 DNS 访问虚拟机

元数据服务器也是虚拟机发出的 DNS 查询的域名服务器解析器。元数据服务器会对所有 DNS 查询执行解析,包括解析为内部 DNS 名称和外部 DNS 名称。对于外部 DNS 查询,元数据服务器会将请求传递到 Google 的公开域名服务器。

以下示例使用 ping 来检查使用地区 DNS 的实例是否连接。如果您已创建允许传入 ICMP 流量进入实例的防火墙规则,则可以使用这种方法。

$ ping [INSTANCE_NAME].[ZONE].c.[PROJECT_ID].internal -c 1

PING [INSTANCE_NAME].[ZONE].c.[PROJECT_ID].internal (10.240.0.17) 56(84) bytes of data.
64 bytes from [INSTANCE_NAME].[ZONE].c.[PROJECT_ID].internal (10.240.0.17): icmp_seq=1 ttl=64 time=0.136 ms

其中:

  • [INSTANCE_NAME] 是实例的名称。
  • [ZONE] 是实例所在的地区。
  • [PROJECT_ID] 是实例所属的项目。

内部 DNS 和 resolv.conf

默认情况下,大多数 Linux 发行版都将 DHCP 信息存储在 resolv.conf 中。Compute Engine 实例被配置为每 24 小时续订一次 DHCP 租约。对于启用了地区 DNS 的实例而言,DHCP 租约每小时到期一次。DHCP 续订操作会覆盖此文件,从而撤消您之前可能做过的任何更改。使用地区 DNS 的实例在 resolv.conf 文件中同时具有地区和全局条目。

地区 DNS

地区 resolv.conf 文件示例:

# Local domain name. Computed from your project name.
domain [ZONE].c.[PROJECT_ID].internal
# Search list for hostname lookup. Starting with entries that represent
# your project and ending with google.internal to facilitate metadata server requests.
search [ZONE].c.[PROJECT_ID].internal. c.[PROJECT_ID].internal. google.internal.
# Address of the DNS server to resolve project specific, and global domain names.
nameserver 169.254.169.254

其中:

  • [ZONE] 是实例所在的地区。
  • [PROJECT_ID] 是实例所属的项目。

地区 dhcp.lease 文件示例:

lease {
  # What interface we are using for the network
  interface "eth0";
  fixed-address 10.128.0.9;
  option subnet-mask 255.255.255.255;
  option routers 10.128.0.1;
  # Lease timeout, older VM instances will have this value set to infinite.
  option dhcp-lease-time 3600;
  option dhcp-message-type 5;
  option domain-name-servers 169.254.169.254;
  option dhcp-server-identifier 169.254.169.254;
  option interface-mtu 1460;
  # Search path options that are copied into the resolv.conf
  option domain-search "[ZONE].c.[PROJECT_ID].internal.", "c.[PROJECT_ID].internal.", "google.internal.";
  option ntp-servers 169.254.169.254;
  option rfc3442-classless-static-routes 32,10,128,0,1,0,0,0,0,0,10,128,0,1;
  option host-name "[INSTANCE_NAME].[ZONE].c.[PROJECT_ID].internal";
  option domain-name "[ZONE].c.[PROJECT_ID].internal";
  renew 4 2017/11/16 02:15:52;
  rebind 4 2017/11/16 02:43:59;
  expire 4 2017/11/16 02:51:29;
}

其中:

  • [INSTANCE_NAME] 是实例的名称。
  • [ZONE] 是实例所在的地区。
  • [PROJECT_ID] 是实例所属的项目。

全局 DNS

全局 resolv.conf 文件示例:

# Local domain name. Computed from your project name.
domain c.[PROJECT_ID].internal
# Search list for hostname lookup. Starting with entries that represent
# your project and ending with google.internal to facilitate metadata server requests.
search c.[PROJECT_ID].internal google.internal.
# Address of the DNS server to resolve project specific, and global domain names.
nameserver 169.254.169.254

其中 [PROJECT_ID] 是实例所属的项目。

全局 dhcp.lease 文件示例:

lease {
  # What interface we are using for the network
  interface "eth0";
  fixed-address 10.128.0.8;
  option subnet-mask 255.255.255.255;
  option routers 10.128.0.1;
  # Lease timeout, older VM instances will have this value set to infinite.
  option dhcp-lease-time 86400;
  option dhcp-message-type 5;
  option domain-name-servers 169.254.169.254;
  option dhcp-server-identifier 169.254.169.254;
  option interface-mtu 1460;
  # Search path options that are copied into the resolv.conf
  option domain-search "c.[PROJECT_ID].internal.", "google.internal.";
  option ntp-servers 169.254.169.254;
  option rfc3442-classless-static-routes 32,10,128,0,1,0,0,0,0,0,10,128,0,1;
  option host-name "[INSTANCE_NAME].c.[PROJECT_ID].internal";
  option domain-name "c.[PROJECT_ID].internal";
  renew 4 2017/11/16 12:07:00;
  rebind 4 2017/11/16 22:44:53;
  expire 5 2017/11/17 01:44:53;
}

其中:

  • [INSTANCE_NAME] 是实例的名称。
  • [PROJECT_ID] 是实例所属的项目。

这些文件具有以下限制:

  • 搜索路径只能处理 6 条记录,其中 3 条记录由 Compute Engine 提供。如果您向搜索路径中添加条目使得条目总数超过 6,则操作系统将不会应用位于第 6 个条目之后的搜索规则。这可能导致 Compute Engine 功能不起作用,例如无法通过其实例名称访问实例。
  • 每当实例上为期 24 小时的 DHCP 租约到期时,对 resolv.conf 的任何手动修改都将恢复为默认的 DHCP。在使用地区 DNS 的实例上,DHCP 租约每小时到期一次。要在 resolv.conf 文件中进行静态修改,多种 Linux 发行版都允许您在 DHCP 政策的开头或末尾处附加相应修改项。

Debian 9

/etc/dhcp/dhclient.conf 文件示例:

# Configuration file for /sbin/dhclient.
#
...
append domain-search "mydomain.com";
prepend domain-name-servers 172.16.1.1;

其中 mydomain.com 是新的搜索网域,172.16.1.1 是您的 DNS 服务器的 IP 地址。

地区 DNS 名称

地区 DNS 名称中包含了实例的名称、实例所在的地区以及拥有该实例的项目。全局 DNS 名称不包含实例所在的地区。一个位置中的地区 DNS 名称是独立于其他位置来使用的,以便您构建更多可用性更好的容错型多区域应用。

现有项目和组织可以继续使用全局 DNS 名称,但最好迁移到地区 DNS 名称

为项目或实例配置 DNS 名称

通过在项目或实例元数据中设置 VmDnsSetting 变量,在您的实例上启用地区 DNS 和/或全局 DNS 搜索路径。如果在特定实例的元数据上设置 VmDnsSetting 变量,它将覆盖从该实例的项目元数据继承而来的任何 VmDnsSetting 变量。

  • 设置 VmDnsSetting=ZonalOnly 以使您的实例只能通过其地区 DNS 名称来访问。实例仍保留地区搜索路径和全局搜索路径,但其全局 DNS 名称不再起作用。其他实例只能使用地区 DNS 名称来访问采用此设置的实例,并且无法使用其全局 DNS 名称或搜索路径来访问这些实例。只要您的应用可支持此设置,它就是首选选项。2018 年 9 月 6 日之后启用 Compute Engine API 的独立项目及组织中创建的项目内的实例均默认使用此设置。请注意,将项目迁移到组织不会更改该项目的默认 DNS 名称。
  • 设置 VmDnsSetting=ZonalPreferred 以启用地区 DNS 搜索路径,同时仍保留全局 DNS 名称。具有此设置的实例可以使用地区或全局 DNS 名称互相访问,并且可以继续访问仅配置了全局 DNS 名称的实例。
  • 设置 VmDnsSetting=GlobalOnly 以便实例仅使用全局名称作为域名和搜索路径条目。使用此值可从项目级的地区 DNS 设置中排除实例,或者将实例恢复为仅使用全局 DNS 名称。2018 年 9 月 6 日之前启用 Compute Engine API 的独立项目及组织中创建的项目内的实例均默认使用此设置。请注意,将项目迁移到组织不会更改该项目的默认 DNS 名称。

阅读设置自定义元数据以了解如何设置项目元数据或实例元数据值。

为实例配置 VmDnsSetting 变量后,刷新实例上的 DHCP 租约。您可以通过重新启动实例、等待租约到期或运行以下命令之一来刷新租约:

  • Linux 实例:sudo dhclient -v -r
  • Windows Server 实例:ipconfig /renew

为现有应用改用地区 DNS 名称

虽然现有项目可以继续使用全局 DNS 名称,但建议您为现有实例和应用改用地区 DNS 名称,以便享受地区 DNS 系统的优势。通常,您可以通过以下过程执行迁移:

  1. 检查您的应用并更新它们以解决与“仅使用地区名称”设置的兼容性问题:
    • 通过实例名称或全局完全限定域名来访问实例的应用:实例名称和全局实例名称并不总在“仅使用地区名称”的环境中进行解析。最佳做法是更新这些名称以使用地区完全限定域名
    • 假定采用特定全局完全限定域名格式的应用:假定采用某种域名格式通常意味着应用设计中存在一项重大问题。Google 建议您将应用设计为独立于域名格式运行。
    • 不希望域名发生更改的应用:某些应用可能不希望域名发生更改,并且需要完全重新启动才能获取新的名称。如果可能,请更新您的应用以识别和处理实例域名中的更改。
  2. 在内部 VPC 网络上将实例配置为使用 VmDnsSetting=ZonalPreferred 设置,该设置会同时使用全局和地区 DNS 名称。此过渡阶段允许实例继续使用全局名称,直到您的应用已准备好仅使用地区名称:
    1. 通过在自定义元数据中设置相应的值,在一个实例上启用 VmDnsSetting=ZonalPreferred
    2. 刷新该实例上的 DHCP 租约,以让实例开始使用地区 DNS 名称:
      • Linux 实例:sudo dhclient -v -r
      • Windows Server 实例:ipconfig /renew
    3. 测试该实例上的应用以确保它们按预期运行。某些应用可能不希望域名发生更改,并且需要完全重新启动才能获取新的名称。
    4. 重复此过程以启用 VmDnsSetting=ZonalPreferred 并刷新 VPC 网络中剩余实例上的 DHCP 租约,直到它们在仅使用地区 DNS 名称的情况下都能按预期运行。您还可以在项目元数据中设置 VmDnsSetting=ZonalPreferred,以将项目中的每个实例都配置为使用地区 DNS 名称。
  3. 在通过 VmDnsSetting=ZonalPreferred 设置让您的应用能够在只使用地区域名的情况下正常运行后,即可在该 VPC 网络上停用全局名称。在内部 VPC 网络上将实例配置为使用 VmDnsSetting=ZonalOnly 设置,该设置仅使用地区 DNS 名称:
    1. 通过在自定义元数据中设置相应的值,在一个实例上启用 VmDnsSetting=ZonalOnly
    2. 刷新该实例上的 DHCP 租约,以让实例开始使用地区 DNS 名称:
      • Linux 实例:sudo dhclient -v -r
      • Windows Server 实例:ipconfig /renew
    3. 测试该实例上的应用以确保它们按预期运行。
    4. 重复此过程以启用 VmDnsSetting=ZonalOnly 并刷新 VPC 网络中剩余实例上的 DHCP 租约,直到它们在仅使用地区 DNS 名称的情况下都能按预期运行。
  4. 在每个 VPC 网络上重复此过程,直到您项目中的所有实例都使用 VmDnsSetting=ZonalOnly 设置。您可以在项目级元数据中设置 VmDnsSetting=ZonalOnly,以便此设置能够自动应用于您在该项目中创建的所有实例。或者,您也可以在项目元数据中设置 VmDnsSetting=ZonalOnly,以将项目中的每个实例都配置为使用地区 DNS 名称。

停用项目或实例上的地区 DNS

要在特定实例上停用地区 DNS,请在该实例的元数据中设置 VmDnsSetting=GlobalOnly。要在整个项目中停用地区 DNS,请在项目元数据中设置 VmDnsSetting=GlobalOnly,并确保未使用 VmDnsSetting 值单独配置您的任何实例。阅读设置自定义元数据以了解如何设置项目元数据或实例元数据值。

如果您需要强制立即刷新 DHCP 租约,可以使用以下命令之一:

  • Container-optimized OS (Google Kubernetes Engine):sudo systemctl restart systemd-networkd
  • Debian/Google App Engine Flex 实例:sudo dhclient -r -v eth0 && sudo rm /var/lib/dhcp/dhclient.* ; sudo dhclient -v eth0
  • Ubuntu 15.04 及更高版本:sudo dhclient -r -v ens4 && sudo rm /var/lib/dhcp/dhclient.* ; sudo dhclient -v ens4
  • Ubuntu 15.04 以前的版本:sudo dhclient -r -v eth0 && sudo rm /var/lib/dhcp/dhclient.* ; sudo dhclient -v eth0
  • Windows:ipconfig /renew

即使在 DHCP 租约续订后,某些操作系统也无法完全更改其 DNS 配置。在这些情况下,请重新启动虚拟机实例的网络以强制更改 DNS 配置:

  • Ubuntu:sudo ifdown --exclude=lo -a && sudo ifup --exclude=lo -a
  • CentOS:sudo /etc/init.d/network restart
  • CoreOS:sudo systemctl restart systemd-networkd
  • Container-optimized OS:sudo systemctl restart systemd-networkd

如果您在容器、Kubernetes Engine 或 App Engine 柔性环境中运行应用,容器设置中的 DNS 配置可能不会自动更新,直到您重新启动容器。要在这些容器应用上停用地区 DNS,必须在项目和实例中设置 VmDnsSetting=GlobalOnly,并重新启动容器,以使其 DNS 设置恢复到原始状态。

后续步骤

  • 请参阅 VPC 概览,了解 GCP VPC 网络。
  • 请参阅使用 VPC,了解如何创建和修改 VPC 网络。
此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Compute Engine 文档