ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

ESXi命令行创建RDM直通磁盘:vmkfstools配置与实战指南

ESXi命令行创建RDM直通磁盘:vmkfstools配置与实战指南

某个周末,数据库同事说应用需要直接访问存储上的一个LUN,要求把磁盘原原本本交给虚拟机,不能套VMFS虚拟磁盘。当时vCenter Web Client刚好处于登录异常状态,我直接SSH上ESXi主机,用vmkfstools把RDM磁盘建了出来。ESXi命令行创建并直通RDM磁盘这件事,听起来有点冷门,其实操作量很小,核心就是vmkfstools一条命令加vmx几行配置。这篇文章把整套流程、两个兼容模式的区别、以及后来踩过的坑完整记录下来,给要接裸盘、共享盘、RAC或Windows故障转移集群的朋友做个参考。

1. 为什么要绕过VMFS直接给虚拟机挂RDM盘

1.1 虚拟磁盘、RDM、PCI直通三者的边界

很多刚接触的人会把RDM和PCI直通混为一谈。先把这个边界理清楚:普通虚拟磁盘是ESXi在VMFS上创建的一个vmdk文件,文件系统负责分配空间,虚拟机看到的其实是一个模拟出来的SCSI盘。RDM则是ESXi在VMFS上创建一个很小的描述文件,这个文件里没有真实数据,只写了一个指针指向底层的物理LUN,比如/vmfs/devices/disks/naa.xxx。真正IO发生时,虚拟机的数据直接读写那个LUN,不再经过VMFS文件层的复制。

而PCI直通是完全另一条路,它把物理HBA卡或NVMe控制器直接分配给虚拟机,虚拟机里能看到硬件卡本身。RDM不是这种级别,它只是SCSI层上的映射,虚拟机的驱动层面看到的依然是一个磁盘,只是磁盘数据落点不是文件而是一个设备。这个区别决定了RDM既保留了一部分虚拟化灵活性,又能满足业务对裸设备才能用的诉求。

还有一个容易被忽略的点:RDM的描述文件虽然小,但它依赖ESXi主机对底层设备的识别能力。也就是说,设备必须能被ESXi正确枚举并纳入/vmfs/devices/disks/目录体系,RDM才有意义。直连存储、SAN存储、vSAN上暴露出来的设备,只要ESXi能看到,理论上都能做RDM映射。

1.2 RDM适合的场景和坚决不用的场景

先说什么时候必须用RDM。第一类是数据库场景,比如Oracle RAC用ASM裸盘,安装程序会检查磁盘的SCSI语义,普通虚拟磁盘在某些版本上会出现检测警告,RDM可以规避这类问题。第二类是Windows故障转移集群,集群仲裁盘和共享盘要求多个节点访问同一个LUN,RDM是最直接的方案。第三类是利用存储阵列快照或复制能力,阵列只能在LUN级别做快照,如果数据被封装在vmdk里,阵列看不到独立的LUN边界,快照粒度就不对。如果你需要的是这些能力,RDM是唯一兼顾“VM能独立运行”和“LUN语义保持”的路径。

但反过来说,如果只是给应用加一块普通数据盘,RDM往往不是最优解。VMFS虚拟磁盘支持精简置备、快照、克隆、Storage vMotion,运维成本低很多。RDM会引入额外的路径依赖,物理盘换掉、映射文件损坏都会变成事故。尤其在没有共享存储的单主机上,RDM带来的东西很有限,遇到主机硬件故障时迁移也麻烦。我见过有团队把MySQL数据盘做成RDM,后来仅仅因为HBA卡更换,设备路径变了,虚拟机起不来,排查一晚上。所以我的原则是:没有明确技术驱动力时,不要为了“绕开VMFS”而用RDM。

2. 动手前的存储盘摸底:SSH、设备标识与分区检查

2.1 打开SSH并确认RDM文件只能落在VMFS

命令行创建RDM,第一步是拿到ESXi的Shell。单机环境建议在Host Client里找到服务管理,把SSH服务临时启动,用完记得关掉。也可以通过DCUI按F2进入系统自定义,在故障排除选项里打开SSH。连接时用root账号,操作全程都在VMkernel的Shell里进行。

这里有个硬性前提:RDM映射文件必须创建在VMFS数据存储上,NFS数据存储不支持。原因很简单,vmkfstools在创建RDM时要把描述文件写入一个VMFS卷,如果目标路径落在NFS、本地闪存或USB启动盘上,命令会直接报错。我习惯先执行df -h /vmfs/volumes/确认一下可用的数据存储挂载点,想清楚把映射文件放在哪个虚拟机的目录下。如果这台虚拟机使用的是某个数据存储,那RDM描述文件也放在同一个数据存储的虚拟机目录里,后续迁移和查找都方便。

