上一篇 下一篇 分享链接 返回 返回顶部

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

发布人:Minchunlin 发布时间:2025-08-25 10:43 阅读量:838


半夜两点,荃湾机房的空调吹得我直打哆嗦。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

真正的难点不是“会不会配”,而是知道为什么要这样配、出了问题往哪查。上面这份笔记,为的就是让你在机房里,少走几次我走过的夜路。祝你

目录结构
全文