ESXi 6.7虚拟共享磁盘配置与并发写入安全解决方案

📅 2026/8/17 23:32:01
ESXi 6.7虚拟共享磁盘配置与并发写入安全解决方案
1. 项目缘起一个真实的集群部署困境最近在帮一个朋友的公司搭建一套小型的内部测试集群用于模拟高可用HA和负载均衡场景。他们的硬件环境是基于一台老旧的服务器上面跑着 VMware ESXi 6.7计划在上面创建三台 CentOS 7 虚拟机共同挂载一个共享存储用来存放应用日志和需要多节点访问的配置文件。听起来是个很常规的需求对吧我一开始也是这么想的。按照以往在物理服务器上配置 iSCSI 或者 FC SAN 共享盘的经验我直接在 ESXi 的 Web 客户端里给第一台虚拟机添加了一块新的虚拟磁盘然后想着“共享”给其他虚拟机用。结果当我在第二台虚拟机上尝试添加现有磁盘时ESXi 直接弹出了一个警告大意是“此磁盘已被其他虚拟机使用无法添加”。这当头一棒让我意识到在虚拟化环境里特别是 ESXi 这种类型一裸金属的 Hypervisor 上所谓的“虚拟共享磁盘”和物理世界的共享磁盘在配置逻辑上有着根本性的不同。它并不是简单地把一个.vmdk文件同时挂给多台虚拟机就完事了其背后涉及到虚拟机存储栈、SCSI 控制器模拟以及磁盘锁机制等一系列问题。如果配置不当最直接、也是最危险的问题就是数据损坏——多台虚拟机同时写入同一块磁盘的同一区域数据会变成什么样完全无法预料。这个项目标题——“Esxi6.7创建虚拟共享磁盘供多台虚拟机使用以及不能同时写的问题”——精准地戳中了两个核心痛点如何创建以及创建后如何规避并发写入风险。本文将基于我这次的实际踩坑和成功实践拆解从零开始配置 ESXi 6.7 虚拟共享磁盘的完整流程并深入探讨那个关键的“不能同时写”问题背后的技术原理与解决方案。2. 理解虚拟共享磁盘ESXi 与 Workstation 的本质区别在动手之前我们必须先厘清一个关键概念在 VMware 的产品体系中ESXi 和 VMware Workstation/Fusion 对于“共享磁盘”的支持程度和实现方式是截然不同的。如果你用过 VMware Workstation可能会记得它有一个非常直观的“共享”复选框在创建虚拟磁盘时勾选就可以让多台虚拟机同时访问。这是因为 Workstation 作为类型二的 Hypervisor运行在宿主机操作系统之上其设计目标就包括单机多系统协同与测试它通过宿主机的文件系统锁和自身的驱动层实现了一种相对“宽松”的共享机制。然而这种机制并不适用于企业级、追求高稳定性和性能的 ESXi。ESXi 的设计哲学是稳定、安全和隔离。默认情况下一块虚拟磁盘.vmdk文件被一台虚拟机挂载后ESXi 会为其加上一把“锁”防止其他虚拟机访问这是避免数据损坏的基本保障。因此要实现多台虚拟机共享同一块虚拟磁盘你必须明确地告诉 ESXi“我知道风险我就是要共享请为我开启特殊的模式。” 这个“特殊的模式”就是通过配置虚拟机的SCSI 控制器和磁盘的共享策略来实现的。这里引出了两个核心配置点SCSI 控制器类型必须使用LSI Logic SAS或VMware Paravirtual。古老的BusLogic和默认给 Windows 虚拟机用的LSI Logic Parallel是不支持共享磁盘功能的。虚拟磁盘模式必须在创建或编辑磁盘时将其共享属性设置为“多写入器”。只有同时满足这两个条件ESXi 才会允许同一块.vmdk文件被多台虚拟机挂载。但请注意这仅仅是解决了“能挂载”的问题。挂载之后如果多台虚拟机上的操作系统如 Windows 或 Linux在没有协同的情况下直接对磁盘进行文件系统操作那么“不能同时写”导致的数据损坏问题依然存在。这就好比给了几个人同一把仓库钥匙共享挂载但没规定谁在什么时候进去搬什么东西无协调机制混乱和冲突是必然的。所以我们的任务分为两层第一层在 ESXi 层面正确配置打通共享通道第二层在操作系统或应用层面建立写入协调机制防止数据损坏。3. 逐步实操在 ESXi 6.7 上创建并配置虚拟共享磁盘假设我们的 ESXi 主机 IP 是192.168.1.100我们要为三台名为node-01,node-02,node-03的虚拟机创建一个大小为 100GB 的共享磁盘用于后续搭建集群。3.1 第一步创建共享虚拟磁盘由于共享磁盘需要独立于任何虚拟机存在我们首先通过 ESXi 主机或 vCenter 的存储浏览器来创建它。登录并定位存储通过浏览器登录 ESXi 的 Web 客户端 (https://192.168.1.100/ui)。导航到“存储”选项卡选择你要存放共享磁盘的数据存储例如datastore1然后点击“数据存储浏览器”。创建虚拟磁盘在数据存储浏览器中点击“创建目录”新建一个文件夹例如shared_disk以便于管理。进入该文件夹点击“上传”按钮但不要选择文件上传。我们需要的是其下拉菜单中的“创建新文件夹”和“创建新虚拟磁盘”。点击“创建新虚拟磁盘”。在弹出的对话框中名称输入一个有意义的名称如shared_cluster_disk.vmdk。磁盘格式选择“厚置备延迟置零”或“厚置备急切置零”。对于共享磁盘尤其是用于集群的不建议使用“精简置备”以避免性能波动和潜在的空间问题。厚置备能提供更稳定、可预测的性能。容量设置为100GB。最关键的一步在对话框的“共享”下拉菜单中选择“多写入器”。这个选项就是告诉 ESXI允许这块磁盘被多个虚拟机同时挂载并进行写操作尽管协调需要上层解决。点击“创建”。此时一个独立的、具有“多写入器”属性的.vmdk文件就出现在你的数据存储中了。注意有些较旧的 ESXi Web 客户端界面“共享”选项可能在一个“高级选项”或类似按钮下。如果直接创建时没找到也可以先创建普通磁盘然后通过编辑虚拟机设置的方式在添加现有磁盘时再设置“多写入器”属性。但先创建为“多写入器”磁盘是最清晰的做法。3.2 第二步为虚拟机配置支持共享的 SCSI 控制器在将共享磁盘挂载到虚拟机之前必须确保虚拟机的 SCSI 控制器类型是正确的。每台需要访问共享磁盘的虚拟机都必须进行此操作。关闭虚拟机确保目标虚拟机如node-01处于关机状态。ESXi 不允许在虚拟机运行时更改 SCSI 控制器类型。编辑虚拟机设置右键点击node-01- “编辑设置”。添加 SCSI 控制器在“虚拟硬件”选项卡中点击“添加其他设备” - “SCSI 控制器”。新添加的控制器会出现在设备列表中。点击它在右侧详情面板中将“SCSI 控制器类型”更改为“LSI Logic SAS”或“VMware Paravirtual”。我个人更倾向于VMware Paravirtual因为它是 VMware 自家优化的驱动在多数情况下能提供更好的 I/O 性能尤其适合虚拟化环境。LSI Logic SAS 的兼容性更广一些。重要记下这个新控制器的SCSI 总线编号例如SCSI(1:0)。共享磁盘必须挂载在独立的、专用于共享的控制器上绝不能与虚拟机系统盘通常是SCSI(0:0)混用同一个控制器。这是最佳实践也是很多集群软件如 Windows Server Failover Cluster的明确要求。3.3 第三步将共享磁盘挂载到多台虚拟机现在我们将之前创建的共享磁盘逐一挂载到三台虚拟机上。挂载到第一台虚拟机 (node-01)在node-01的“编辑设置”界面点击“添加其他设备” - “现有硬盘”。浏览到我们之前创建的shared_cluster_disk.vmdk文件并选择。添加后该磁盘会出现在设备列表。点击它在右侧进行关键配置SCSI 控制器选择我们刚才新建的那个 SCSI 控制器如SCSI(1:0)。SCSI ID可以设置为0或1等。确保在同一控制器上 ID 唯一即可。虚拟设备节点这里会自动根据控制器和 ID 生成例如SCSI(1:0)。共享确认此处显示为“多写入器”。如果是“无”需要点击下拉菜单手动改为“多写入器”。如果创建磁盘时已设置这里通常会自动识别。点击“保存”。挂载到第二、三台虚拟机 (node-02,node-03)对node-02和node-03重复3.2和3.3.1的步骤。也就是说先为它们各自添加一个类型为VMware Paravirtual的新 SCSI 控制器。然后通过“添加现有硬盘”选择完全相同的shared_cluster_disk.vmdk文件。同样将这块磁盘分配到新加的 SCSI 控制器上并确保其“共享”属性为“多写入器”。至此ESXi 层面的配置就全部完成了。三台虚拟机现在都拥有了对同一块虚拟磁盘文件的访问权限。你可以启动这三台虚拟机。3.4 第四步在虚拟机操作系统中初始化和识别磁盘启动所有虚拟机后我们需要在操作系统内部处理这块新磁盘。识别磁盘以 Linux (CentOS 7) 为例使用lsblk或fdisk -l命令查看新磁盘。你会发现一块新的硬盘设备例如/dev/sdb如果系统盘是/dev/sda的话。分区与格式化这个操作只需要在任意一台虚拟机例如node-01上执行一次sudo fdisk /dev/sdb使用g创建 GPT 分区表然后n创建新分区最后w保存。创建文件系统例如 EXT4sudo mkfs.ext4 /dev/sdb1。警告绝对不要在node-02或node-03上重复分区和格式化操作否则会破坏刚刚在node-01上创建的文件系统导致数据丢失。挂载测试在node-01上可以临时挂载一下检查sudo mount /dev/sdb1 /mnt。创建个测试文件后卸载sudo umount /mnt。现在如果你在node-02和node-03上执行lsblk也能看到/dev/sdb1分区并且file -s /dev/sdb1会显示它是 EXT4 文件系统。但是如果你尝试在node-02上执行mount /dev/sdb1 /mnt系统可能会挂载成功。这正是危险的开始因为现在node-01和node-02都独立地挂载了同一个文件系统它们各自的内核缓存Cache和文件系统元数据如 inode 表、块位图在内存中有一份副本。当两者同时写入时这些缓存无法同步最终写回磁盘时会造成元数据严重破坏文件系统会迅速崩溃数据几乎无法恢复。这就是标题中提到的“不能同时写的问题”在操作系统层面的体现。ESXi 的“多写入器”模式只解决了物理磁盘层面的并发访问许可但并没有提供文件系统级别的锁协调。要安全地“同时写”我们必须引入集群文件系统或分布式锁管理器。4. 解决“不能同时写”集群文件系统与锁机制详解要让多台虚拟机安全地共享一个磁盘并支持并发写入我们必须使用一种能理解“集群”概念的文件系统。这类文件系统内置了分布式锁和心跳机制确保在任一时刻只有一个节点可以对文件系统的某个部分如一个文件或一个元数据块进行修改。4.1 为何普通文件系统EXT4 NTFS不行以 EXT4 为例它设计时假设只有一个系统实例独占访问底层存储设备。它的日志Journal机制、块分配策略、目录项更新等都依赖于单节点内存中的元数据缓存。当两个节点不经过协调直接操作时节点A删除了文件F1在其内存中标记了F1的 inode 为空闲。节点B同时创建了新文件F2可能恰好分配到了F1刚刚释放的 inode 和磁盘块。两个节点的操作异步写回磁盘最终磁盘上的 inode 表和数据块指向会完全混乱文件系统元数据遭到不可逆的破坏。因此绝对禁止在多节点上直接挂载mount同一个 EXT4/NTFS 分区并同时进行读写操作。即使你通过脚本控制“同一时间只有一台机器挂载”在切换时也需要先确保所有节点的缓存都已完全刷新sync并卸载umount这在实际高可用场景中既复杂又不可靠。4.2 解决方案引入集群文件系统我们需要用集群文件系统替换 EXT4。常见的开源选择有GFS2和OCFS2。GFS2 (Global File System 2) 源自红帽通常需要与Red Hat Cluster Suite (RHCS)或Pacemaker/Corosync集群栈配合使用。它依赖一个分布式锁管理器DLM来同步所有节点对文件系统的访问。配置相对复杂但非常成熟稳定适用于需要强一致性的生产环境。OCFS2 (Oracle Cluster File System 2) 由 Oracle 开发并开源。它的设计相对独立可以不需要一个完整的集群管理器自身就包含了节点心跳和锁机制。配置步骤比 GFS2 稍简单一些对于中小型集群是个不错的选择。下面我以在三节点 CentOS 7 集群上配置OCFS2为例演示如何安全地实现共享磁盘的并发读写。4.3 实战配置 OCFS2 集群文件系统前提三台虚拟机 (node-01,node-02,node-03) 已按第三章配置好共享磁盘/dev/sdb1且网络互通建议配置主机名解析如/etc/hosts。步骤1在所有节点安装 OCFS2 工具包sudo yum install -y ocfs2-tools步骤2配置 OCFS2 集群栈OCFS2 需要一个集群配置文件来定义节点成员。在所有节点上创建并编辑相同的配置文件/etc/ocfs2/cluster.confsudo tee /etc/ocfs2/cluster.conf EOF cluster: node_count 3 name my_shared_cluster node: ip_port 7777 ip_address 192.168.1.101 number 0 name node-01 cluster my_shared_cluster node: ip_port 7777 ip_address 192.168.1.102 number 1 name node-02 cluster my_shared_cluster node: ip_port 7777 ip_address 192.168.1.103 number 2 name node-03 cluster my_shared_cluster EOF请将ip_address替换为各节点的实际 IP。node_count和number要对应。步骤3启动 OCFS2 集群服务# 在所有节点上执行 sudo systemctl start o2cb sudo systemctl enable o2cb # 将集群配置加载到内核模块 sudo /etc/init.d/o2cb configure # 在交互提示中依次输入 # Cluster stack backing O2CB [default]: o2cb # Cluster to start on boot (none, \my_shared_cluster\) [none]: my_shared_cluster # 回答 yes 以在引导时启动 # 在线注册集群 sudo /sbin/o2cb register-cluster my_shared_cluster步骤4格式化共享磁盘为 OCFS2仅在一个节点如 node-01上执行# 先确保集群服务在线 sudo /sbin/o2cb online my_shared_cluster # 格式化 /dev/sdb1 分区为 OCFS2 # -L 指定卷标-N 指定最大节点数实际节点数-T 指定文件系统类型此处为datafiles适用于通用文件 sudo mkfs.ocfs2 -L \shared_volume\ -N 4 -T datafiles /dev/sdb1步骤5在所有节点上挂载 OCFS2 文件系统首先在所有节点上创建挂载点sudo mkdir /shared_data然后在所有节点上挂载# 先确保集群在线 sudo /sbin/o2cb online my_shared_cluster # 挂载文件系统 sudo mount -t ocfs2 /dev/sdb1 /shared_data为了开机自动挂载在所有节点的/etc/fstab中添加/dev/sdb1 /shared_data ocfs2 _netdev,noatime,nodiratime 0 0_netdev选项很重要它告诉系统这是一个网络设备尽管是块设备但依赖网络心跳等网络就绪后再挂载。现在你可以在node-01的/shared_data下创建一个文件然后在node-02和node-03上立即就能看到。你可以尝试从不同节点同时读写不同文件甚至谨慎地测试同时读写同一文件的不同位置OCFS2 支持字节范围锁。OCFS2 的锁管理器会协调这些操作确保数据一致性。5. 避坑指南与进阶思考在整个配置过程中我遇到了不少坑这里总结一下希望能帮你节省时间SCSI 控制器混用导致无法识别最初我图省事想把共享磁盘挂在系统盘所在的默认LSI Logic Parallel控制器上结果其他虚拟机根本无法添加该磁盘ESXi 报错。牢记必须使用独立的、支持共享的控制器类型SAS 或 Paravirtual。未设置“多写入器”属性在某一台虚拟机上添加磁盘时忘了在磁盘属性里将“共享”从“无”改成“多写入器”。虽然这台虚拟机自己能挂载但其他虚拟机在添加该磁盘时ESXi 会提示设备忙或不被支持。每台虚拟机上的这块磁盘设备都必须显式设置为“多写入器”。所有节点未使用相同的 SCSI ID这不是强制要求但强烈建议在所有虚拟机上将共享磁盘分配到相同控制器类型如都是VMware Paravirtual的相同 SCSI ID 上例如都是SCSI(1:0)。这能保证在所有节点操作系统中磁盘设备名如/dev/sdb保持一致极大简化后续脚本和配置的复杂度。OCFS2 心跳网络问题OCFS2 节点间通过 TCP/IP 心跳判断对方是否存活。如果网络延迟大或不稳定可能导致节点被错误驱逐引发文件系统只读或挂载点卡住。建议为集群心跳使用独立的、可靠的网络如万兆或专用 VLAN并在cluster.conf中配置该网络的 IP。资源预留在虚拟化环境中如果共享磁盘所在的存储性能不足如 IOPS 低、延迟高当多个节点并发访问时性能会急剧下降甚至影响心跳导致集群分裂。务必为运行集群的虚拟机预留足够的 CPU、内存并确保共享磁盘位于高性能存储如 SSD 存储上。备份与快照对配置了共享磁盘的虚拟机进行快照要极其小心。vSphere 的快照功能在涉及共享磁盘时行为复杂可能无法保证集群的一致性。最佳实践是在拍摄快照前先在所有集群节点上卸载 (umount) OCFS2 文件系统并停止 (offline) OCFS2 集群服务。对于生产环境应考虑使用支持应用一致性的第三方备份工具。回到标题中的问题“不能同时写”我们现在可以给出完整的答案在 ESXi 6.7 上通过配置支持“多写入器”的虚拟磁盘和正确的 SCSI 控制器可以解决虚拟机层面的磁盘共享挂载问题。而要解决操作系统层面的并发写入冲突防止数据损坏则必须依赖集群文件系统如 OCFS2、GFS2或运行在其上的集群软件如 Windows Server Failover Cluster所提供的分布式锁机制。这两者结合才能实现真正安全、可用的多虚拟机共享存储方案。