2.2 从esxcli输出中读取NAA、型号与容量

SSH登录后,第一件事不是急着执行vmkfstools,而是把主机上的裸设备列表看清楚。最常用的命令是:

esxcli storage core device list

输出很长,每块设备会带一个形如naa.6005076803950ff3a000000000000000的标识,这是设备的NAA,也是后面RDM映射文件里真正引用的路径。除了NAA,列表里还能看到Device Type、Size、Model这些信息,通过容量和型号可以确认自己盯上的是哪块盘。另一种快速看路径的方式是:

ls -l /vmfs/devices/disks/

这个目录下会列出naa.*、t10.*、vml.*这些设备名。其中naa开头的名称最稳定,因为它直接对应SCSI设备的世界统一名称;t10和vml则和某个主机/控制器实例绑定,硬件变更后容易变。所以我在创建RDM时,只用NAA路径。

如果主机连接的是SAN存储,同一个LUN在主机上可能有多个路径,esxcli storage core path list能看到对应关系,不过这不影响RDM创建,ESXi已经通过多路径机制把同一设备折叠成一个逻辑设备了。

2.3 分区表检查和设备占用确认

在把一个裸设备映射给虚拟机之前,必须确认两点:设备上没有VMFS文件系统,设备没有被datastore占用。如果设备已经被VMFS格式化,你又强行把它做成RDM,等于同一块盘同时被两个存储管理层访问,数据损坏概率极高。

检查分区表用:

partedUtil get /vmfs/devices/disks/naa.xxx

如果输出里只有少量分区信息,说明设备已经有分区;如果基本是空输出,说明整盘还没划分,可以直接整盘映射。再跑一下:

esxcli storage core device partition list

确认设备没有处于VMFS卷的使用状态。这里要特别提醒,直通LUN和创建RDM前,最好再确认一下后端存储上这个LUN是不是已经被别的系统占用。多路径环境下ESXi能看到的设备,在存储阵列上可能同时被交换机共享给其他主机,这种事情不会在ESXi命令里体现,只能靠存储层面的规划文档去确认。

3. vmkfstools是核心:创建RDM映射文件的两个模式

3.1 -z和-r:物理兼容与虚拟兼容怎么选

vmkfstools创建RDM时有两个模式,分别对应物理兼容和虚拟兼容,命令参数是-z和-r。这是整个操作里最需要理解的地方,选错模式后面会有一堆限制。

对比项物理兼容PCM(-z)虚拟兼容VCM(-r)
命令参数vmkfstools -zvmkfstools -r
SCSI命令直接透传给阵列,LUN特性完全保留通过虚拟SCSI层转换,部分LUN语义丢失
ESXi快照不支持,vSphere界面里快照按钮置灰支持虚拟机快照
Storage vMotion不支持支持
典型场景数据库ASM、共享集群、阵列快照普通盘透传但希望保留迁移灵活性

我的经验是:除非业务明确依赖LUN级SCSI特性,否则优先选虚拟兼容模式-r。很多人一听到“物理兼容”就以为性能更好,其实并不全是这样。物理兼容最大价值是SCSI语义完整,比如集群软件需要SCSI-3 Persistent Reservation做锁,这时候必须用物理兼容,虚拟兼容会在SCSI层过滤掉部分命令。如果你只需要把一块存储盘当作大容量数据盘,虚拟兼容模式完全够用,而且后面热迁移、打快照都不受限。

3.2 创建命令的写法、顺序和查看映射文件内容

命令的基本格式是:

vmkfstools -z /vmfs/devices/disks/naa.xxx /vmfs/volumes/datastore1/vm01/vm01-rdm.vmdk

两个参数顺序不能反:第一个是源设备路径,第二个是目标RDM描述文件路径。目标文件的后缀必须是.vmdk,但请记住它只是一个几KB到几十KB的描述文件,不是真正的数据盘。创建前目标目录必须已经存在,如果虚拟机目录还不存在,先mkdir建好。以下面这套为例,设备是naa.6000...,虚拟机叫vm01,数据存储是datastore1:

vmkfstools -z /vmfs/devices/disks/naa.6005076803950ff3a000000000000000 /vmfs/volumes/datastore1/vm01/vm01-rdm.vmdk

创建后先看文件大小和内容:

ls -l /vmfs/volumes/datastore1/vm01/vm01-rdm.vmdk cat /vmfs/volumes/datastore1/vm01/vm01-rdm.vmdk

