故障排除 Ironic¶
Nova 返回“未找到有效主机”错误¶
有时 Nova Conductor 日志文件“nova-conductor.log”或 Nova API 返回的消息会包含以下错误
NoValidHost: No valid host was found. There are not enough hosts available.
“未找到有效主机”表示 Nova 调度程序未能找到适合启动新实例的裸金属节点。
这通常意味着 Nova 期望找到的资源与 Ironic 宣传给 Nova 的资源之间存在不匹配。
在这种情况下,应检查几项内容
确保有足够的节点处于“可用”状态,未处于维护模式且未被现有实例使用。使用以下命令检查
baremetal node list --provision-state available --no-maintenance --unassociated
如果此命令未显示足够的节点,请使用通用的 `baremetal node list` 命令检查其他节点。例如,处于“可管理”状态的节点应设为可用
baremetal node provide <IRONIC NODE>
如果访问节点的管理接口时出现问题,Bare Metal 服务会自动将节点置于维护模式。有关详细信息,请参阅电源故障和恢复。
可以使用 `node validate` 命令来验证所有必需字段是否存在。以下命令不应返回任何内容
baremetal node validate <IRONIC NODE> | grep -E '(power|management)\W*False'
如果之前自动清理失败,也会将节点置于维护模式。
确保您的计算服务正在运行并已启用
$ openstack compute service list --service nova-compute +----+--------------+-------------+------+---------+-------+----------------------------+ | ID | Binary | Host | Zone | Status | State | Updated At | +----+--------------+-------------+------+---------+-------+----------------------------+ | 7 | nova-compute | example.com | nova | enabled | up | 2017-09-04T13:14:03.000000 | +----+--------------+-------------+------+---------+-------+----------------------------+
默认情况下,计算服务在连续 10 次构建失败后会被禁用。这是为了确保新的构建请求不会路由到损坏的计算服务。如果是这种情况,请确保修复故障的根源,然后重新启用它
openstack compute service set --enable <COMPUTE HOST> nova-compute
从 Pike 版本开始,请使用以下命令检查所有节点是否都设置了 `resource_class` 字段
baremetal node list --fields uuid name resource_class
然后检查口味(flavor)是否已配置为通过其属性请求这些资源类
openstack flavor show <FLAVOR NAME> -f value -c properties
例如,如果您的节点具有资源类 `baremetal-large`,它将由具有属性 `resources:CUSTOM_BAREMETAL_LARGE` 设置为 `1` 的口味匹配。有关正确配置的更多详细信息,请参阅创建用于 Bare Metal 服务的口味。
在调度时,Nova 将查询 Placement API 服务以获取可用的资源提供程序(在 Ironic 的情况下:具有给定资源类的节点)。如果 Placement 没有所请求资源类的分配候选者,则请求将导致“未找到有效主机”错误。因此,使用以下命令检查 Placement 是否了解所请求资源类的资源提供程序(节点)是明智的
$ openstack allocation candidate list --resource CUSTOM_BAREMETAL_LARGE='1' +---+-----------------------------+--------------------------------------+-------------------------------+ | # | allocation | resource provider | inventory used/capacity | +---+-----------------------------+--------------------------------------+-------------------------------+ | 1 | CUSTOM_BAREMETAL_LARGE=1 | 2f7b9c69-c1df-4e40-b94e-5821a4ea0453 | CUSTOM_BAREMETAL_LARGE=0/1 | +---+-----------------------------+--------------------------------------+-------------------------------+
对于 Ironic,资源提供程序是可用 Ironic 节点的 UUID。如果此命令返回空列表(或不包含目标资源提供程序),则操作员首先需要了解为什么资源跟踪器尚未将此提供程序报告给 placement。潜在的解释包括
资源跟踪器周期尚未完成,一旦完成,资源提供程序就会出现(周期完成时间与相应 `nova-compute` 服务管理的节点数量成正比);
节点处于资源跟踪器不认为其适合调度的状态,例如,当节点 `maintenance` 设置为 `True` 时;请确保目标节点处于 `available` 状态且 `maintenance` 为 `False`;
您正在使用的 Nova 口味(flavor)与任何可用 Ironic 节点的属性都不匹配。使用
openstack flavor show <FLAVOR NAME>
进行比较。您的口味中以 `capability:` 开头的额外规范(extra specs)应与 `node.properties['capabilities']` 中的规范匹配。
注意
Nova 和 Ironic 中能力(capabilities)的格式不同。例如,在 Nova 口味中
$ openstack flavor show <FLAVOR NAME> -c properties +------------+----------------------------------+ | Field | Value | +------------+----------------------------------+ | properties | capabilities:boot_mode='uefi' | +------------+----------------------------------+
但在 Ironic 节点中
$ baremetal node show <IRONIC NODE> --fields properties +------------+-----------------------------------------+ | Property | Value | +------------+-----------------------------------------+ | properties | {u'capabilities': u'boot_mode:uefi'} | +------------+-----------------------------------------+在 Ironic 中更改节点后,需要一段时间才能将这些更改从 Ironic 传播到 Nova。检查
openstack hypervisor stats show
是否正确显示了您系统中的总资源量。您还可以检查 `openstack hypervisor show
` 以查看 Nova 报告的各个 Ironic 节点的状态。 找出是哪个 Nova 调度程序过滤器排除了您的节点。检查 `nova-scheduler` 日志中包含类似内容的行
Filter ComputeCapabilitiesFilter returned 0 hosts
排除最后主机的过滤器的名称可能会提供关于确切匹配项未匹配的提示。有关更多详细信息,请参阅Nova 过滤器文档。
如果以上均无效,请仔细检查 Ironic conductor 日志,查看是否有任何 conductor 相关的错误是“未找到有效主机”的根源。如果在 Ironic conductor 日志中有任何“部署节点
时出错:[Errno 28] ...”错误消息,则表示 conductor 在部署过程中遇到了特殊错误。因此,您可以仔细检查日志以进行修复或规避,然后重试。
修补部署 Ramdisk¶
在调试部署和/或检查问题时,您可能希望快速应用对 ramdisk 的更改以查看其是否有帮助。当然,您可以在 ramdisk 构建期间注入您的代码和/或 SSH 密钥(取决于您确切的构建方式)。但也可以快速修改已构建的 ramdisk。
创建一个空目录并将 ramdisk 内容解压到那里
$ mkdir unpack
$ cd unpack
$ gzip -dc /path/to/the/ramdisk | cpio -id
最后一个命令将在当前目录中解压整个 Linux 文件系统树。现在您可以修改任何您想要的文件。文件的实际位置将取决于您构建 ramdisk 的方式。
注意
在基于 systemd 的系统上,您可以使用 `systemd-nspawn` 工具(来自 `systemd-container` 包)从解压的文件系统树创建轻量级容器
$ sudo systemd-nspawn --directory /path/to/unpacked/ramdisk/ /bin/bash
这将允许您在文件系统内运行命令,例如使用包管理器。如果 ramdisk 也是基于 systemd 的,并且您已设置登录凭据,您甚至可以通过以下方式启动真实的 ramdisk 环境
$ sudo systemd-nspawn --directory /path/to/unpacked/ramdisk/ --boot
完成修改后,将当前目录的全部内容重新打包
$ find . | cpio -H newc -o | gzip -c > /path/to/the/new/ramdisk
注意
您不需要修改内核(例如 `tinyipa-master.vmlinuz`),只需要修改 ramdisk 部分。
API 错误¶
`debug_tracebacks_in_api` 配置选项可以设置为在所有 4xx 和 5xx 错误中返回 API 响应中的堆栈跟踪。
从部署 Ramdisk 检索日志¶
在调试部署(特别是在部署失败的情况下)时,能够访问部署 ramdisk 的日志以识别问题根源非常重要。默认情况下,Ironic 在部署失败时会从部署 ramdisk 检索日志,并将其保存在本地文件系统的 `/var/log/ironic/deploy` 目录中。
要更改此行为,操作员可以在 `/etc/ironic/ironic.conf` 文件中的 `[agent]` 组下进行以下更改
`deploy_logs_collect`: Ironic 是否应在部署时收集部署日志。此选项的有效值为
`on_failure` (**默认**): 在部署失败时检索部署日志。
`always`: 始终检索部署日志,即使部署成功。
`never`: 禁用检索部署日志。
`deploy_logs_storage_backend`: 日志将存储的存储后端名称。此选项的有效值为
`local` (**默认**): 将日志存储在本地文件系统中。
`swift`: 将日志存储在 Swift 中。
`deploy_logs_local_path`: 当 `deploy_logs_storage_backend` 配置为 `local` 时,日志应存储的目录路径。默认情况下,日志将存储在 **`/var/log/ironic/deploy`**。
`deploy_logs_swift_container`: 当 deploy_logs_storage_backend 配置为“swift”时,用于存储日志的 Swift 容器名称。默认是 **`ironic_deploy_logs_container`**。
`deploy_logs_swift_days_to_expire`: 日志对象在 Swift 中被标记为过期的天数。如果为 None,则日志将永久保留,或直到手动删除。当 deploy_logs_storage_backend 配置为“swift”时使用。默认是 **30** 天。
当日志被收集时,Ironic 将根据 `deploy_logs_storage_backend` 配置选项存储一个包含所有日志的 `.tar.gz` 文件。所有日志对象的命名将遵循以下模式
<node>[_<instance-uuid>]_<timestamp yyyy-mm-dd-hh:mm:ss>.tar.gz
注意
当 Ironic 配置为独立模式使用时,部署节点不需要 `instance_uuid` 字段。如果存在,它将被附加到名称中。
访问日志数据¶
存储在本地文件系统中时¶
当将日志存储在本地文件系统中时,日志文件可以在 `deploy_logs_local_path` 配置选项中配置的路径中找到。例如,查找来自节点 `5e9258c4-cfda-40b6-86e2-e192f523d668` 的日志
$ ls /var/log/ironic/deploy | grep 5e9258c4-cfda-40b6-86e2-e192f523d668
5e9258c4-cfda-40b6-86e2-e192f523d668_88595d8a-6725-4471-8cd5-c0f3106b6898_2016-08-08-13:52:12.tar.gz
5e9258c4-cfda-40b6-86e2-e192f523d668_db87f2c5-7a9a-48c2-9a76-604287257c1b_2016-08-08-14:07:25.tar.gz
注意
在将日志保存到文件系统时,操作员可能希望启用某种形式的日志轮换,以避免磁盘空间问题。
存储在 Swift 中时¶
当使用 Swift 时,操作员可以将容器中的对象与 Ironic 中的节点关联起来,并使用 **prefix** 参数搜索节点 `5e9258c4-cfda-40b6-86e2-e192f523d668` 的日志。例如
$ swift list ironic_deploy_logs_container -p 5e9258c4-cfda-40b6-86e2-e192f523d668
5e9258c4-cfda-40b6-86e2-e192f523d668_88595d8a-6725-4471-8cd5-c0f3106b6898_2016-08-08-13:52:12.tar.gz
5e9258c4-cfda-40b6-86e2-e192f523d668_db87f2c5-7a9a-48c2-9a76-604287257c1b_2016-08-08-14:07:25.tar.gz
要从 Swift 下载特定日志,请执行
$ swift download ironic_deploy_logs_container "5e9258c4-cfda-40b6-86e2-e192f523d668_db87f2c5-7a9a-48c2-9a76-604287257c1b_2016-08-08-14:07:25.tar.gz"
5e9258c4-cfda-40b6-86e2-e192f523d668_db87f2c5-7a9a-48c2-9a76-604287257c1b_2016-08-08-14:07:25.tar.gz [auth 0.341s, headers 0.391s, total 0.391s, 0.531 MB/s]
日志文件的内容¶
日志只是一个 `.tar.gz` 文件,可以按以下方式解压
$ tar xvf <file path>
文件内容可能因部署 ramdisk 使用的发行版而略有不同
对于使用 `systemd` 的发行版,将有一个名为 **journal** 的文件,其中包含通过 `journalctl` 命令收集的所有系统日志。
对于其他发行版,ramdisk 将收集 `/var/log` 目录的所有内容。
对于所有发行版,日志文件还将包含以下命令的输出(如果存在): `ps`、`df`、`ip addr` 和 `iptables`。
以下是一个示例,展示了解压使用 `systemd` 的发行版的日志文件内容
$ tar xvf 5e9258c4-cfda-40b6-86e2-e192f523d668_88595d8a-6725-4471-8cd5-c0f3106b6898_2016-08-08-13:52:12.tar.gz
df
ps
journal
ip_addr
iptables
PXE 或 iPXE 期间的 DHCP 不一致或不可靠¶
这可能是由于某些交换机上的生成树协议延迟造成的。在节点尝试 PXE 期间,该延迟阻止交换机端口进入转发模式,因此数据包永远无法到达 DHCP 服务器。要解决此问题,应将连接到裸金属节点的交换机端口设置为边缘端口或 PortFast 类型端口。这样配置后,交换机端口将在链接建立后立即进入转发模式。以 Cisco Nexus 交换机为例,操作方法如下
$ config terminal
$ (config) interface eth1/11
$ (config-if) spanning-tree port type edge
为什么在使用 LACP bonding 和 iPXE 时会出现 X 问题?¶
如果您使用 iPXE,其设计和网络交互的一个不幸方面是它会自动响应远程交换机的链路聚合控制协议(LACP)对端。iPXE 仅为用于网络引导的单个端口执行此操作。
理论上,这可能有助于加快与某些交换机供应商的端口链接状态的建立,但据 Ironic 开发人员所知,iPXE 的官方原因并未记录在案。其最终结果是,一旦 iPXE 停止响应对端端口发出的 LACP 消息(在启动 ramdisk 和 iPXE 将控制权移交给完整操作系统过程中会发生),交换机通常会启动一个计时器来确定如何处理故障。这是因为,根据 LACP 的模式,这可能被解释为交换机或网络 fabric 故障。
这可能表现为 ramdisk 发现无法通过网络接口获取 DHCP 地址、下载突然停止,甚至是一些小问题,例如内省(introspection)中 LLDP 端口数据不可用等各种行为或问题。
总体而言
Ironic 的代理不支持 LACP,Ironic 社区普遍认为这可能会弊大于利。在 Victoria 开发周期期间,我们为大多数操作添加了重试逻辑,试图应对最差的默认等待时间,以确保部署不会因交换机端口进入临时阻塞状态的短暂网络连接故障而失败。在适用且可能的情况下,这些补丁已向后移植到支持的版本。这些补丁还要求交换机端口最终能够回退到非绑定模式。如果端口保持阻塞状态,流量将无法流动,部署很可能会超时。
如果您必须使用 LACP,请考虑在网络交换机中使用 `passive` LACP 协商设置,而不是 `active`。区别在于,使用 passive 时,连接的工作负载很可能是一台服务器,它应该请求交换机建立链路聚合。而不是被视为另一台交换机。
请咨询您的交换机供应商的支持论坛。一些供应商为使用 iPXE 引导机器的交换机提供推荐的端口设置。
IPMI 错误¶
在使用 IPMI 时,根据供应商不同,需要启用几个设置。
启用 IPMI over LAN¶
默认情况下,机器可能未启用通过 LAN 的 IPMI。这可能导致 IPMI 端口无法通过 ipmitool 访问,如
$ ipmitool -I lan -H ipmi_host -U ipmi_user -P ipmi_pass chassis power status
Error: Unable to establish LAN session
要解决此问题,请使用您的 BMC 工具或 Web 应用程序启用 `IPMI over lan` 设置。
故障排除 lanplus 接口¶
在使用 lanplus 接口时,您可能会遇到以下错误
$ ipmitool -I lanplus -H ipmi_host -U ipmi_user -P ipmi_pass power status
Error in open session response message : insufficient resources for session
Error: Unable to establish IPMI v2 / RMCP+ session
要解决此问题,请使用您的 BMC 工具或 Web 应用程序启用 `RMCP+ Cipher Suite3 Configuration` 设置。
为什么我的节点卡在“-ing”状态?¶
Ironic conductor 使用以 `-ing` 结尾的状态作为指示,表明 conductor 正在积极处理与节点相关的某项工作。
通常,这意味着节点上设置了内部锁或 `reservation`,并且 conductor 正在下载、上传或尝试执行某种输入/输出操作 - 有关详细信息,请参阅API 返回“节点被主机锁定”的原因。
在 conductor 卡住的情况下,这些操作应超时,但在操作系统中存在操作会阻塞直到完成的情况。这类操作会根据具体环境和配置的不同而有所差异。
什么可能导致这类故障?¶
这类故障的典型原因主要与 `iowait` 的概念有关,无论是从远程主机下载还是在 conductor 的磁盘上读取或写入。操作员可以使用 `iostat` 工具来识别花费在存储设备等待上的 CPU 时间百分比。
特别重要的字段是 `iowait`、`await` 和 `tps`,这些可以在 `iostat` 手册页中找到。
在网络文件系统的情况下,对于像镜像缓存或分布式 `tftpboot` 或 `httpboot` 文件夹等后端组件,IO 操作的失败可能会(取决于操作系统和底层客户端设置)导致线程卡在阻塞等待状态,这实际上是无法检测到的,除非操作系统记录连接错误甚至锁管理器访问错误。
例如,对于 `nfs`,底层客户端恢复行为,就 `soft`、`hard`、`softreval`、`nosoftreval` 而言,将很大程度上影响此行为,但 NFS 服务器设置也会影响此行为。失败的一个明确迹象是 `ls /path/to/nfs` 命令挂起一段时间。在这种情况下,应咨询存储管理员并检查网络连接是否存在错误,然后再尝试恢复以继续。
文件大小 != 磁盘大小¶
一个容易产生的误解是,2.4 GB 的文件意味着只有 2.4 GB 被写入磁盘。但是,如果该文件的虚拟大小是 20 GB 或 100 GB,则情况可能会非常糟糕,并延长节点在 `deploying` 和 `deploy wait` 状态下花费的时间。
同样,这类情况将取决于部署的具体配置,但希望这些是这些操作可能发生的地方。
根据 `force_raw_images` 选项,在下载到 conductor 时将镜像转换为原始镜像文件。使用 Glance 的用户也可能在这里遇到问题,因为 conductor 会缓存要写入的镜像,当 `image_download_source` 设置为 `http` 而不是 `swift` 时就会发生这种情况。
注意
QCOW2 镜像转换实用程序在转换镜像或将其写入最终存储设备时会消耗大量内存。这是因为文件不是顺序的,并且必须从内部块映射中重新组装。内部 Ironic 将此限制为 1GB RAM。执行大量部署的操作员可能希望在这些情况下禁用原始镜像,以最大限度地减少 conductor 因内存和网络 IO 而成为限制因素。
为什么我的节点卡在“等待”状态?¶
Ironic conductor 使用包含 `wait` 的状态作为指示,表示 conductor 正在等待来自另一个组件的回调,例如 Ironic Python Agent 或 Inspector。如果此反馈未到达,conductor 将超时,节点最终将进入 `failed` 状态。然而,根据配置和情况,节点可能会长时间停留在 `wait` 状态,甚至永远不会超时。这类等待状态包括
`clean wait` 用于清理,
`inspect wait` 用于内省,
`rescue wait` 用于救援,以及
`wait call-back` 用于部署。
Conductor 和节点之间的通信问题¶
当节点似乎卡在等待状态时,最常见的问题之一是节点从未收到任何指令或未按预期做出反应:conductor 已将节点移至等待状态,但节点永远不会回调。例如,错误的密码套件(ciphers)会导致 ipmitool 卡住,或者 BMC 处于接受命令但未执行请求任务(或仅执行部分任务,如关闭,但不启动)的状态。在这种情况下,通过 ping 或控制台查看节点是否执行了任何操作以及执行了什么操作很有用。如果节点似乎对 conductor 发出的请求没有反应,则尝试带外执行相应操作可能值得,例如直接发送到 BMC 来确认开/关命令是否正常工作。有关 IPMI 错误的章节。上面提供了一些额外的检查点。在某些情况下,可能需要重置 BMC。
Ironic Python Agent 卡住¶
当 conductor 等待的组件卡住时,节点也可能停留在等待状态,例如,当硬件管理器进入循环或等待一个永不发生的事件时。在这些情况下,连接到 IPA 并检查其日志可能很有帮助,请参阅 ironic-python-agent (IPA) 的故障排除指南,了解如何执行此操作。
停止操作¶
可以通过 `abort` 命令在 `clean wait`、`inspect wait`、`service wait` 和 `rescue wait` 状态下停止清理、检查、服务和救援。如果当前运行的步骤的 `abortable` 参数设置为 `True`,则 abort 会立即发生,否则将在当前运行的步骤完成后中止。节点将被移至相应的失败状态(`clean failed`、`inspect failed`、`service failed` 或 `rescue failed`)。
baremetal node abort <node>
通过启动 undeploy(通常导致清理)可以中止在 `wait call-back` 状态下的部署。
baremetal node undeploy <node>
有关更多详细信息,请参阅裸金属状态机。
注意
由于 Bare Metal 服务在等待状态下不执行任何主动操作,因此在 conductor 重启时,节点不会移至失败状态。
部署因“无法更新 MAC 地址”而失败¶
与网络服务(neutron)的集成设计是这样的:一旦在 API 中创建了虚拟端口,就必须更新其 MAC 地址,以便 DHCP 服务器能够适当地响应。
这有时会导致出现错误,表明 MAC 地址已在使用中。这是因为在过去某个时候,一个虚拟接口被意外或由于某种意外故障而孤立,并且之前的条目仍然存在于 Neutron 中。
当在 ironic-conductor 日志输出中报告时,此错误看起来像这样。
无法在 Neutron 端口 305beda7-0dd0-4fec-b4d2-78b7aa4e8e6a 上更新 MAC 地址:MacAddressInUseClient:无法完成网络 1e252627-6223-4076-a2b9-6f56493c9bac 的操作。MAC 地址 52:54:00:7c:c4:56 正在使用中。
由于我们对此条目一无所知,因此我们使部署过程失败,因为我们无法做出任何假设来尝试自动解决冲突。
我怎么会遇到这种情况?¶
最初这是一个相当容易遇到的问题。编排(heat)和服务(nova)之间的重试逻辑路径有时会导致创建额外的非必要端口。
此类错误自 Rocky 开发周期以来已基本得到解决。此后,此问题可能出现的原因是网络(neutron)VIF 附件在删除 Bare Metal 服务中的端口之前未被移除或删除。
最终,关键在于端口正在被删除。在大多数操作情况下,确实没有必要删除端口,并且 VIF 附件存储在端口对象上,因此删除端口*可能*会导致 VIF 未在 Neutron 中清理干净。
在正常情况下,删除端口时,节点应处于稳定状态,并且不应已配置。如果 `baremetal port delete` 命令失败,这可能表明仍有关联一个已知的 VIF。通常,如果它们是暂时的(来自清理、配置、救援甚至检查),将节点置于 `available` 状态将解除您的删除操作的阻塞,除非存在租户 VIF 附件。在这种情况下,需要使用 `baremetal node vif detach` 命令从 Bare Metal 服务中移除 VIF。
可以通过检查端口的 `internal_info` 字段来查看端口是否有关联的 VIF 附件。
警告
`maintenance` 标志可用于强制删除节点的端口,但这将禁用任何通常会阻止用户发出删除命令并意外孤立 VIF 附件记录的检查。
如何解决这个问题?¶
通常,您需要识别具有问题 MAC 地址的端口。示例
$ openstack port list --mac-address 52:54:00:7c:c4:56
从命令的输出中,您应该能够识别 `id` 字段。使用它,您可以删除该端口。示例
$ openstack port delete <id>
警告
在删除端口之前,应始终验证它是否不再使用或不再适用/可操作。如果 Bare Metal 服务与单个 Neutron 进行多次部署,则可能存在库存输入错误,或者甚至重复的 MAC 地址,这也可能产生相同的基本错误消息。
我的测试 VM 镜像未部署 - 挂载点不存在¶
可能发生的情况¶
尝试部署的镜像很可能是分区镜像,其中用户希望从中引导的文件系统缺少所需的文件夹,例如 `/dev` 和 `/proc`,这些是安装 Linux 操作系统镜像的引导加载程序所必需的。
应注意,对于我们正在尝试设置 UEFI 引导加载程序配置的整个磁盘镜像,也可能出现类似的错误。也就是说,在这种情况下,镜像可能无效或包含意外的内部结构。
进行测试的用户可能会选择他们认为会起作用的东西,因为它们在虚拟机上有效。这些镜像通常对测试很有吸引力,因为它们是通用的,并且包括建立网络和可能安装用户密钥的基本支持。不幸的是,这些镜像通常缺乏许多不同类型物理硬件所需的驱动程序和固件,这使得使用它们非常成问题。此外,像 Cirros 这样的镜像在其根文件系统中没有任何内容(即空文件系统),因为它们设计用于 `ramdisk` 在启动时将内容写入磁盘。
如何避免此问题?¶
我们通常建议使用 diskimage-builder 或供应商提供的镜像。Centos、Ubuntu、Fedora 和 Debian 都发布了通常包含物理硬件驱动程序和固件的操作系统镜像。其中许多发布的“云”镜像还支持网络自动配置和用户密钥填充。
自动配置 TLS 的问题¶
这些问题将表现为 `ironic-conductor` 日志中的错误,看起来类似于(为了便于阅读,行已换行)
ERROR ironic.drivers.modules.agent_client [-]
Failed to connect to the agent running on node d7c322f0-0354-4008-92b4-f49fb2201001
for invoking command clean.get_clean_steps. Error:
HTTPSConnectionPool(host='192.168.123.126', port=9999): Max retries exceeded with url:
/v1/commands/?wait=true&agent_token=<token> (Caused by
SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:897)'),)):
requests.exceptions.SSLError: HTTPSConnectionPool(host='192.168.123.126', port=9999):
Max retries exceeded with url: /v1/commands/?wait=true&agent_token=<token>
(Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:897)'),))
问题的原因是 Bare Metal 服务无法访问带有 ramdisk 在第一次心跳时提供的 TLS 证书。您可以在 `/var/lib/ironic/certificates/
您可以尝试使用日志消息中的 IP 地址连接到 ramdisk
curl -vL https://<IP address>:9999/v1/commands \
--cacert /var/lib/ironic/certificates/<node UUID>.crt
您可以使用 openSSL 获取有关证书的详细信息
openssl x509 -text -noout -in /var/lib/ironic/certificates/<node UUID>.crt
时钟偏移¶
问题的一个可能来源是节点上的硬件时钟与 Bare Metal 服务所在机器的时间之间的差异。可以通过比较 `openssl` 输出中的 `Not Before` 字段与日志消息的时间戳来检测。
建议的解决方案是通过传递 `ipa-ntp-server` 参数和 NTP 服务器地址(节点可访问)来启用 ironic-python-agent 中的 NTP 支持。
如果不可能,则需要确保机器上的硬件时间正确。请注意时区可能存在的问题:存储时区在硬件中的能力是最近才出现的,可能不可用。由于 ironic-python-agent 很可能在 UTC 下运行,因此硬件时钟也应设置为 UTC。
注意
Microsoft Windows 默认使用本地时间,因此以前运行过 Windows 的机器可能时间不正确。
我检查了时钟偏移,尝试了 NTP 同步,证书报告尚未生效¶
如果您遇到过尝试同步系统时钟但部署/清理操作失败,并声称证书尚未生效或已过期的情况,可能存在一些不同的问题。
但首先,我们需要区分一个方面。大多数系统中存在不止一个时钟。
具体来说,基板管理控制器(Baseboard Management Controller)有自己的时钟,该时钟可能与系统的“主机”时钟同步,也可能不同步。确保在 BIOS 固件设置中检查主机时钟非常重要。最好的方法是,在控制台上,启动到固件设置,并检查“日期/时间设置”。
在大多数情况下,简单的时钟偏移可以通过使用 `ipa-ntp-server` 设置来解决,但是 Ironic 社区已经注意到一些报告说即使这也不能解决问题。调查发现一些硬件还允许引入带有 UTC 偏移量或本地化时区的时区设置。似乎当 ramdisk 启动时,ramdisk 时钟无法正确计算 UTC,并且由于固件设置中应用的了时区设置,它会认为时间有偏移。Ironic 社区建议系统中使用的唯一时区设置为 UTC,因为 Linux 通常期望系统时钟为 UTC。
另一个选项是 ironic-python-agent 配置文件中的 `auto_tls_allowed_clock_skew` 设置。它默认为 1 小时。如果您发现需要在部署中修改此设置,请通知 Ironic 社区。
我更改了 ironic.conf,现在我无法编辑我的节点。¶
每当在 ironic 中创建节点时,都会在驱动程序组合中识别默认接口。这可能源于 `ironic.conf` 中设置的显式默认值,或由已启用接口列表的接口顺序决定。结果是 `ironic-conductor` 无法使用组合驱动程序生成 `task`,因为驱动程序的某一部分不再启用。这使得编辑或更新节点变得困难,如果设置已更改。
例如,对于网络接口,如果在 `ironic.conf` 中设置了 `default_network_interface=neutron` 或 `enabled_network_interfaces=neutron,flat`,则节点将使用 `neutron` 网络接口创建。
这是因为 `default_network_interface` 会覆盖新节点的设置,并且该设置会被**保存**到数据库的 nodes 表中。
同样,`enabled_network_interfaces` 的顺序具有优先权,列表中的第一个条目通常在创建节点时设置为默认值,并且该记录会**保存**到数据库的 nodes 表中。
驱动程序组合不计算默认值的唯一情况是,在创建节点时提供了显式值。
示例故障¶
处于此状态的节点,当 `network_interface` 保存为 `neutron` 时,但 `neutron` 接口不再启用,将导致基本的转换请求失败
$ baremetal node manage 7164efca-37ab-1213-1112-b731cf795a5a
Could not find the following interface in the 'ironic.hardware.interfaces.network' entrypoint: neutron. Valid interfaces are ['flat']. (HTTP 400)
如何修复此问题?¶
恢复您对 `ironic.conf` 所做的更改。
这适用于对任何 `default_*_interface` 选项的更改,或 `enabled_*_interfaces` 选项中的接口顺序的更改。
在使用更新的配置重新启动 conductor 后,您应该能够使用 `baremetal node set` 命令更新接口。在此示例中,我们使用 `network_interface`,因为这是最常遇到这种情况的地方
$ baremetal node set $NAME_OR_UUID --network-interface flat
注意
有其他方法可以解决这类问题,但我们鼓励操作员在进行重大配置更改时注意操作一致性。
更新保存的接口后,您应该能够安全地在 `ironic.conf` 配置更改中更改 conductor 启用的接口。
我收到内存不足错误¶
这个问题,也称为“OOMKiller 杀死了我的 conductor”,是指您的操作系统内存达到某个点,操作系统会采取措施来减少内存消耗,以防止机器完全崩溃。不幸的是,这可能导致不可预测的行为。
我怎么会遇到这种情况?¶
运行 ironic-conductor 的主机中内存的主要消耗者之一是使用 `qemu-img` 工具转换磁盘镜像。该工具,因为其处理的磁盘镜像经过压缩且块顺序不线性,需要相当多的内存才能有效地重新组装并将磁盘写入设备,或仅仅是转换格式(例如转换为 `raw` 镜像)。
默认情况下,ironic 的配置将此转换限制为该进程的 1 GB RAM,但每次转换都会导致额外的缓冲区内存使用,这会增加整体系统内存压力。通常仅来自缓冲区的内存压力不会导致内存不足的情况,但同时运行的多个转换或部署*可能*会导致极大的内存压力并存在系统内存不足的风险。
如何解决这个问题?¶
可以通过几种不同的方式解决此问题
使用原始镜像,但这些镜像可能大得多,并且需要传输更多数据“通过线路”。
添加更多物理内存。
添加交换空间。
减少并发,可能通过另一个 conductor 或更改 nova-compute.conf 的 `max_concurrent_builds` 参数。
或者最后,调整 `ironic.conf` 文件中的 `DEFAULT.minimum_required_memory` 参数。默认值应被视为“最后的手段默认值”,您可能需要预留额外的内存。您可能还希望调整 `DEFAULT.minimum_memory_wait_retries` 和 `DEFAULT.minimum_memory_wait_time` 参数。
为什么 API 返回“节点被主机锁定”?¶
此错误通常表现为客户端的 HTTP 错误 409
节点 d7e2aed8-50a9-4427-baaa-f8f595e2ceb3 被主机 192.168.122.1 锁定,请在当前操作完成后重试。
发生这种情况是因为请求了一个修改节点的操作,而另一个此类操作正在运行。冲突的操作可能是用户请求的(例如,配置操作)或与内部进程相关的(例如,在电源同步期间更改电源状态)。报告的主机名对应于持有锁的 conductor 实例。
通常,这些错误是短暂的,可以安全地在几秒钟后重试。如果锁被持有很长时间,您可以采取以下步骤。
首先,检查节点的当前 `provision_state`
verifying表示 conductor 正在尝试访问节点的 BMC。如果这种情况持续数分钟,则表示 BMC 要么无法访问,要么行为异常。仔细检查 `driver_info` 中的信息,特别是 BMC 地址和凭据。
如果访问详细信息正确,请尝试使用其 Web UI 等重置 BMC。
- `deploying` / `inspecting` / `cleaning`
表示 conductor 正在执行一些活动工作。这可能包括下载或转换镜像,执行同步带外部署或清理步骤等。节点可能在此状态下停留数分钟,具体取决于各种因素。请查阅 conductor 日志。
- `available` / `manageable` / `wait call-back` / `clean wait`
表示某个后台进程正在持有锁。最常见的是电源同步循环。与 `verifying` 状态类似,它可能表示 BMC 访问已损坏或太慢。Conductor 日志将为您提供正在发生的情况的见解。
使用 conductor 日志跟踪进程
隔离相关的日志部分。锁定消息来自 `ironic.conductor.task_manager` 模块。您还可以检查 `ironic.common.states` 模块中的任何状态转换。
$ grep -E '(ironic.conductor.task_manager|ironic.common.states|NodeLocked)' \ conductor.log > state.log
查找 `NodeLocked` 的第一个实例。它可能看起来像这样(为便于阅读,此处及以下内容省略了时间戳和请求 ID)
DEBUG ironic.conductor.task_manager [-] Attempting to get exclusive lock on node d7e2aed8-50a9-4427-baaa-f8f595e2ceb3 (for node update) __init__ /usr/lib/python3.6/site-packages/ironic/conductor/task_manager.py:233 DEBUG ironic_lib.json_rpc.server [-] RPC error NodeLocked: Node d7e2aed8-50a9-4427-baaa-f8f595e2ceb3 is locked by host 192.168.57.53, please retry after the current operation is completed. _handle_error /usr/lib/python3.6/site-packages/ironic_lib/json_rpc/server.py:179
此故障之前的事件将为您提供关于锁被持有的原因的线索。
查找故障之前的最后一个成功*独占*锁定事件,例如
DEBUG ironic.conductor.task_manager [-] Attempting to get exclusive lock on node d7e2aed8-50a9-4427-baaa-f8f595e2ceb3 (for provision action manage) __init__ /usr/lib/python3.6/site-packages/ironic/conductor/task_manager.py:233 DEBUG ironic.conductor.task_manager [-] Node d7e2aed8-50a9-4427-baaa-f8f595e2ceb3 successfully reserved for provision action manage (took 0.01 seconds) reserve_node /usr/lib/python3.6/site-packages/ironic/conductor/task_manager.py:350 DEBUG ironic.common.states [-] Exiting old state 'enroll' in response to event 'manage' on_exit /usr/lib/python3.6/site-packages/ironic/common/states.py:307 DEBUG ironic.common.states [-] Entering new state 'verifying' in response to event 'manage' on_enter /usr/lib/python3.6/site-packages/ironic/common/states.py:313
这是根本原因,由于验证 BMC 凭据而持有锁。
查找锁何时被释放(如果被释放)。消息看起来像这样
DEBUG ironic.conductor.task_manager [-] Successfully released exclusive lock for provision action manage on node d7e2aed8-50a9-4427-baaa-f8f595e2ceb3 (lock was held 60.02 sec) release_resources /usr/lib/python3.6/site-packages/ironic/conductor/task_manager.py:447
消息告诉您锁被持有的原因(`for provision action manage`)以及被持有的时间(60.02 秒,这对于访问 BMC 来说太长了)。
不幸的是,由于 conductor 的设计方式,无法优雅地中断在 `*-ing` 状态下卡住的锁。作为最后的手段,您可能需要重启受影响的 conductor。请参阅为什么我的节点会卡在“-ing”状态?。
ConcurrentActionLimit 是什么?¶
ConcurrentActionLimit 是一个异常,当请求的操作无法立即服务时,会向客户端引发此异常,因为已达到并发“部署”或“清理”操作的节点总阈值。
这些限制存在两个截然不同的原因。
第一个是它们允许操作员调整部署,这样在任何给定时间都不能触发过多的并发部署,因为单个 conductor 对总体并发任务有一个内部限制,这只限制了正在运行的并发操作的数量。因此,这考虑了处于 `deploy` 和 `deploy wait` 状态的节点数量。在部署的情况下,默认值相对较高,应该适合*大多数*大型操作员。
第二个是为了帮助减缓将整个裸金属节点群迁移到清理过程中的能力,以帮助防范经过身份验证的恶意用户或意外的脚本驱动操作。在这种情况下,会评估处于 `deleting`、`cleaning` 和 `clean wait` 状态的节点总数。清理操作的默认最大限制是*50*,应适合大多数裸金属操作员。
可以通过使用支持 `ironic-conductor` 服务的 ironic.conf 文件中的 `max_concurrent_deploy` 和 `max_concurrent_clean` 设置来修改这些设置。这两个设置都不能显式禁用,但是设置也没有上限。
注意
这是基础设施操作员根据 Ironic 在大规模生产中的实际运维经验提出的功能请求。默认值可能不适合最大规模的操作员。
为什么会出现 NVMe 分区不是块设备的错误?¶
在某些情况下,您可能会遇到一个错误,表明 NVMe 块设备上创建的分区不是块设备。
示例
lsblk: /dev/nvme0n1p2: not a block device
发生的情况是分区内部包含一个分区表,这会混淆 NVMe 设备交互。虽然在某些情况下(例如软件 RAID)拥有嵌套分区表在根本上是有效的,但在 NVMe 的情况下,驱动程序和可能的底层设备会变得非常困惑。部分原因是 NVMe 设备中的分区是更高级别的抽象。
出现这种情况的方式是您可能有一个 `whole-disk` 镜像,并且它被配置为分区镜像。如果使用 glance,您的镜像属性可能有一个 `img_type` 字段,该字段应为 `whole-disk`,或者您在 glance 镜像 `properties` 字段中有一个 `kernel_id` 和 `ramdisk_id` 值。内核和 ramdisk 值的定义也表明该镜像属于 `partition` 镜像类型。这是因为 `whole-disk` 镜像可以从镜像内的内容启动,而分区镜像在没有内核和 ramdisk 的情况下无法启动。
如果您在独立模式下使用 Ironic,建议检查可选的 `instance_info/image_type` 设置。与上面的 Glance 用法非常相似,如果您设置了 Ironic 的节点级 `instance_info/kernel` 和 `instance_info/ramdisk` 参数,Ironic 将继续像部署分区镜像一样部署镜像,创建一个新的块设备上的分区表,然后将镜像的内容写入新创建的分区。
注意
作为一般提醒,Ironic 社区建议使用全盘镜像而不是分区镜像。
为什么我不能将安全擦除/擦除与 RAID 控制器一起使用?¶
据报道,存在一些情况,基础设施操作员期望在 RAID 控制器后面的特定设备类型被安全擦除或擦除。
例如,服务器可能连接有 NVMe 设备到 RAID 控制器,该控制器可能处于直通或单磁盘卷模式。同样的情况基本上存在于任何磁盘/存储介质/类型。
基本原因在于 RAID 控制器基本上充当具有缓冲缓存的命令转换器。它们倾向于向操作系统提供简化的协议,并以设备的原生协议与存储设备进行交互。这是根本问题的根源。
SCSI 等协议植根于大量的计算历史,但从未发展到包含像安全擦除这样的原始命令,后者是在ATA 协议中出现的。
SCSI 中最接近 ATA 安全擦除的原始命令是 `FORMAT UNIT` 和 `UNMAP` 命令。
`FORMAT UNIT` 可能是一个可行的解决方案,并且有一个名为 `sg_format` 的工具,但上游没有足够的调用来实现并充分测试它,以至于 Ironic 社区会放心地发布这种功能。也有可能 RAID 控制器不会将此命令传递到最终设备,就像某些 RAID 控制器知道如何处理 ATA 命令并将其传递给支持它们的磁盘设备一样。这完全取决于硬件配置场景。
`UNMAP` 命令类似于 ATA `TRIM` 命令。不幸的是,SCSI 协议要求在块级别执行此操作,与 `FORMAT UNIT` 类似,它可能不受支持或只是被传递。
如果您有兴趣在此领域工作,或愿意提供测试帮助,请随时联系Ironic 开发社区。另一个选项是创建您自己的自定义硬件管理器,其中可以包含您首选的逻辑,但这需要一些 Python 开发经验。
最后一点需要注意,根据 RAID 控制器、BMC 和许多其他变量,您可能能够利用 RAID 配置界面来删除卷/磁盘,然后重新创建它们。这可能与干净磁盘具有相同效果,但这也取决于 RAID 控制器的行为。
我处于“clean failed”状态,该怎么办?¶
退出 `clean failed` 状态只有一种方法。但在我们了解*如何*操作之前,我们需要强调尝试理解*为什么*清理失败的重要性。简单地说,这可能只是 DHCP 故障,但在复杂的情况下,它可能是清理操作针对底层硬件失败,可能由于硬件故障。
因此,我们鼓励大家在退出 `clean failed` 状态*之前*尝试理解*为什么*会失败,因为您可能会使情况变得更糟。例如,如果正在进行固件更新,您可能需要对物理服务器执行回滚操作,具体取决于固件的更新内容和方式。不幸的是,这也接近于“没有简单答案”的领域。
这可以用有时发生的瞬态网络故障和未获得 DHCP 地址的情况来抵消。例如,`last_error` 字段指示“清理节点时达到超时”的内容会暗示这一点,但我们建议遵循几个基本的故障排除步骤
咨询节点的 `last_error` 字段,使用 `baremetal node show
` 命令。 如果 Ironic 的版本支持该功能,请查阅节点历史日志,`baremetal node history list` 和 `baremetal node history get
`。 检查物理机的实际控制台屏幕。*如果* ramdisk 启动了,您通常需要检查控制器日志,并查看是否在负责裸金属节点的 conductor 上存储了上传的代理日志。请参阅从部署 Ramdisk 检索日志。如果节点由于某种原因未启动,您通常可以立即重试并继续。
一旦您明白了*为什么*会达到该状态,如何退出该状态是利用 `baremetal node manage
在我添加了大量新节点后,我似乎无法内省它们¶
在较大的集群中,同步 DHCP 进行内省和硬件发现的操作可能需要很长时间,因为操作开销很大。发生的情况是,我们花费大量时间尝试执行更新,导致进程持续繁忙,这可能会产生副作用,例如影响对最近添加到集群的节点的成功内省能力。
为解决此问题,请尝试将 `[pxe_filter]sync_period` 设置得不那么频繁,即一个更大的值,以使 conductor 在运行同步之间有时间。
注意
预计在 2024.1 版本中,Ironic 将通过将 `ironic-inspector` 服务合并到 `ironic` 本身来直接实现此功能。这次合并将实现稍微更高效的实现,这可能需要重新评估和调整 `[pxe_filter]sync_period` 参数。
我的一些或全部裸金属节点消失了!救命?!¶
如果您刚升级,并且发生了这种情况
不要惊慌
不要尝试重新注册节点。它们应该仍然在那里,只是您暂时看不到它们。
在过去的几年里,Ironic 和 OpenStack 项目作为一个整体一直在努力改进基于角色的访问控制模型。对于 Ironic 用户来说,这意味着扩展的角色访问控制模型,允许对节点进行区分,并使项目能够自我管理。
结果是,项目内的用户只能通过 `owner` 和 `lessee` 字段看到裸金属节点,这些节点已被授予项目访问权限。
然而,与任何复杂的努力一样,可能会出现一些小问题,而您就遇到了一个。具体来说,基于大规模操作员的反馈,Ironic 保留了系统范围用户使用的逻辑,而 OpenStack 在很大程度上避免了这种情况,因为担心工作量。
因此,您可以通过几种不同的路径解决此问题,而您的理想路径也将取决于您的使用模式和舒适度。我们建议在采取任何进一步行动之前阅读本回答部分的其余内容。
一个好的起点是获得一个具有 `admin` 或 `member` 角色的`system` 范围的帐户。这两个角色都允许更改节点的 `owner` 或 `lessee` 字段。使用此帐户执行 `baremetal node list` 命令应该会显示所有项目中的所有裸金属节点。或者,如果您只是想暂时启用旧的 RBAC 策略来更改字段,那也是一种选择,尽管不鼓励这样做,并且可以通过使用 `[oslo_policy] enforce_scope` 和 `[oslo_policy] enforce_new_defaults` 设置来实现。
系统范围帐户¶
一个 `system` 范围的帐户是指拥有对整个 OpenStack 部署的访问权限和权限的帐户。一个简化的理解方式是,在部署时,使用用户名和密码来“引导”keystone。授予该用户的权限本质上是系统范围的 `admin` 角色级别的访问权限。您可以使用此级别的访问权限来检查状态或运行其他命令。
在下面的示例中,如果成功,应该会返回 Ironic 已知的ョ所有裸金属节点的列表,一旦执行用户提供了有效的密码。在本例中,“admin”帐户是用 keystone 引导的。需要注意的是,此命令要成功,您的当前命令 shell 中不能加载任何“OS_*”环境变量,包括“OS_CLOUD”。
$ openstack --os-username=admin --os-user-domain-name=default --os-system-scope all baremetal node list
您也可以发出一个系统范围的令牌并使用该令牌重用后续命令,或者甚至生成一个具有 `member` 角色的新系统范围帐户。
更改/分配所有者¶
Ironic 基于项目 ID 进行匹配。owner 字段可以设置为项目 ID 值,这允许裸金属节点可见。
$ PROJECT_ID=$(openstack project show -c id -f value $PROJECT_NAME)
$ baremetal node set --owner $PROJECT_ID $NODE_UUID_OR_NAME
为什么我只看到*部分*节点?¶
在 Ironic 的 Zed 开发周期中,Ironic 添加了一个默认为 True 的选项,该选项允许项目范围的 `admin` 用户创建自己的裸金属节点,而无需更高级别的访问。这个默认启用的选项 `[api] project_admin_can_manage_own_nodes` 会自动将请求者的项目 ID 附加到裸金属节点上,前提是创建时未指定 `owner`。显然,如果操作员以前从未关注过 `owner` 字段,这可能会产生混合的认知。
如果您的裸金属管理流程要求使用项目范围的帐户进行完全的机器管理,请为需要管理的节点配置适当的节点 `owner`。Ironic 认识到这将因流程和偏好而异。
Swift 中的配置驱动器,但重建失败?¶
部署实例时,Ironic 可以配置为将配置驱动器存储在 Swift 中。配置驱动器的指针在 Ironic 中保存为具有过期时间的临时 URL。
当您发出节点的重建请求时,Ironic 期望您会在请求中提供新的配置驱动器内容,但这也是可选的。
由于 Swift 已被设置为可选的配置驱动器存储位置,如果之前的配置驱动器文件不再可访问且未向 Ironic 提供新的配置驱动器,则重建可能会失败。
为了解决此问题,您可以在请求中提供新的配置驱动器内容,或通过更改设置 deploy.configdrive_use_object_store 为 false 来禁用为新的裸金属节点部署将配置存储在 Swift 中。
Ironic 提示我的镜像无效¶
由于 Ironic 中添加的安全修复程序(源于 qemu-img 工具的安全策略),Ironic 会强制执行与镜像文件相关的某些方面。
强制要求磁盘镜像的文件格式与 API 用户告诉 Ironic 的信息匹配。任何不匹配都会导致镜像被声明为无效。文件内容与 Image 服务中存储的内容不匹配将需要上传新镜像,因为此属性在镜像创建后无法在 Image 服务中更改。
强制要求要写入的输入文件格式为
qcow2或raw。可以通过修改ironic.conf中的[conductor]permitted_image_formats来扩展此功能。对文件执行安全和健全性检查评估,可以通过修改
[conductor]disable_deep_image_inspection并将其设置为True来禁用。这样做不被认为是安全的,并且应仅由操作员执行,他们接受使用镜像可能存在损坏或恶意结构的固有风险。镜像安全检查通常在部署过程开始和分阶段构件时执行,但是当 ironic-python-agent 需要时,会执行一个后期检查。
使用 /dev/sda 不会将数据写入第一个磁盘¶
替代名称:我选择了 /dev/sda,但在重启后发现它是 /dev/sdb。
从历史上看,Linux 用户已经习惯了 /dev/sda 是物理机器中第一个设备的上下文。这意味着,如果您查看 by_path 信息、HCTL 或设备 LUN,设备会以零结尾。
例如,假设有 3 个磁盘,两个控制器,第二个控制器上有一个磁盘,看起来会是这样:
/dev/sda 映射到 LUN 为 0、HCTL 为 0:0:0:0 的设备
/dev/sdb 映射到 LUN 为 1、HCTL 为 0:0:1:0 的设备
/dev/sdc 映射到 LUN 为 2、HCTL 为 0:1:0:0 的设备
然而,这是我们习惯的一种模式,因为设备发现的顺序是顺序且同步的。换句话说,内核一次遍历所有可能的设备。当内核在设备初始化是异步的模式下运行时,这种模式会失效,而有些发行版已决定采用这种模式。
异步初始化的结果是 /dev/sda 始终是第一个初始化的设备,而不是系统中的第一个设备。因此,我们可能会得到类似以下的结果:
/dev/sda 映射到 LUN 为 1、HCTL 为 0:0:1:0 的设备
/dev/sdb 映射到 LUN 为 2、HCTL 为 0:1:0:0 的设备
/dev/sdc 映射到 LUN 为 0、HCTL 为 0:0:0:0 的设备
通常,大多数操作员可能会考虑引用 /dev/disk/by-path 结构来匹配磁盘设备,因为这似乎暗示了一个静态顺序,但是,运行异步设备初始化的内核会以相同的方式对所有内容进行排序,包括 PCI 设备,这意味着 by-path 也可能不可靠。此外,如果您的服务器硬件正在使用多路径 IO,您应该启用多路径进行操作,以便使用该设备。
最终结果是,最佳的匹配标准是:
序列号
全球唯一名称 (World Wide Name)
设备 HCTL,在这些情况下似乎是静态的,但对于使用多路径的主机不适用。最终,它可能不够静态,取决于所使用的硬件。