Libvirt: 使用 virtlogd 守护进程

https://blueprints.launchpad.net/nova/+spec/libvirt-virtlogd

如果计算节点上启用了串行控制台功能,并且 [serial_console].enabled = True,则会禁用启动消息的日志记录。从 REST API 的角度来看,这意味着两个 API os-getConsoleOutputos-getSerialConsole 是互斥的。当实例启动时出现问题时,这两个 API 对云操作员来说都很有价值。此蓝图旨在消除这两个 REST API 之间的 XOR 关系。

问题描述

该问题可以在 libvirt 驱动程序中的 _create_serial_console_devices 方法中看到。简化后的逻辑是

def _create_serial_console_devices(self, guest, instance, flavor,
                                   image_meta):
    if CONF.serial_console.enabled:
        console = vconfig.LibvirtConfigGuestSerial()
        console.type = "tcp"
        guest.add_device(console)
    else:
        consolelog = vconfig.LibvirtConfigGuestSerial()
        consolelog.type = "file"
        guest.add_device(consolelog)

这个 if-else 建立了在客户机启动消息的日志记录与获取客户机串行控制台句柄之间的 XOR 关系。从驱动程序的角度来看,这意味着获得方法 get_serial_consoleget_console_output 的有效返回值,这些返回值用于满足两个 REST API os-getConsoleOutputos-getSerialConsole

用例

从最终用户角度来看,这意味着,在当前状态下,可以在主机 A 上获取实例的控制台输出(未启用串行控制台),但在主机 B 上重建后(已启用串行控制台),则无法获取控制台输出。由于最终用户不知道主机的配置,这可能会造成混淆。写下来后,我很好奇为什么串行控制台是按计算节点范围设计的,而不是按实例范围设计的,但这又是另一个我不想在这里讨论的问题。

实施后,部署者将在实例启动时出现问题时,都将拥有这两种方式。持久化的日志,以防实例崩溃,以及串行控制台,以防实例启动但存在问题,例如网络建立失败,导致无法通过 SSH 访问。他们还将受到主机的新依赖项的影响(参见 依赖项)。

开发人员不受影响。

提议的变更

我想从日志文件切换到 virtlogd 守护进程。该日志守护进程在 libvirt ML [1] 上宣布,并且可在 libvirt 版本 1.3.3 和 Qemu 2.6.0 中使用。此日志守护进程处理来自客户机控制台的输出,并将其写入主机上的文件 /var/log/libvirt/qemu/guestname-serial0.log,但会截断/轮转该日志,以防止耗尽主机的磁盘空间(这将解决一个旧的 bug [3])。

Nova 将生成

<serial type="tcp">
  <source mode="connect" host="0.0.0.0" service="2445"/>
  <log file="/var/log/libvirt/qemu/guestname-serial0.log" append="on"/>
  <protocol type="raw"/>
  <target port="1"/>
</serial>

为了提供控制台日志数据,nova 需要直接从磁盘读取控制台日志文件。由于日志文件会自动轮转,因此我们必须确保读取所有必要的轮转日志文件以满足 get_console_output 驱动程序 API 合同的上限。

常见问题解答

  1. 迁移/重建如何处理?基于节点补丁级别,可能发生的 4 种情况

    1. N -> N:源节点和目标节点都没有补丁。这就是我们今天的情况。无需执行任何操作。

    2. N -> N+1:目标节点已补丁,这意味着它可以利用来自 virtlogd 的输出。我们能否“导入”源节点的现有日志到目标节点的 virtlogd 日志中?

      答:客户机将保留其来自源主机的配置,并且在重建之前不会使用 virtlogd 服务。

    3. N+1 -> N:源节点已补丁,并且实例迁移到无法利用 virtlogd 输出的目标节点。如果目标节点上启用了串行控制台,我们是否会丢弃日志,因为我们无法在目标节点上更新它

      答:在迁移到旧主机的情况下,我们将尝试将现有的日志文件复制过去,并使用 type=tcp 后端配置客户机。这为交互式控制台提供持续支持。如果可能,日志文件将保持不变。复制操作失败不应阻止客户机的迁移。

    4. N+1 -> N+1:源节点和目标节点都已补丁。libvirt 是否会从源节点迁移现有的日志,这将解决另一个开放的 bug [4]?

  2. 问:如果 nova-compute 正在读取日志文件,而 virtlogd 尝试写入文件但被阻止,是否会发生客户机停滞?

    答:不会,virtlogd 将确保所有内容都完全并行化

  3. 问:virtlogd 守护进程与计算节点具有 1:1 的关系。当例如数百个实例在一个计算节点上运行时,它的性能如何?

    答:我们可以为 virtlogd 添加 I/O 速率限制,使其拒绝从单个客户机读取数据过快。这可以防止单个客户机使主机瘫痪。

  4. 问:是否存在架构依赖性?目前,s390 架构上的 nova-compute 节点依赖于 串行控制台 功能,因为它无法提供其他控制台类型(VNC、SPICE、RDP)。这意味着它将受益于同时拥有两者。

    答:没有架构依赖性。

  5. 问:如何处理 virtlogd 守护进程的重启?在停止和启动之间的时间范围内,我们是否会丢失信息?

    答:virtlogd 守护进程能够重新执行自身,同时保持文件句柄打开。这将确保在 virtlogd 重启期间不会丢失数据。

  6. 问:我们需要检查 libvirt 的版本来检测主机上是否可用 virtlodg 吗?或者仅仅检查 /var/log/virtlogd/ 文件夹是否存在就足够了?

    答:我们将检查 libvirt 的版本号,以确定它是否能够使用它。