cat输出里能看到createType和类似RW xxx vmfsPassthroughRawDeviceMap "naa.xxx"的描述行。如果创建的是虚拟兼容模式,对应的描述类型会是vmfsRawDeviceMap。看到这两类标识就说明映射建立成功了,底层数据没有发生任何复制,LUN还是原来的LUN。

3.3 创建时容易遇到的报错

vmkfstools失败时通常不会废话,直接给一行错误,但常见报错基本都能对应到特定问题。

出现Failed to open device: Not found,大概率是设备路径写错了,回到ls /vmfs/devices/disks/对着名字抄一遍。出现The device is in use或者类似占用提示,说明设备被VMFS或其他功能占用了,需要先解除占用。出现Invalid argument,先检查目标目录是否存在,目标路径的父目录没建好是高频原因。还有一种是目标vmdk文件已经存在,vmkfstools不会覆盖它,必须先删掉旧映射文件。

我遇到过最隐蔽的问题是把设备路径写成了/vmfs/devices/disks/vml.xxx,而实际上某个存储迁移后该路径已经指向了别的设备。排查方式就是cat一下映射文件,再比对esxcli storage core device list里的NAA,确认映射关系没有漂移。

4. 把RDM挂给虚拟机:改vmx配置比界面更可控

4.1 查询虚拟机ID并安全关机

映射文件创建好之后,还要让虚拟机“接住”它。界面操作当然可以,在Web Client里编辑虚拟机设置,添加硬盘时选择已有vmdk文件即可。但如果vCenter不可用,或者你想做成脚本化操作,就必须直接改vmx。

先查虚拟机ID:

vim-cmd vmsvc/getallvms

输出里第二列就是VM ID,假设是42。如果虚拟机正在运行,建议先关机:

vim-cmd vmsvc/power.off 42

改vmx前一定先备份:

cp /vmfs/volumes/datastore1/vm01/vm01.vmx /tmp/vm01.vmx.bak

这一步别省。我见过有人改完vmx后虚拟机无法注册,最后就是靠备份文件恢复的。既然是命令行场景,备份成本又低,顺手做掉。

4.2 手动编写SCSI控制器与RDM设备行

编辑vmx文件,比如用vi打开:

vi /vmfs/volumes/datastore1/vm01/vm01.vmx

先看现有配置里用了哪个SCSI控制器编号。大部分虚拟机默认用scsi0,那RDM就放在scsi1上,避免冲突。在文件末尾追加这样几行:

scsi1.present = "TRUE" scsi1.virtualDev = "lsilogicsas" scsi1.sharedBus = "none" scsi1:0.present = "TRUE" scsi1:0.deviceType = "scsi-passthru" scsi1:0.fileName = "/vmfs/volumes/datastore1/vm01/vm01-rdm.vmdk" scsi1:0.mode = "independent-persistent"

需要解释几个关键项。scsi1.present把新控制器启用,controllerType用lsilogicsas是LSI Logic SAS控制器,我习惯让RDM挂在LSI SAS控制器上,和PVSCSI比起来少些兼容性问题。deviceType = scsi-passthru是物理兼容RDM的标志,如果创建的是虚拟兼容RDM,这里写scsi-block。mode = independent-persistent在共享RDM场景里经常用,它告诉ESXi这块盘不走普通快照链,也不参与虚拟机快照语义。

如果多台虚拟机要共享同一个RDM盘,比如Windows故障转移集群的共享卷,还要把sharedBus改成virtual:

scsi1.sharedBus = "virtual" scsi1:0.mode = "independent-persistent"

这个配置不能靠猜,共享RDM如果不能被多个节点同时访问,集群软件会直接报锁冲突。

4.3 reload、开机与虚拟机内验证

vmx改完后要让虚拟机重新读取配置:

vim-cmd vmsvc/reload 42 vim-cmd vmsvc/power.on 42

开机后先进虚拟机内部确认盘是否出现。Linux用lsblk或fdisk -l,Windows打开磁盘管理看有没有符合条件的磁盘。如果看到一块处于“未初始化”状态的盘,不要慌,这是因为RDM透传的是整块LUN,LUN上可能没有分区信息或者分区表不是虚拟机期望的类型。只有确认这个盘是空盘或已知的数据盘后才能做相应处理,千万别顺手格式化。

我遇到的另一个问题是虚拟机里根本看不到盘。这时先检查vmx里的fileName路径是否写对,再确认控制器编号没有和已有控制器冲突。如果都正常,尝试把scsi1.virtualDev从lsilogicsas换成lsilogic或默认控制器类型再试。有些老虚拟机模板对LSI SAS控制器的支持不完整,换成LSI Parallel反而能识别。

