在虚拟机上配置 NTP


许多依赖于事件的精密排序的软件系统都依靠稳定、一致的系统时钟。大多数服务编写的系统日志都包含时间戳,时间戳有助于调试系统的各个组件之间发生的问题。为帮助确保系统时钟同步,Compute Engine 实例已预先配置为使用网络时间协议 (NTP)。

除了保持服务器时间同步以外,在出现闰秒的罕见情况下,NTP 也很实用。闰秒是指对世界协调时间 (UTC) 增加或减少 1 秒的调整,以考虑地球旋转引起的变化。闰秒不会按照常规的时间间隔发生,因为地球的旋转速度会随着气候和地质事件而不规则地变化。之前出现的闰秒已经对网络上的各种服务和应用造成了显著影响。NTP 服务器有助于确保在出现闰秒时,所有服务器报告相同的时间。

本文档介绍了如何在虚拟机 (VM) 上配置 NTP 服务器,以确保该服务器在出现闰秒时正常运行。

Google NTP 服务器和闰秒弥补

Unix 操作系统的闰秒通常通过重复当天的最后一秒来实现。这会导致预计时间戳只会增加的软件出现问题。为了解决这个问题,Google Cloud 的时间服务器会在二十四个小时(闰秒出现前十二个小时及闰秒出现后十二个小时)内“弥补”这额外的一秒,这样计算机便不会立即将这额外的一秒视为重复的时间戳。此操作可以降低依赖于一致时间戳的系统的风险。建议将所有 Compute Engine 虚拟机 (VM) 实例配置为使用内部 Google NTP 服务。

为您的实例配置 NTP

Google Cloud 无法预测外部 NTP 服务(如 pool.ntp.org)如何处理闰秒。如果可能的话,建议您不要在 Compute Engine 虚拟机上使用外部 NTP 来源。更糟糕的是,同时使用 Google NTP 服务和外部服务可能会导致系统时间发生不可预知的变化。仅使用一个外部 NTP 来源比使用混合来源要好,但外部 NTP 服务(如 pool.ntp.org)可能会使用步进来处理闰秒。因此,虚拟机可能会出现重复的时间戳。

最安全的方法是将 Compute Engine 虚拟机配置为使用单个 NTP 服务器(由 Google 提供的内部 NTP 服务器)。请勿混用外部 NTP 服务器和 Google NTP 服务器,因为这可能会导致意想不到的行为。

为确保虚拟机配置正确,请按照以下说明操作。

Linux (chrony)

默认情况下,大多数新 Linux 版本都使用 chrony 来管理其 NTP 设置和时间同步。如需确保 chrony 仅使用内部 NTP 服务,请检查 chrony 配置并移除外部 NTP 服务器。

  1. 使用 ssh 连接到您的实例。

    控制台

    如需使用控制台通过 SSH 连接到虚拟机,请按照以下步骤操作:

    1. 转到 Google Cloud 控制台中的虚拟机实例页面。

      转到“虚拟机实例”

    2. 点击要配置的虚拟机对应的 SSH 按钮。

      SSH 按钮。

    gcloud

    如需使用 Google Cloud CLI 通过 SSH 连接到虚拟机,请运行以下命令:

    gcloud compute instances ssh VM_NAME
    

    VM_NAME 替换为您要连接的虚拟机的名称。

  2. 在您的实例上,运行 chronyc sources 来检查 NTP 配置的当前状态:

    $ chronyc sources
    

    输出类似于以下内容:

     210 Number of sources = 2
     MS Name/IP address         Stratum Poll Reach LastRx Last sample
     ===============================================================================
     ^* metadata.google.internal      2   6   377     4    -14us[  -28us] +/-  257us
     ^- 38.229.53.9                   2   6    37     4   -283us[ -297us] +/-   28ms
    

    如果您看到指向 metadata.googlemetadata.google.internal 的单条记录,则无需进行任何更改。如果您看到 metadata.google 与公共来源(如 pool.ntp.org)之间混用了多个来源,请更新来源以移除所有外部 NTP 服务器。

    示例输出中有两条记录,一条指向 metadata.google.internal,另一条指向外部地址。由于存在多个来源,因此您需要更新 NTP 服务器以移除 38.229.53.9 地址,如下一步所述。

  3. 配置您的 NTP 服务器以移除外部 NTP 服务器。

    如需从列表中移除其他 NTP 服务器,请使用您偏好的文本编辑器修改 /etc/chrony/chrony.conf 文件。找到所有以 server external_source_ip_or_name 开头的行并将其移除。

    修改 /etc/chrony/chrony.conf 文件后,重启 chrony 服务。重启命令可能因 Linux 发行版而异,如以下示例所示:

    sudo service chrony restart
    
    sudo systemctl restart chrony
    
  4. 再次运行 chronyc sources 命令以验证您的配置:

    $ chronyc sources
    

    输出应类似如下所示:

     210 Number of sources = 1
     MS Name/IP address         Stratum Poll Reach LastRx Last sample
     ===============================================================================
     ^* metadata.google.internal      2   7   377    98  -1343ns[-1588ns] +/-  396us
    

Linux (ntpd)

