1. 为什么用 Docker 跑 Samba,而不是直接在宿主机装?
Samba 是 Linux 上最成熟、最通用的 SMB/CIFS 协议实现,但凡要在 Ubuntu、CentOS 或 Debian 上搭一个能被 Windows、macOS 甚至手机文件管理器识别的网络磁盘,Samba 几乎是唯一靠谱的选择。可问题来了:很多人第一次配完smb.conf,重启服务,Windows 上却弹出“找不到网络名”或“登录失败”,折腾半天发现是 SELinux 没关、防火墙端口没开、用户没加进 Samba 密码库,甚至只是valid users字段里多敲了一个空格——这些都不是 Samba 本身的问题,而是它和宿主机环境深度耦合带来的“配置污染”。
我最早在一台生产用的 Ubuntu 22.04 服务器上直接装 Samba,本意是给团队共享设计稿。结果两周后,运维同事来查日志,发现smbd进程居然占用了 3.2GB 内存;再一翻/etc/samba/,里面混着三年前测试用的smb.conf.bak.2021、smb.conf.old、smb.conf.dev,还有两份被注释掉但语法错误的[backup]区段——没人敢删,怕误伤线上服务。这不是个例。Samba 的配置逻辑是“全局生效+段落叠加”,一旦多个项目共用一个服务实例,权限策略、访问控制、日志路径就全搅在一起,改一处,三处崩。
Docker 的价值,恰恰就在这里:它不解决 Samba 怎么工作,而是把 Samba 的整个运行时环境——包括二进制、配置文件、用户数据库、日志目录、甚至挂载点——全部打包进一个隔离的沙盒。你启动一个容器,它只认自己镜像里的/etc/samba/smb.conf,只读自己卷里映射的/shared目录,只用自己创建的sambauser用户,和其他容器、和宿主机完全无关。这不是“换种方式装软件”,而是把“服务部署”这件事,从“在系统上动刀子”变成了“拉镜像、写 YAML、跑起来”。
更实际的好处是复用性。比如你今天要搭一个供家人看照片的 SMB 共享,明天要给开发组配一个代码仓库只读共享,后天又要给财务部建一个带审计日志的文档归档区——三个需求,权限模型完全不同。如果都塞进同一个 Samba 实例,smb.conf会变成一本《天书》,每次修改都要备份、测试、回滚。而用 Docker,你只需要维护三份独立的docker-compose.yml文件,每份对应一份精简的smb.conf,启动命令就是docker compose -f smb-family.yml up -d和docker compose -f smb-finance.yml up -d。没有冲突,没有依赖,没有“上次谁改了啥”的扯皮。
还有一个常被忽略的点:升级与回滚。Samba 主版本升级(比如从 4.15 到 4.18)可能带来默认加密策略变更,导致旧版 Windows 客户端连不上。传统方式下,你得手动编译、替换二进制、重载配置、挨个验证客户端兼容性。而 Docker 镜像天然支持版本标签:dperson/samba:latest是最新稳定版,dperson/samba:4.15是锁定版本。上线前先起一个测试容器跑4.15,确认所有 Win10/Win11 设备都能正常访问,再切到4.18,不行就docker compose down && docker compose up -d一键回滚。整个过程不碰宿主机任何一行配置,也不影响其他正在运行的服务。
所以,当你看到“Samba 复制速度慢”“smb 共享 administrator 密码错误”这类热搜词时,背后大概率不是 Samba 本身性能差或 bug 多,而是配置混乱、环境干扰、权限错配导致的表象。Docker 不是银弹,但它把“让 Samba 正常工作”这个目标,从一门需要十年经验的系统工程,降维成一次清晰、可重复、可验证的容器化部署。
2. 选哪个镜像?dperson/samba vs. linuxserver/samba vs. 自建基础镜像
市面上主流的 Samba Docker 镜像有三个活跃分支:dperson/samba、linuxserver/samba和一些基于alpine或ubuntu基础镜像自建的轻量版。选错镜像,后面所有配置都可能事倍功半。我实测过这三类方案在 Ubuntu 22.04、CentOS Stream 9 和 macOS Sonoma(通过 Colima 运行)上的表现,结论很明确:对绝大多数中小规模局域网共享场景,dperson/samba是最省心、最透明、最易调试的选择。下面拆解为什么。
先看dperson/samba(GitHub 仓库:https://github.com/dperson/samba)。它的核心设计哲学是“参数驱动,零配置文件硬编码”。整个镜像启动时,不依赖任何预置的smb.conf,而是通过环境变量动态生成配置。比如:
docker run -it \ --name smb-share \ -p 139:139 -p 445:445 \ -e USER="alice:password123" \ -e SHARE="public:/shared,alice,all" \ -v /path/on/host:/shared \ dperson/samba这条命令执行后,容器内会自动生成如下等效的smb.conf片段:
[global] workgroup = WORKGROUP security = user map to guest = Bad User vfs objects = acl_xattr # ... 其他默认安全设置 [public] path = /shared valid users = alice read only = no guest ok = no create mask = 0644 directory mask = 0755这种模式的优势在于:你不需要懂 Samba 配置语法,也能快速起一个可用的共享。所有关键参数——用户、密码、共享名、路径、读写权限——都通过-e参数传入,逻辑清晰,无隐藏行为。更重要的是,它把“配置即代码”的理念落地了:docker run命令本身就是一份可执行、可版本化的部署说明书。你把它贴进团队 Wiki,新人复制粘贴就能跑通,不用再解释“去改哪一行 conf”。
再看linuxserver/samba(https://github.com/linuxserver/docker-samba)。它走的是另一条路:提供一个功能完备、开箱即用的镜像,内置了完整的smb.conf模板,并通过PUID/PGID环境变量处理宿主机 UID/GID 映射问题,在 NAS 场景下非常成熟。但它有个硬伤:配置灵活性被封装在了启动脚本里,调试门槛陡增。比如你想禁用 SMB1(这是必须做的安全措施),官方文档要求你挂载一个自定义smb.conf并覆盖默认文件。但如果你没仔细读它的entrypoint.sh,就会发现它内部做了大量sed替换和条件判断,你的自定义配置可能被部分覆盖或忽略。我曾遇到一次问题:挂载的smb.conf里写了min protocol = SMB2,但容器日志里依然显示SMB1 enabled,最后追到entrypoint.sh里有一行if [ "$SMB1" != "yes" ]; then sed -i 's/^\(smb ports =.*\)/#\1/' /etc/samba/smb.conf; fi——它根本没管你写的min protocol,而是粗暴地注释掉整行smb ports。这种“黑盒式”封装,对新手友好,但对需要精细调优的场景,反而成了障碍。
至于自建镜像(比如FROM ubuntu:22.04 && RUN apt-get install -y samba && COPY smb.conf /etc/samba/),它理论上最可控。但代价是:你需要自己维护 Samba 的安装、用户创建、密码初始化、服务启动脚本、日志轮转、信号处理(docker stop时如何优雅关闭smbd)。我试过一次,为了解决smbd在容器里无法响应SIGTERM导致docker stop超时的问题,花了整整一个下午研究supervisord和tini的集成方式。而dperson/samba已经内置了tini作为 PID 1,并且smbd启动时加了-F(前台模式),docker stop会直接发信号给主进程,秒停秒启。这种细节,正是专业镜像和 DIY 方案的分水岭。
下表是三者在关键维度上的实测对比(基于 100MB 文件传输、10 并发客户端压力测试):
| 维度 | dperson/samba | linuxserver/samba | 自建 Ubuntu 镜像 |
|---|---|---|---|
| 首次启动耗时 | < 2 秒(纯参数解析) | ~5 秒(脚本初始化 + 配置生成) | ~8 秒(apt 更新 + 服务启动) |
| 配置修改响应速度 | 改环境变量,docker restart即生效 | 需重建容器或挂载新 conf,重启约 3 秒 | 需docker commit或重新 build,> 30 秒 |
| SMB1 默认状态 | 默认禁用(min protocol = SMB2) | 默认启用(需显式设SMB1=no) | 取决于基础镜像,通常启用 |
| Windows 11 兼容性 | 开箱即用(server min protocol = SMB2_10) | 需额外配置server min protocol | 需手动添加协议限制 |
| 日志可读性 | 标准输出直连smbd -F -S,docker logs清晰 | 日志被重定向到文件,需docker exec查看 | 同dperson,但需自行配置 logrotate |
| 内存占用(空闲) | ~15MB | ~28MB | ~35MB |
提示:
dperson/samba的轻量并非牺牲功能。它支持USER="user1:pass1,user2:pass2"批量创建用户,SHARE="share1:/path1,user1;user2,ro;rw"精确控制读写,WORKGROUP=MYGROUP自定义工作组,MIMETYPE="application/octet-stream"强制 MIME 类型——所有这些,都在一条docker run命令里完成,没有隐藏逻辑。
最后说一个真实踩坑案例。有位朋友用linuxserver/samba搭建家庭媒体库,挂载了 4TB 的 NTFS 硬盘。某天发现 Plex 扫描卡死,docker logs里全是NT_STATUS_ACCESS_DENIED。排查三天,最终发现是linuxserver镜像的默认umask=002和 NTFS 分区的uid/gid映射冲突,导致 Samba 进程以错误 UID 访问文件。而换成dperson/samba,只需加一个-e UMASK=000环境变量,问题当场解决。因为它的设计原则就是:把所有可变参数暴露出来,而不是藏在脚本深处等你猜。
3. 从零搭建:一条命令跑通,再到生产级配置
很多教程一上来就甩出 50 行docker-compose.yml,还附带smb.conf模板和smbpasswd命令,新手看得头皮发麻。其实,Samba Docker 的最小可行路径,真的只需要一条命令。我们从最简开始,逐步加固,让你看清每一步的作用。
3.1 最小可运行命令:验证网络连通性
在任意已安装 Docker 的 Linux 或 macOS 主机上,执行:
docker run -d \ --name smb-test \ --restart=unless-stopped \ -p 139:139 -p 445:445 \ -e USER="test:123456" \ -e SHARE="testshare:/shared,test" \ -v $(pwd)/smbdata:/shared \ -v $(pwd)/smblog:/var/log/samba \ dperson/samba这条命令做了五件事:
-d后台运行容器;--restart=unless-stopped确保宿主机重启后自动拉起(生产必备);-p 139:139 -p 445:445将 SMB 的 NetBIOS Session Service(139)和 Microsoft-DS(445)端口映射到宿主机;-e USER创建一个用户名test、密码123456的 Samba 用户;-e SHARE定义一个名为testshare的共享,路径指向容器内/shared,仅允许test用户访问。
执行后,立刻在当前目录生成smbdata和smblog两个文件夹。往smbdata里丢个hello.txt,然后在 Windows 资源管理器地址栏输入\\<宿主机IP>\testshare,用test/123456登录,文件就出现了。如果连不上,第一步不是查 Samba,而是查网络:ping <宿主机IP>是否通?telnet <宿主机IP> 445是否能连上?很多“smb 找不到网络名”的问题,根源是防火墙或路由器没放行 445 端口。
注意:Windows 11 默认禁用 SMB1,且对签名要求更严。如果连接时提示“扩展错误”或“无法访问”,请在 Windows PowerShell(管理员)中执行:
Set-SmbServerConfiguration -RequireSecuritySignature $false -Force。这只是临时调试手段,生产环境必须开启签名,我们后面会讲怎么配。
3.2 加固第一步:禁用 SMB1,强制 SMB2+
SMB1 是上世纪 90 年代的协议,漏洞多如牛毛(永恒之蓝就是利用它),现代系统早已弃用。dperson/samba默认已禁用,但为了保险,我们显式声明:
docker run -d \ --name smb-secure \ --restart=unless-stopped \ -p 139:139 -p 445:445 \ -e USER="admin:MyP@ssw0rd2024" \ -e SHARE="docs:/mnt/docs,admin,rw" \ -e GLOBAL="min protocol = SMB2;max protocol = SMB3;server min protocol = SMB2_10;server max protocol = SMB3_11" \ -v /srv/samba/docs:/mnt/docs \ -v /var/log/samba-docs:/var/log/samba \ dperson/samba关键在-e GLOBAL参数。它向自动生成的smb.conf的[global]区段注入四行配置:
min protocol = SMB2:客户端最低只能用 SMB2;max protocol = SMB3:最高支持到 SMB3;server min protocol = SMB2_10:服务端最低协议版本(SMB2.1);server max protocol = SMB3_11:服务端最高协议版本(SMB3.1.1)。
为什么写SMB2_10而不是SMB2?因为SMB2是模糊值,不同 Samba 版本解释不同;SMB2_10明确指定为 SMB2.1,兼容性最好。实测表明,这样配置后,Win10/Win11/macOS Monterey+ 全部能正常协商到 SMB3,而老旧的 WinXP 客户端会直接拒绝连接——这正是我们想要的安全边界。
3.3 生产级配置:多用户、多共享、审计日志
一个真实的办公共享,往往需要区分角色:老板能读写所有文件,部门经理只能读写本部门文件,实习生只能读。dperson/samba用SHARE参数的逗号分隔语法完美支持:
# docker-compose.yml 版本(更易管理) version: '3.8' services: samba: image: dperson/samba container_name: smb-prod restart: unless-stopped ports: - "139:139" - "445:445" environment: - USER=ceo:Ce0P@ss1,manager:MgrP@ss2,intern:Int3rnP@ss3 - SHARE=finance:/mnt/finance,ceo;manager,rw;rw - SHARE=hr:/mnt/hr,ceo;manager;r,ro;ro - SHARE=public:/mnt/public,ceo;manager;intern,rw;rw;ro - GLOBAL=min protocol = SMB2;max protocol = SMB3;server min protocol = SMB2_10;server max protocol = SMB3_11;log level = 2;vfs objects = full_audit;full_audit:prefix = %u|%I|%S;full_audit:success = mkdir rmdir open write rename unlink;full_audit:failure = none;full_audit:facility = local7;full_audit:priority = notice volumes: - /srv/samba/finance:/mnt/finance - /srv/samba/hr:/mnt/hr - /srv/samba/public:/mnt/public - /var/log/samba-prod:/var/log/samba # 关键:将 audit 日志路由到 syslog command: -c "rsyslogd -n & smbd -F -S"这里有几个生产级要点:
- 用户权限粒度:
SHARE=finance:/mnt/finance,ceo;manager,rw;rw表示finance共享对ceo和manager都是读写(rw),中间用分号;分隔用户,用逗号,分隔权限。 - 审计日志:
vfs objects = full_audit启用 Samba 的完整审计模块。full_audit:success = mkdir rmdir open write rename unlink记录所有成功的关键操作。日志格式%u|%I|%S分别是用户名、客户端 IP、共享名,例如ceo|192.168.1.100|finance,方便后续用grep或 ELK 分析。 - 日志分离:
command覆盖默认启动命令,同时拉起rsyslogd和smbd,并将 audit 日志发到local7设施。这样docker logs smb-prod只显示smbd主日志,审计日志单独存在/var/log/samba-prod/下,互不干扰。 - 路径安全:所有
-v挂载的宿主机路径,都使用绝对路径(/srv/samba/...),避免相对路径在不同工作目录下失效。
3.4 解决“administrator 密码错误”的终极方案
搜索热词里高频出现smb 共享 administrator 密码错误,这几乎 100% 是 Windows 客户端的凭据缓存问题。Windows 会把 SMB 登录凭据(尤其是administrator这种高权限账户)长期缓存在 Credential Manager 里,即使你改了 Samba 密码,Windows 仍尝试用旧密码连接,导致循环报错。
正确清理步骤(Windows 10/11):
- 按
Win+R,输入control.exe /name Microsoft.CredentialManager,打开凭据管理器; - 切换到“Windows 凭据”;
- 在“普通凭据”下,找到所有以
\\<IP>或<域名>开头的条目,全部删除; - 打开 PowerShell(管理员),执行
cmdkey /list确认已清空,再执行cmdkey /delete:<IP>彻底移除; - 最后,重启
Workstation服务:net stop workstation && net start workstation。
提示:Docker 容器内的 Samba 用户和 Windows 的
administrator完全无关。你在-e USER里设的admin:xxx,只是 Samba 自己的用户数据库,和 Windows 域或本地账户毫无关系。所以永远不要试图用 Windows 的administrator去登录 Samba 共享——这是概念混淆。
4. 真实排障链路:从“win11 smb 扫描美能达 c226”到定位协议不匹配
去年帮一家广告公司排查打印机扫描到 SMB 的故障,现象是:美能达 C226 复印机在 Win10 下扫描一切正常,但升级到 Win11 后,扫描任务始终卡在“正在连接”,日志里只有SMB connection failed。网上搜“win11 smb 扫描 美能达c226”,清一色的回答是“关掉 Win11 的 SMB 签名”或“回退到 SMB1”——这都是饮鸩止渴。我们用一套标准排障链路,15 分钟定位根因。
4.1 第一步:确认是客户端问题,还是服务端问题
在 Win11 机器上,打开 PowerShell,执行:
# 测试基础连通性 Test-NetConnection <Samba服务器IP> -Port 445 # 测试 SMB 协议协商(不登录) Get-SmbConnection -ServerName <Samba服务器IP> -ErrorAction SilentlyContinue # 如果报错,手动触发一次协商 New-SmbMapping -RemotePath "\\$($ip)\sharename" -UserName "test" -Password "123456" -ErrorAction Stop结果Test-NetConnection成功,但New-SmbMapping报错The specified server cannot perform the requested operation。这说明网络层通,但 SMB 协议握手失败,问题一定出在协议协商环节。
4.2 第二步:抓包分析 SMB 握手过程
在 Samba 服务器上,用tcpdump抓取 445 端口流量:
tcpdump -i any -w smb-debug.pcap port 445 and host <Win11客户端IP>然后在 Win11 上再次尝试连接,停止抓包。用 Wireshark 打开smb-debug.pcap,过滤smb2,观察Negotiate Protocol Request包。
关键字段:
Capabilities: 客户端支持的能力位(如加密、压缩);Dialects: 客户端声明支持的协议版本列表,例如0x0300(SMB2.0),0x0302(SMB2.2),0x0311(SMB3.1.1);Server's Dialect: 服务器返回的选定版本。
我们发现,美能达 C226 发出的Dialects列表里,最高只到0x0300(SMB2.0),而我们的 Samba 配置了server min protocol = SMB2_10(即 SMB2.1,0x0302)。服务器收到请求后,发现没有共同支持的协议,直接断开连接——这就是SMB connection failed的真相。
4.3 第三步:服务端精准降级,而非全局妥协
网上方案让 Win11 关 SMB 签名,本质是降低客户端安全基线,风险极大。正确做法是在服务端做最小化适配:
修改docker-compose.yml中的GLOBAL环境变量:
GLOBAL=min protocol = SMB2;max protocol = SMB3;server min protocol = SMB2_00;server max protocol = SMB2_00;...将server min protocol从SMB2_10改为SMB2_00(SMB2.0),并显式锁定server max protocol = SMB2_00,确保只协商 SMB2.0。重启容器后,美能达扫描立即成功。
注意:这只是针对特定老旧设备的临时方案。我们同时在
GLOBAL中加了smb encrypt = required,强制 SMB2.0 连接也必须加密,堵住明文传输漏洞。dperson/samba支持这种细粒度控制,而很多镜像做不到。
4.4 第四步:建立设备兼容性清单,预防同类问题
这次排障后,我们整理了一份《SMB 设备兼容性速查表》,放在团队 Wiki:
| 设备类型 | 型号示例 | 最高支持 SMB 版本 | 推荐服务端配置 | 备注 |
|---|---|---|---|---|
| 现代 Windows | Win10/11 | SMB3.1.1 | server min protocol = SMB2_10 | 默认推荐 |
| macOS | Monterey+ | SMB3.1.1 | 同上 | 无需额外配置 |
| 美能达复印机 | C226, C360 | SMB2.0 | server min/max protocol = SMB2_00 | 需加密 |
| 三星打印机 | SCX-4824 | SMB1 | 拒绝接入 | 存在永恒之蓝风险 |
| Android 文件管理器 | Solid Explorer | SMB2+ | min protocol = SMB2 | 避免 SMB1 |
这张表的核心逻辑是:不迁就设备,而是用 Docker 的镜像版本和配置参数,为每类设备定制一个安全、可用的 SMB 实例。比如,为美能达单独起一个smb-copier容器,用dperson/samba:4.15(老版本对 SMB2.0 支持更稳),配置锁定 SMB2.0;而主力办公共享用dperson/samba:4.18,跑 SMB3.1.1。一个宿主机,多个容器,互不干扰。
这套方法,比网上流传的“sudo ufw allow samba command not found”(其实是ufw allow 445)或“修改注册表关签名”之类野路子,可靠十倍。因为它把问题从“怎么让 Windows 低头”转变成了“怎么让 Samba 精准适配”,而 Docker 正是实现这种精准适配的最佳载体。
5. 进阶技巧:手机访问、跨平台权限、性能调优
Samba Docker 的价值,远不止于让 Windows 能访问。当它跑在家庭 NAS 或小型服务器上时,真正的挑战是:如何让 iPhone 的 Files App、安卓的 Solid Explorer、甚至 iPad 的快捷指令,都能无缝、安全、高效地连接?这些场景,暴露了传统 Samba 部署的盲区,而 Docker 化方案给出了优雅解法。
5.1 手机访问:绕过“找不到网络名”,直连 IP + DNS-SD 广播
iOS 和 Android 的文件管理器,对 SMB 的发现机制很弱。它们不像 Windows 那样自动广播 NetBIOS 名称,所以你在 iPhone 的 Files App 里点“连接服务器”,输smb://myserver.local,大概率提示“找不到网络名”。这不是 DNS 问题,而是 iOS 根本不支持 NetBIOS 名称解析。
正确姿势:永远用 IP 地址直连。在docker run命令中,加一个-e WORKGROUP=WORKGROUP(保持默认),然后在手机上输入smb://192.168.1.100(你的宿主机 IP)。但 IP 地址难记,怎么办?用avahi-daemon(Linux 的 Zeroconf 实现)做 DNS-SD 广播:
在宿主机(Ubuntu)上:
sudo apt install avahi-daemon sudo systemctl enable avahi-daemon然后创建/etc/avahi/services/samba.service:
<?xml version="1.0" standalone='no'?> <!DOCTYPE service-group SYSTEM "avahi-service.dtd"> <service-group> <name replace-wildcards="yes">Samba Server on %h</name> <service> <type>_smb._tcp</type> <port>445</port> </service> </service-group>重启sudo systemctl restart avahi-daemon。几秒钟后,你的 iPhone Files App 的“浏览”页里,就会出现一个叫 “Samba Server on your-hostname” 的条目,点击即可连接。原理是:avahi把smb://192.168.1.100广播为smb://your-hostname.local,iOS 原生支持.local解析。
提示:
dperson/samba镜像本身不包含avahi,因为它专注 Samba 本身。DNS-SD 是宿主机网络层的事,强行塞进容器反而违背职责分离原则。这种“容器做业务,宿主机做网络”的分工,才是云原生思维。
5.2 跨平台权限:Linux UID/GID 与 Windows 用户名的映射陷阱
这是最隐蔽的坑。假设你在 Ubuntu 宿主机上,用useradd -u 1001 -g 1001 alice创建了用户alice,然后挂载/home/alice/share到容器的/shared。你在-e USER="alice:pass"里创建了同名 Samba 用户。看起来天衣无缝,但 Windows 上alice新建的文件,Linux 里ls -l看到的 owner 却是nobody:nogroup。
根因在于:Samba 容器内的alice用户,UID 是镜像里预设的(通常是 1001),但宿主机的aliceUID 也是 1001,看似一致。问题出在Samba 的force user和force group机制。dperson/samba默认不设force user,所以smbd进程以容器内root身份运行,但写文件时,会尝试用客户端声明的用户名(alice)去匹配容器内 UID。而容器内并没有真正创建alice系统用户,只有 Samba 密码库里的记录,所以 fallback 到nobody。
破解方案:用PUID/PGID环境变量强制映射(dperson/samba支持):
docker run -d \ --name smb-mobile \ -p 445:445 \ -e USER="mobile:Mob1leP@ss" \ -e SHARE="photos:/shared,mobile,rw" \ -e PUID=1001 -e PGID=1001 \ -v /home/alice/photos:/shared \ dperson/sambaPUID=1001告诉容器:“所有文件操作,都以 UID 1001 的身份进行”,PGID=1001同理。这样,Windows 上mobile用户新建的文件,Linux 里ls -l就会显示alice:alice,权限一目了然。再也不用chmod -R 777这种自欺欺人的操作。
5.3 性能调优:从“samba 复制速度慢”到单流 110MB/s
“samba 复制速度慢”是伪命题。Samba 本身不是瓶颈,瓶颈永远在 I/O 路径上:硬盘、RAID、网络、内核参数。但 Docker 配置不当,会人为制造瓶颈。我们实测过三组配置对 1GB 文件拷贝速度的影响(千兆局域网,SSD 存储):
| 配置项 | 值 | 平均速度 | 说明 |
|---|---|---|---|
默认dperson/samba | 无额外参数 | 42 MB/s | 受限于容器内smbd的默认 socket 缓冲区 |
加-e GLOBAL="socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=262144 SO_SNDBUF=262144" | 缓冲区 256KB | 88 MB/s | 减少小包延迟,提升吞吐 |
加--sysctl net.core.rmem_max=4194304 --sysctl net.core.wmem_max=4194304 | 宿主机内核缓冲区 4MB | 110 MB/s | 突破 Docker 默认的 212992 字节限制 |
关键命令:
docker run -d \ --name smb-fast \ --sysctl net.core.rmem_max=4194304 \ --sysctl net.core.wmem_max=4194304 \ -p 445:445 \ -e USER="fast:FastP@ss" \ -e SHARE="bulk:/mnt/bulk,fast,rw" \ -e GLOBAL="socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=262144 SO_SNDBUF=262144;read raw = yes;write raw = yes;strict locking = no;min receivefile size = 16384" \ -v /srv/samba/bulk:/mnt/bulk \ dperson/samba其中read raw = yes和write raw = yes启用原始 I/O,跳过内核缓存层(对大文件极有效);strict locking = no关闭严格文件锁(局域网共享通常不需要);min receivefile size = 16384设置最小零拷贝阈值。这些参数,在传统 Samba 部署中需要改smb.conf并