5. 真正实战后才会懂的坑与维护细节

5.1 路径变更与映射文件失效的修复思路

RDM映射文件里写的是设备路径,而不是某种“永久句柄”。虽然NAA相对稳定,但宿主机硬件更换、存储控制器故障、LUN重新拷贝,都可能导致旧路径失效。映射文件失效的典型表现是虚拟机开机时报错:找不到虚拟磁盘,或者虚拟磁盘状态异常。

修复思路不复杂:先看esxcli storage core device list里设备是否还在,如果还在但名称变了,就用新设备路径重新创建一次RDM映射文件,然后修改vmx里的fileName字段指向新文件。如果设备彻底不在了,说明底层LUN掉线,那就不是改配置能解决的问题,要先把存储链路恢复。

我个人的习惯是,每次做完RDM后把/vmfs/devices/disks/下的设备名和映射文件内容保存一份文本记录,放到虚拟机目录里。这个动作看起来多此一举,但排障时不用满世界翻记录,省下大量时间。

5.2 物理兼容RDM的快照、vMotion与克隆限制

物理兼容RDM的限制一定要提前讲清楚。第一,vSphere界面里的快照按钮会变灰,因为SCSI命令已经透传到阵列,ESXi无法捕获一个“完整磁盘状态”。第二,Storage vMotion对物理兼容RDM基本不可用,遇到存储迁移只能先卸载RDM或者转成虚拟磁盘。第三,模板克隆时如果虚拟机里挂了物理兼容RDM,克隆出的虚拟机通常不会带着真正的LUN数据,它可能生成一个普通虚拟磁盘,数据完全对不上。

所以生产环境如果用了物理兼容RDM,变更流程里要专门评估这些限制。早期我有一个教训:某测试环境做了物理兼容RDM,后来想把虚拟机整体迁移到另一台存储,结果发现物理兼容盘动不了,最后只能先在虚拟机层面分离数据盘,迁移完成后再重新映射,步骤繁琐但安全。

虚拟兼容RDM虽然支持快照和Storage vMotion,但它本质上已经经过了虚拟SCSI封装,底层LUN的一些高级特性不再透传。如果你的业务目标就是“保留LUN语义”,那虚拟兼容反而不满足需求。选哪个模式,本质是一道业务需求题。

5.3 删除RDM时别把底层盘一起删了

RDM描述文件和数据盘是两层东西,删除时必须清醒。先移除虚拟机里的RDM设备,界面上点击Remove,这个动作只断开映射,描述文件还留在datastore里。然后再手动删除描述文件:

rm /vmfs/volumes/datastore1/vm01/vm01-rdm.vmdk

这条命令删除的只是映射文件,底层LUN上的数据不会被删除,因为数据从始至终都不在VMFS上。反过来,如果你想彻底销毁这块LUN上的数据,必须到存储端去操纵LUN,删除RDM描述文件不会帮你释放底层空间。

这里要特别注意:千万不要对/vmfs/devices/disks/下的设备文件执行删除或格式化操作。那些设备文件是ESXi内核设备节点的映射,误删可能直接把物理设备搞坏。维护RDM时只操作虚拟机目录里的vmdk描述文件,这是个底线。

5.4 共享RDM、多路径与性能的补充说明

共享RDM是另一个高频场景。多台虚拟机访问同一个LUN时,必须保证底层是共享存储,并且vmx里有正确的共享SCSI配置。RDM本身不会自动加锁,锁机制完全依赖虚拟机里跑的应用,比如Windows集群的Persistent Reservation或数据库集群的分布式锁。如果没有这些锁机制,多台虚拟机同时写同一块裸盘,数据损坏只是时间问题。

多路径方面也要纠正一个误解:RDM给虚拟机看到的是单个SCSI设备路径,ESXi层面的多路径MPIO对客户机是不可见的。虚拟机内部的软件无法感知底层HBA卡的多个物理链路,如果业务需要在客户机内看到多个路径,那得走PCI直通而不是RDM。这两者的适用范围完全不同。

性能上,RDM和VMFS虚拟磁盘在绝大多数工作负载下差距并不明显,尤其是全闪存储时代,文件层损耗非常小。RDM的优势始终是“语义透传”和“LUN粒度管理”,而不是“更快”。遇到数据库性能瓶颈,优先看队列深度、缓存策略和应用IO模式,别把锅甩给虚拟磁盘格式。

我每次做RDM维护时,都会先把/vmfs/devices/disks/下的设备名和映射文件内容备份一份,这个习惯帮我解决了不少线上问题。如果你正准备用命令行给ESXi接RDM盘,照着上面流程操作,基本不会跑偏。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进