大多数较早的 Linux 发行版都使用 ntpd 来管理其 NTP 设置和时间同步。如需确保 ntpd 仅使用内部 NTP 服务,请检查 ntpd 配置并移除外部 NTP 服务器。

  1. 使用 ssh 连接到您的实例。

    控制台

    如需使用控制台通过 SSH 连接到虚拟机,请按照以下步骤操作:

    1. 转到 Google Cloud 控制台中的虚拟机实例页面。

      转到“虚拟机实例”

    2. 点击要配置的虚拟机对应的 SSH 按钮。

      SSH 按钮。

    gcloud

    如需使用 Google Cloud CLI 通过 SSH 连接到虚拟机,请运行以下命令:

    gcloud compute instances ssh VM_NAME
    

    VM_NAME 替换为您要连接的虚拟机的名称。

  2. 在您的实例上,运行 ntpq -p 来检查 NTP 配置的当前状态:

    $ ntpq -p
    

    输出类似于以下内容:

    remote           refid           st t when poll reach   delay   offset  jitter
    
    ==============================================================================
    *metadata.google 255.28.23.83     2 u   27   64    1    0.634   -2.537   2.285
    *217.162.232.173 130.149.17.8     2 u  191 1024  176   79.245    3.589  27.454
    

    如果您看到指向 metadata.googlemetadata.google.internal 的单条记录,则无需进行任何更改。如果您看到 metadata.google 与公共来源(如 pool.ntp.org)之间混用了多个来源,则需要更新您的来源以移除所有外部 NTP 服务器。

    示例输出中有两条记录,一条指向 metadata.google,另一条指向外部地址。由于存在多个来源,因此您需要更新 NTP 服务器以移除 *217.162.232.173 地址,如下一步所述。

  3. 配置 NTP 服务器以移除外部来源。

    如需配置 NTP 服务器,请使用您偏好的文本编辑器修改 /etc/ntp.conf 文件。找到配置的 servers 部分,并移除所有非 Google NTP 来源,例如:

    vim /etc/ntp.conf
    
    # You do need to talk to an NTP server or two (or three).
    #server ntp.your-provider.example
    ...
    server metadata.google.internal iburst
    

    修改 /etc/ntp.conf 文件后,重启 NTP 服务。重启命令可能因 Linux 发行版而异:

    sudo service ntp reload
    
  4. 再次运行 ntpq -p 命令以验证您的配置:

    ntpq -p
    
    remote           refid           st t when poll reach   delay   offset  jitter
    ==============================================================================
    *metadata.google 255.28.23.83     2 u   27   64    1    0.634   -2.537   2.285
    

Windows

  1. 转到 Google Cloud 控制台中的虚拟机实例页面。

    转到“虚拟机实例”

  2. 点击要连接到的 Windows 实例旁边的 RDP 按钮。

    SSH 按钮。

  3. 登录后,右键点击 PowerShell 图标,然后选择以管理员身份运行

    PowerShell 图标。

  4. 当命令提示符加载时,运行以下命令以查看当前的 NTP 配置:

    w32tm /query /configuration
    
    [Configuration]
    ...
    Type: NTP (Local)
    NtpServer: metadata.google.internal,
    ...
    

    如果您看到指向 metadata.googlemetadata.google.internal 的单条记录,则无需进行任何更改。如果您看到 metadata.google 与公共来源之间混用了多个来源,则需要移除外部服务器。请按照 Windows 指南配置 NTP 服务器。

  5. 为确保在 Windows 虚拟机上实现最广泛的软件兼容性,Google 建议您使用 gVNIC 驱动程序来确保通过 metadata.google 实现亚毫秒级的 NTP 准确度。

    如果您必须将 VirtIO 与 Windows 虚拟机搭配使用,以通过 NTP 服务器实现亚毫秒级的准确度,Google 建议您不要使用 Windows 时间服务(停止并取消注册 w32tm)。

    1. 停止 Windows 时间服务:

      net stop w32time
      
    2. 从注册表中移除 Windows 时间服务:

      w32tm /unregister
      
    3. 停止 Windows 时间服务并从注册表中移除后,安装 Meinberg NTP 客户端

      按照 Meinberg 文档中提供的配置说明进行操作。

    4. 将 Meinberg NTP 客户端的 NTP 服务器配置为 metadata.google.internal

      完成 NTP 配置后,请等待 5 到 15 分钟,以便虚拟机中的系统时钟在 NTP 服务器中稳定下来。

      如需了解不建议使用 w32tm 的原因,请参阅已知问题文档

对 Google Cloud 外部的系统使用闰秒弥补

Google NTP 服务器的闰秒弥补功能是一种便捷的方式,可管理在对时间敏感的系统中重放一秒所涉及的风险。其他 NTP 服务可以为大多数软件系统提供可接受的解决方案。但是,请务必不要将 Google 闰秒弥补 NTP 服务与公共 NTP 步进服务混用。

如需将 Google Cloud 之外的设备同步为经过闰秒弥补处理的时间,您可以为这些设备使用 Google 公共 NTP。Google 公共 NTP 使用与提供给 Compute Engine 虚拟机相同的闰秒弥补。

后续步骤