香港服务器如何实现跨系统共享存储(Windows NTFS 与 Linux ext4),解决文件兼容问题?

半夜两点,荃湾机房的空调吹得我直打哆嗦。Windows 团队的同事在一旁抱怨:“渲染素材在 Linux 上生成,拷到我们的 NTFS 共享就各种权限报错。”Linux 同学回怼:“你们的 SMB 盘中文名一多,就开始乱码,Git 还动不动全量改动。”这套香港站点原本只想做个两端兼容的共享目录,结果变成了跨系统拉扯的事故现场。那一夜,我把咖啡换成了热美式,给自己下了个死命令——把 Linux 的 ext4 和 Windows 的 NTFS 拉到一条线上,让同一份数据既能被 Windows 流畅编辑,也能被 Linux 稳定读写,并且权限、字符集、锁机制都说得过去。
下面这篇,就是我那次“救火”的实操复盘:既保留了机房里的真问题与真坑,又把方案做成了能落地、能复用的标准化手册。
一、现场背景与目标
业务画像:
Linux(CentOS 7.9)端跑编译、视频转码、模型训练,产出大量中小文件 + 若干大文件(GB~TB)。
Windows(Server 2019/2022)端跑剪辑、DCC 工具、Office/PS 等,需要对同一数据目录进行协作。
站点间通过专线回内地,站内为万兆平面网络(10GbE),核心交换机做 LACP 汇聚。
目标:
用统一的共享目录承载两端协作;
避免文件名乱码、权限错乱、锁冲突、时间戳异常引发的误改动;
性能可跑满万兆,稳定可用,最好能做高可用。
二、三种架构路线对比(为什么我最终选 A + HA)
| 方案 | 核心思路 | 优点 | 风险/限制 | 适用场景 |
|---|---|---|---|---|
| A. Linux 为中心(ext4 存本地/集群,Samba 向 Windows 提供 SMB,Linux 端本地/NFS 访问) | 数据以 ext4 为主,Samba 做 Windows 门面,Linux 原生/或 NFS | 权限语义贴近 POSIX,性能稳定,易做 HA | Samba 配置需要打磨 ACL/编码/锁;NFS 与 SMB 并发要规范 | 以 Linux 工具链为主、Windows 偶尔/同频协作 |
| B. Windows 为中心(NTFS 存本地,SMB 原生提供,Linux 通过 CIFS 挂载) | 数据以 NTFS 为主,Linux 以 cifs 访问 | 对 Windows 应用最友好,SMB 原生 | Linux 端权限/符号链接/保留字符受限、元数据语义差异 | Windows 工具链为主,Linux 辅助 |
| C. 统一分布式(CephFS/GlusterFS)+ SMB 网关 | 背后是统一文件系统,Linux 原生挂载,Windows 通过 Samba 网关 | 统一命名空间,规模化/HA 方便 | 架构/运维复杂度高,需要额外资源和经验 | 数据规模大、需要水平扩展与多站点复制 |
我的选择:先落地 A 方案(Linux 为中心)作为标准形态,再在两台 Linux 存储节点上做 DRBD + Pacemaker 的 HA;对强 Windows 场景,补一份 B 方案的配置基线,做到两套都能跑、按业务切换。
三、现场硬件与系统基线
| 角色 | 型号/CPU | 内存 | 存储 | 网卡 | 系统 |
|---|---|---|---|---|---|
| 存储节点 x2 | 2×Xeon Gold 6226R | 256 GB | 4× NVMe U.2 3.84TB(RAID10)+ LVM + ext4 | 2×10GbE(LACP) | CentOS 7.9(内核 3.10) |
| Windows 客户端 | 任意工作站 | 64~128 GB | 本地 SSD | 1×1/10GbE | Windows 10/11 / Server 2019/2022 |
| Linux 客户端 | 任意计算节点 | 64~256 GB | 本地 SSD | 1×10GbE | CentOS 7/AlmaLinux 8/Ubuntu LTS |
说明:CentOS 7 是历史包袱,但现场就这样;文内已给出对 cifs-utils 版本和 SMB 方言的规避。
四、实施路线 A(推荐):Linux 为中心(ext4)→ Windows 访问
1)磁盘与文件系统(ext4)初始化
# 组 RAID(示例用 mdadm,或用硬 RAID)
mdadm --create /dev/md0 --level=10 --raid-devices=4 /dev/nvme{0..3}n1
mkfs.ext4 -L data_raid10 /dev/md0
# LVM(可选)
pvcreate /dev/md0
vgcreate vg_data /dev/md0
lvcreate -n lv_share -L 6.5T vg_data
mkfs.ext4 -m 0 -O dir_index,extent,uninit_bg /dev/vg_data/lv_share
# 挂载并启用 ACL/xattr(很关键)
mkdir -p /data/share
echo '/dev/vg_data/lv_share /data/share ext4 defaults,noatime,acl,user_xattr 0 2' >> /etc/fstab
mount -a
# 验证
tune2fs -l /dev/vg_data/lv_share | egrep 'Filesystem features|Block size'
要点:开启 acl,user_xattr,为 Samba 的 NTFS ACL 映射与扩展属性打好地基。
2)Samba 安装与核心配置
yum install -y samba samba-client samba-common policycoreutils-python
groupadd share && useradd -g share shareop
passwd shareop
(echo 'StrongP@ssw0rd'; echo 'StrongP@ssw0rd') | smbpasswd -a shareop
/etc/samba/smb.conf(核心片段)
[global]
workgroup = WORKGROUP
server string = hk-smb1
security = user
map to guest = Bad User
# 协议与性能
server min protocol = SMB2_10
server max protocol = SMB3
aio read size = 1
aio write size = 1
use sendfile = yes
strict locking = yes
# 多通道新版本才稳,CentOS7自带Samba较老,建议不开
# server multi channel support = yes
# 字符集与文件名
unix charset = UTF-8
dos charset = CP936
# 尽量避免短名混淆
mangled names = no
case sensitive = auto
# ACL 与扩展属性(关键)
vfs objects = acl_xattr recycle full_audit
map acl inherit = Yes
store dos attributes = Yes
ea support = Yes
# 回收站(可选)
recycle:repository = .recycle
recycle:keeptree = yes
recycle:versions = yes
recycle:touch = yes
# 审计(现场排错很有用)
full_audit:prefix = %u|%I|%S
full_audit:success = open,close,mkdir,rmdir,rename,unlink
full_audit:failure = none
full_audit:facility = LOCAL7
full_audit:priority = NOTICE
[projects]
path = /data/share/projects
browsable = yes
writable = yes
valid users = @share, shareop
force group = share
create mask = 0664
directory mask = 0775
inherit permissions = yes
mkdir -p /data/share/projects
chgrp -R share /data/share
chmod -R 2775 /data/share
# SELinux 与防火墙
semanage fcontext -a -t samba_share_t "/data/share(/.*)?"
restorecon -Rv /data/share
setsebool -P samba_export_all_rw on
firewall-cmd --permanent --add-service=samba
firewall-cmd --reload
systemctl enable smb nmb --now
testparm
关键解释
- vfs objects = acl_xattr:把 NTFS ACL 映射到 xattr,Windows 看着“像 NTFS”。
- map acl inherit:保证目录继承行为更接近 Windows 预期。
- unix charset=UTF-8 + dos charset=CP936:对简体中文场景稳妥,现代 SMB 走 Unicode,但这组配置能兜住边角。
- SELinux 打标、开放 samba 布尔值是 CentOS 7 的必修课,否则会莫名其妙 “Permission denied”。
3)Windows 侧挂载与验证
PowerShell(以域外本地用户为例)
$User="shareop"
$Pwd=ConvertTo-SecureString "StrongP@ssw0rd" -AsPlainText -Force
$Cred=New-Object System.Management.Automation.PSCredential($User,$Pwd)
New-PSDrive -Name "P" -PSProvider FileSystem -Root "\\10.10.10.11\projects" -Credential $Cred -Persist
# 或者老派命令:
# net use P: \\10.10.10.11\projects /user:shareop StrongP@ssw0rd /persistent:yes
验证点
中文/空格/长路径文件名创建 → Linux 端 ls 正常、smbstatus 可见句柄。
Windows 修改权限 → Linux 端 getfacl 能看到 ACL 变化(写在 xattr)。
大文件写入(>10GB)→ 速率接近万兆(见“性能”章节)。
4)Linux 客户端访问的两种姿势
- 姿势 1(推荐):Linux 客户端直接用 NFS 连同一台存储(不与 Windows 抢 SMB 语义)。
- 姿势 2:Linux 客户端也走 SMB(cifs) 访问,方便统一审计,但丢失一部分 POSIX 语义(符号链接/权限映射折衷)。
NFS 导出(同机开 NFS 注意权限一致)
yum install -y nfs-utils
echo "/data/share/projects 10.10.10.0/24(rw,sync,fsid=100,no_root_squash,sec=sys)" >> /etc/exports
systemctl enable nfs-server --now
exportfs -rav
Linux 端挂载(cifs 方案示例)
yum install -y cifs-utils
mkdir -p /mnt/projects
cat >/root/.smbcred <<EOF
username=shareop
password=StrongP@ssw0rd
domain=WORKGROUP
EOF
chmod 600 /root/.smbcred
echo "//10.10.10.11/projects /mnt/projects cifs credentials=/root/.smbcred,iocharset=utf8,vers=3.0,sec=ntlmssp,uid=1000,gid=1000,file_mode=0664,dir_mode=0775,cache=strict,actimeo=1,mfsymlinks 0 0" >> /etc/fstab
mount -a
坑位预告:CentOS 7 的 cifs-utils 默认可能去尝试 SMB1,务必显式 vers=3.0 或 3.1.1;mfsymlinks 能让 Linux 端在 SMB 上“模拟”符号链接(实为 xattr),千万别拿它做深度依赖。
五、实施路线 B:Windows 为中心(NTFS)→ Linux 访问
这一套我在以剪辑工具为主的项目里也落过地。
Windows 侧(PowerShell)
# 格式化数据盘为 NTFS(GUI 亦可)
Initialize-Disk -Number 2 -PartitionStyle GPT
New-Partition -DiskNumber 2 -UseMaximumSize -AssignDriveLetter | Format-Volume -FileSystem NTFS -NewFileSystemLabel "Data"
# 建共享与权限
New-Item -ItemType Directory -Path "D:\Projects"
icacls D:\Projects /inheritance:e
icacls D:\Projects /grant "Users:(OI)(CI)(M)" "Administrators:(OI)(CI)(F)"
New-SmbShare -Name projects -Path "D:\Projects" -FullAccess "Administrators" -ChangeAccess "Users"
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Confirm:$false
Linux 侧(cifs)
yum install -y cifs-utils
mkdir -p /mnt/projects
cat >/root/.wcred <<EOF
username=winshare
password=Str0ng!
domain=WORKGROUP
EOF
chmod 600 /root/.wcred
echo "//10.10.10.21/projects /mnt/projects cifs credentials=/root/.wcred,vers=3.1.1,sec=ntlmssp,iocharset=utf8,uid=1000,gid=1000,file_mode=0664,dir_mode=0775,cache=strict,actimeo=1,noserverino,mfsymlinks 0 0" >> /etc/fstab
mount -a
要点:
- noserverino 可避开部分 inode 映射问题(避免工具误判“文件全变了”)。
- NTFS 不接受 : * ? < > | 等字符,Linux 要教育使用者或在入口做校验。
- Linux 侧尽量别对 SMB 目录滥用 POSIX 特性(硬链接、复杂 ACL 组合),否则容易踩语义坑。
六、权限与字符集的统一策略(踩坑最多的部分)
字符集:unix charset=UTF-8、Windows 走 Unicode,Linux 端 iocharset=utf8。老历史文件若是 GBK 编码命名,需批量改名/转码脚本一次性处理。
权限:
Linux 侧用 acl_xattr,Windows 改权限会落在 xattr 上;
目录 chmod 2775 + force group=share,避免混乱;
inherit permissions = yes 是我在线上稳住默认权限传播的关键。
锁与并发:
开 strict locking = yes;对同一目录既走 NFS 又走 SMB 的情况,明确不允许不同协议对同一批文件并发改写;
CI/CD 工具只在一端写,另一端读,减少冲突。
时间戳细节:SMB 层的时间粒度与本地 ext4/NTFS 仍可能有细微差异,配合 git config core.autocrlf=false、git config core.filemode=false,避免“全量改动”。
七、表格:关键配置参数与我的现场默认值
Samba 参数速查
| 参数 | 值 | 作用/备注 |
|---|---|---|
| server min/max protocol | SMB2_10 / SMB3 | 禁 SMB1,稳妥兼容 |
| unix/dos charset | UTF-8 / CP936 | 中文场景兜底 |
| vfs objects | acl_xattr recycle full_audit | ACL 映射、回收、审计 |
| map acl inherit | Yes | 继承更像 Windows |
| store dos attributes | Yes | 保留 DOS 属性 |
| strict locking | Yes | 跨端并发更稳 |
| mangled names | No | 避免短名混淆 |
cifs 挂载常用选项
| 选项 | 值 | 说明 |
|---|---|---|
| vers | 3.0/3.1.1 | 指定 SMB 方言 |
| sec | ntlmssp/krb5 | 认证方式 |
| iocharset | utf8 | 字符集 |
| uid/gid | 1000/1000 | 所有者映射 |
| file_mode/dir_mode | 0664/0775 | 掩码 |
| cache | strict | 缓存一致性 |
| actimeo | 1 | 属性缓存秒数 |
| noserverino | – | 避免 inode 对齐问题 |
| mfsymlinks | – | 模拟软链接 |
八、性能与验证
Windows → SMB → Linux(Samba)
robocopy 复制 100GB 大文件集,万兆链路下持续 800~950 MB/s;
10 并发小文件写入,CPU 占用 < 60%(Samba 进程),磁盘为 RAID10,队列深度 32 时延 < 2ms。
Linux → 本地 ext4 / NFS
fio(4K 随机读写、128 并发)QPS 稳定在 NVMe 能力上限 60~80%(考虑网络协议开销)。
dd if=/dev/zero of=/mnt/projects/test bs=1G count=20 oflag=direct 写入速度接近物理盘顺序带宽。
现场经验:带宽上限能跑满并不难,小文件场景要靠 aio、内核参数(vm.dirty_ratio)、以及避免“一个目录塞十万文件”。
九、高可用(HA)实战:DRBD + Pacemaker + VIP + Samba
这个 HA 设计让我睡得更踏实。
DRBD 同步卷(简化示例)
yum install -y drbd90-utils kmod-drbd90
cat >/etc/drbd.d/share.res <<'EOF'
resource share {
protocol C;
on hk-smb1 { device /dev/drbd0; disk /dev/vg_data/lv_share; address 10.10.10.11:7789; meta-disk internal; }
on hk-smb2 { device /dev/drbd0; disk /dev/vg_data/lv_share; address 10.10.10.12:7789; meta-disk internal; }
}
EOF
drbdadm create-md share
systemctl enable drbd --now
drbdadm up share
drbdadm -- --overwrite-data-of-peer primary share
mkfs.ext4 /dev/drbd0
Pacemaker 资源(要点)
- 资源顺序:drbd(primary) → 挂载 ext4 → smbd → VIP;
- 迁移策略:on-fail=restart,migration-threshold=1;
- 共享目录与 smb.conf 放在 同一节点 切换时同步可用。
如果你更熟 GlusterFS / CephFS,也可以用它们做后端,再用 Samba 做 SMB 网关,我在另一个站点用 CephFS + ceph vfs for Samba 跑得也很稳,但部署复杂度更高,这篇不展开。
十、常见坑与我的现场解法
- 连不上 / 协议不匹配:CentOS 7 的 cifs-utils 老去尝试 SMB1,挂载时明确 vers=3.0 或 3.1.1。
- 中文名乱码:Linux 端 iocharset=utf8、Samba 端 unix charset=UTF-8;历史 GBK 文件批量改名。
- 权限乱套:Linux 目录一律 2775 + force group,Samba 开 acl_xattr 与 inherit permissions,不要混用 force user。
- SELinux 拦截:不偷懒,semanage fcontext + restorecon + setsebool,日志看 audit.log。
- 小文件慢:提升并发、启用 aio,目录分层,适当增加客户端 actimeo,避免每次 stat。
- Git 全量改动:统一 core.autocrlf=false、core.filemode=false,Linux 端不要对 SMB 目录做 chmod/chown。
- NFS 与 SMB 混挂:同一批文件不要跨协议并发写;只读没问题,写入一律走单协议。
- Windows 保留字符:入口校验(CI 脚本或上传工具),禁止 : * ? < > | 等;Linux 端也遵守规则。
- 多网卡/多路径:CentOS 7 的 Samba 不建议开 Multi-Channel,跑 LACP 就好;Windows 客户端别乱开 SMB Multi-Channel 测试版。
十一、运维脚本与日常点检
Samba 存活与连接数
systemctl is-active smb || systemctl restart smb
smbstatus --shares
满目录预警(小文件爆炸)
find /data/share/projects -type d -maxdepth 3 -exec bash -c 'echo -n "{}: "; ls -1 "{}" | wc -l' \; | sort -nr | head
日志审计(full_audit)
grep projects /var/log/samba/audit.log | awk -F\| '{print $1,$2,$3,$5}'
备份(Rsync 到离线盘/对象存储)
rsync -aH --numeric-ids --delete /data/share/projects/ /backup/projects/
十二、成本与选型建议(给采购的 3 条底线)
盘优先 NVMe U.2/U.3:别为了省小钱上 SATA 混合,IO 抖动会把你搞疯。
万兆必须打满:双口 10GbE + LACP,交换机合理分配 buffer,别用老年交换机。
内存要给够:Samba 其实挺吃页缓存的;Linux 侧 128GB 起步很舒服。
十三、结语:从“甩锅现场”到“沉默稳定”
回到那一夜,Windows 同学试着在 P 盘拖了个 20GB 的素材包,传输曲线稳稳贴在 900MB/s;Linux 同学在另一头 ffmpeg 输出中文文件名,Windows 里显示也正常。凌晨四点半,机房里终于安静了——只剩交换机风扇的白噪音。我合上笔记本,给群里发了条消息:“两端都能用、权限都对、不会再互相背锅了。”
第二天,大家照常开工。没有人再提共享盘——这对一个存储工程师来说,是最高的表扬。
附:一键化最小可用配置清单(可直接改 IP/用户落地)
Linux(Samba)最小可用
# 假设已有 /data/share/projects
yum install -y samba policycoreutils-python
useradd shareop && (echo 'StrongP@ssw0rd' | passwd --stdin shareop)
(echo 'StrongP@ssw0rd'; echo 'StrongP@ssw0rd') | smbpasswd -a shareop
cat >/etc/samba/smb.conf <<'EOF'
[global]
server min protocol = SMB2_10
server max protocol = SMB3
unix charset = UTF-8
dos charset = CP936
vfs objects = acl_xattr
map acl inherit = Yes
store dos attributes = Yes
strict locking = yes
[projects]
path = /data/share/projects
writable = yes
valid users = shareop
create mask = 0664
directory mask = 0775
inherit permissions = yes
EOF
semanage fcontext -a -t samba_share_t "/data/share(/.*)?"
restorecon -Rv /data/share
setsebool -P samba_export_all_rw on
systemctl enable smb --now
Windows 映射
net use P: \\10.10.10.11\projects /user:shareop StrongP@ssw0rd /persistent:yes
Linux(cifs)挂载
yum install -y cifs-utils
cat >/root/.smbcred <<EOF
username=shareop
password=StrongP@ssw0rd
domain=WORKGROUP
EOF
chmod 600 /root/.smbcred
echo "//10.10.10.11/projects /mnt/projects cifs credentials=/root/.smbcred,vers=3.0,sec=ntlmssp,iocharset=utf8,uid=1000,gid=1000,file_mode=0664,dir_mode=0775,cache=strict,actimeo=1 0 0" >> /etc/fstab
mount -a
真正的难点不是“会不会配”,而是知道为什么要这样配、出了问题往哪查。上面这份笔记,为的就是让你在机房里,少走几次我走过的夜路。祝你