备选方案

  1. 在启用串行控制台的情况下,我们可以建立与客户机的连接,并执行 tail /var/log/dmesg.log 并将该输出返回到驱动程序的 get_console_output 方法中,该方法用于满足 os-getConsoleOutput REST API。

    反驳:我们需要将身份验证数据保存到客户机,这在技术上并不具有挑战性,但客户可能不满意 Nova 可以在任何时候访问他们的客户机。第二个论点是,串行控制台访问是阻塞的,这意味着如果用户 A 使用实例的串行控制台,则用户 B 无法执行相同的操作。

  2. 我们可以删除 if-else 并创建两个设备。

    反驳:这在 [2] 中尝试过,并停止了,因为这可能会引入向后不兼容性,从而阻止实例的重建。根本原因在于,客户机上有 4 个串行设备的上限,如果将已经具有 4 个串行设备的实例重建到具有补丁 [2] 的计算节点上,则可能会超过该上限。

数据模型影响

REST API 影响

安全影响

通知影响

其他最终用户影响

性能影响

其他部署者影响

  • 此功能需要运行 virtlogd 服务并对其进行监控。

  • 这将解决一个长期存在的 bug,该 bug 可能导致主机磁盘空间耗尽(参见 [3])。

开发人员影响

实现

负责人

主要负责人

Markus Zoeller (https://launchpad.net/~mzoeller)

工作项

  • (可选) 运行一个已启用串行控制台的 gate 作业

  • 添加版本检查,以确定 libvirt 是否支持 virtlogd 功能

  • 添加“正常路径”,该路径创建使用 virtlogd 的客户机设备

  • 确保“重建”在使用从旧主机迁移时使用新功能

  • 添加从 N+1 -> N 主机迁移时的客户机重新配置,以保持向后兼容性

依赖项

  • Libvirt 1.3.3,它带来了 [1] 中描述的libvirt virtlod logging 守护进程

  • Qemu 2.6.0

测试

带有 CONF.compute_feature_enabled.console_output 注释的 tempest 测试将需要使用具有

  • 已解决 virtlogd 依赖项的设置。

  • 并且已启用串行控制台功能(据我所知,目前还没有启用此功能的作业)

  • 必须添加一个针对实时迁移情况的新功能测试

文档影响

参考资料

[1] libvirt ML,“[libvirt] RFC: Building a virtlogd daemon”

https://#/archives/libvir-list/2015-January/msg00762.html

[2] Gerrit,“libvirt: use log file and serial console at the same time”

https://review.openstack.org/#/c/188058/

[3] Launchpad,“ console.log grows indefinitely ”

https://bugs.launchpad.net/nova/+bug/832507

[4] Launchpad,“live block migration results in loss of console log”

https://bugs.launchpad.net/nova/+bug/1203193

[5] libvirt/qemu ML 上的补丁集

  • [PATCH 0/5] Initial patches to introduce a virtlogd daemon

  • [PATCH 1/5] util: add API for writing to rotating files

  • [PATCH 2/5] Import stripped down virtlockd code as basis of virtlogd

  • [PATCH 3/5] logging: introduce log handling protocol

  • [PATCH 4/5] logging: add client for virtlogd daemon

  • [PATCH 5/5] qemu: add support for sending QEMU stdout/stderr to virtlogd

[6] libvirt ML,“[libvirt] [PATCH v2 00/13] Introduce a virtlogd daemon”

https://#/archives/libvir-list/2015-November/msg00412.html

历史

修订版

发布名称

描述

Newton

引入