Docker在Windows和Linux上部署,差别比你想的大
很多人第一次在 Windows 上装 Docker,看到托盘图标变绿就以为成了,结果一跑容器就报错。问题不在命令写错,而在 Windows 和 Linux 跑 Docker 的底层根本不是一回事。Linux 上 Docker 直接调用内核的 namespace 和 cgroup,Windows 上得先架一层虚拟化,再在里面跑一个 Linux 内核。这层东西平时不吭声,一旦内存或端口出问题,排查方向就完全不一样了。
Windows 端:先搞清楚你装的到底是什么
Windows 上装 Docker 有两条路。一条是 Docker Desktop,另一条是在 WSL2 里直接装 Docker Engine。两者差别不小。
Docker Desktop 装完会默认起一个 WSL2 发行版叫 docker-desktop,容器实际跑在这个发行版里。它的内存上限由 .wslconfig 控制,默认是主机内存的一半。一台 16G 的机器,容器最多只能用 8G,再多就 OOM。这个限制在 Linux 上不存在,所以同一份 compose 文件从 Linux 搬到 Windows,最先炸的往往是内存。
改法是在用户目录下建 .wslconfig:
- [wsl2]
- memory=12GB
- processors=6
改完要执行 wsl --shutdown 再重启 Docker,不然不生效。这点很多人踩过,以为改了没用。
另一条路是在 WSL2 里装原生 Docker Engine,不装 Desktop。这样没有那层图形界面,资源占用小,行为也更接近 Linux。代价是没有托盘图标、没有右键菜单,端口转发要自己配。我一般建议:纯开发用 Desktop 图省事,要跑接近生产的负载就在 WSL2 里装 Engine。
Linux 端:装完之后最容易漏的三步
Linux 上装 Docker 本身不复杂,官方脚本一行就完事。麻烦的是装完之后。
第一,默认只有 root 能跑 docker 命令。把当前用户加进 docker 组:
- sudo usermod -aG docker $USER
- 然后退出登录再进,组权限才生效
注意这个组等于给了 root 权限,生产机上要掂量。
第二,数据卷默认放在 /var/lib/docker。如果系统盘小,跑几个镜像就满了。改法是在 /etc/docker/daemon.json 里指定 data-root 到数据盘。这个改动要迁移已有数据,别直接改,先停 Docker 再 rsync 过去。
第三,日志默认不限制大小。一个跑得久的容器,json-file 日志能堆到几个 G。加上 log-opts 限制:
- max-size=10m
- max-file=3
这行加不加,长期跑下来磁盘占用差好几倍。
网络模式:两边差得最明显的地方
Linux 上 --network host 能让容器直接用宿主机网络,性能几乎没有损耗。Windows 上这个模式在 Docker Desktop 里基本用不了,容器跑在 WSL2 虚拟机里,host 指的是那台虚拟机,不是你的 Windows 主机。
所以从 Windows 访问容器,得靠端口映射 -p 8080:80。而 WSL2 的 localhost 转发有时会抽风,容器明明起来了,浏览器就是连不上。这种情况多半是 WSL2 的网络没起来,wsl --shutdown 重启一下通常能好。
跨主机通信的话,两边都得配 overlay 网络,这块 Windows 上的支持一直不如 Linux 顺。如果不是必须,容器编排我建议直接上 Linux 物理机或独立服务器,少一层虚拟化就少一堆怪问题。像 西雅图裸机云服务器 X 这种 E5-2697*2 / 32G / 100M 的配置,跑十几个容器绰绰有余,月付 $129.00,比在 Windows 上跟 WSL2 较劲省心得多。
什么时候不该用 Docker Desktop
如果你只是想在本地跑个数据库或中间件测试,Desktop 够用。但如果要做下面这些事,我建议直接上 Linux:
- 需要 host 网络模式做低延迟通信
- 要跑 Kubernetes 或 Docker Swarm
- 容器数量超过十个,或者对内存有硬性要求
Windows 上的 Docker 适合开发调试,不适合当生产环境。这个界限分清楚,能少走很多弯路。
最后说个实际取舍。一台 16G 内存的 Windows 开发机,扣掉系统占用和 WSL2 默认上限,容器实际能用的可能只有 6G 左右。同样预算换成 Linux 独立服务器,32G 内存全部给容器用,价格可能还更低。部署方式的选择,很多时候本质上是资源账。