一、缘由:就是因为"懒"
事情是这样的。
我本地开发环境是Windows + WSL2(跑的Ubuntu),写Go代码、跑测试、调试都很舒服。但生产环境的服务器还存在一部分的CentOS 7,这时候问题就来了——本地编译好的二进制文件,扔到CentOS 7上能不能跑?
理论上Go的交叉编译很方便,GOOS=linux GOARCH=amd64 一行环境变量搞定。但现实往往不这么温柔:
- 动不动就碰到CGO依赖(
CGO_ENABLED=1的场景),比如用到了sqlite、某些网络库 - glibc版本对不上:本地Ubuntu的glibc比CentOS 7的新不少,编译出来的东西拿到老系统上直接报
GLIBC_2.xx not found - 静态编译?关掉CGO确实可以,但有些库你关不掉,关了就编不过
折腾了几次静态编译的各种参数组合之后,我悟了:与其费劲研究交叉编译环境,不如直接在本地弄个CentOS 7,所见即所得。
WSL2刚好支持导入自定义发行版,而Docker Hub上有现成的CentOS 7镜像。把Docker镜像导出来喂给WSL,完美。
这就是这篇文章的缘由——懒,懒得研究静态编译那堆参数,直接在WSL2里装个CentOS 7编完拉倒。
二、两条路:手动 vs 偷懒
装CentOS 7到WSL2,本质上就两条路:
| 方案 | 原理 | 适合谁 |
|---|---|---|
| 手动导入Docker镜像 | Docker拉镜像 → 导出tar → WSL导入 | 喜欢掌控每一步、已有Docker环境的人 |
| 第三方UI工具一键安装 | Windows商店里的WSL管理工具,点鼠标搞定 | 纯懒人,不想敲命令 |
两种我都试过,下面分别说。第一种是本文的重点,第二种适合赶时间的同学。
三、方案一:手动导入Docker镜像(纯手工版)
思路很直白:WSL2导入的是tar格式的rootfs,Docker可以导出容器的rootfs,把Docker的CentOS 7容器导出来喂给WSL就行了。
1. 前置准备
确认你的Windows已经启用了WSL2。没启用的话,用管理员权限打开PowerShell,跑两条命令开启功能:
PowerShelldism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
然后设WSL2为默认版本:
PowerShellwsl --set-default-version 2
重启一下电脑,这三步是WSL2的基础设置,搞过一次以后就不用再管了。
2. 用Docker拉CentOS 7镜像
确保本地Docker Desktop在跑,然后拉镜像:
Bashdocker pull centos:centos7
验证一下拉下来了没:
Bashdocker images
能看到 centos 那一行,TAG是 centos7,就说明OK了。镜像大概200MB,很小。
3. 启动容器并导出
先跑一下容器让它生成完整的rootfs:
Bashdocker run centos:centos7
容器会立刻退出(因为没给持续的进程),这是正常的。找到这个容器的ID:
Bashdocker ps -a
从输出里找到那个基于 centos:centos7 的容器,记下CONTAINER ID,然后导出为tar文件:
Bashdocker export <容器ID> > /tmp/centos7.tar
这个tar文件就是完整的CentOS 7文件系统,后面要喂给WSL。
4. 导入到WSL2
回到Windows的PowerShell,执行导入:
PowerShellwsl --import centos7 D:\dev\wsl\centos7 D:\dev\wsl\centos7.tar --version 2
这里三个参数的含义:
centos7:这个WSL实例起的名字,随便取D:\dev\wsl\centos7:WSL实例的存储路径,自己定D:\dev\wsl\centos7.tar:刚才导出的tar文件路径
验证是否导入成功:
PowerShellwsl -l -v
看到 centos7 出现在列表里,VERSION是2,就成了。
5. 进去试试
Bashwsl -d centos7
进去看一眼版本:
Bashcat /etc/centos-release
输出 CentOS Linux release 7.9.2009(具体版本号可能不同)——完事,一个干净的CentOS 7环境就在你手边了。
之后在本地用这个环境编译Go程序,编完直接扔到生产服务器上,glibc版本完全一致,跑不起来算我输。
四、方案二:第三方UI工具一键安装(偷懒版���
如果你觉得上面那堆命令太烦,还有更省事的办法。
Windows商店里有一些WSL管理工具,提供图形界面,点点鼠标就能导入各种Linux发行版。比如在商店里搜索"WSL"相关的管理器,有些支持直接导入自定义的tar包,有些内置了社区维护的CentOS等发行版镜像,选一下、点一下"安装"就完事了。

操作流程大概是:打开Windows商店 → 搜索WSL管理工具 → 安装 → 在软件里选择要导入的发行版(或选择本地的tar文件)→ 点"导入"或"安装" → 等几分钟就好了。整个过程不用碰命令行。
这个方案的好处是简单直观,适合不熟悉Docker、或者只是偶尔需要用一下的同学。坏处也有:
- 依赖第三方软件:商店里的工具质量参差不齐,有些更新不及时
- 灵活性差:想精确控制导入路径、磁盘配额这些参数,还是得回到命令行
- 镜像来源:内置的发行版镜像不一定是官方的,安全性需要自己判断
我的建议是:第一次走一遍手动流程,理解原理之后,日常用UI工具图个省事。 毕竟知道原理了,出问题才知道怎么排查。
五、日常使用技巧
装好了不等于完事,几个实用技巧:
定期备份。WSL实例搞坏了不用从头来,导一份完整的备份:
PowerShellwsl --export centos7 D:\backup\centos7-backup.tar
压缩虚拟磁盘。WSL2的虚拟磁盘文件(ext4.vhdx)只会涨不会缩,用久了占好几个G。先关掉WSL,再用diskpart压缩:
PowerShellwsl --shutdown diskpart # 在diskpart里: # select vdisk file="D:\dev\wsl\centos7\ext4.vhdx" # attach vdisk readonly # compact vdisk # detach vdisk
多发行版切换。wsl -d centos7 和 wsl -d Ubuntu 随时切换,互不影响。想设默认的话:
PowerShellwsl --set-default centos7
之后直接敲 wsl 就进CentOS 7。
不进去也能编译。这是我最常用的技巧——不用先 wsl 进去再切目录,直接在Windows的PowerShell里一行命令搞定。wsl 命令后面跟要在Linux里执行的命令就行:
PowerShellwsl -d centos7 -- bash -c "cd /mnt/d/projects/myapp && go build -o myapp"
这行的意思:用centos7这个实例,执行 cd 到项目目录(Windows的D盘在WSL里是 /mnt/d),然后编译。编完的 myapp 直接出现在Windows的目录里,拖到服务器上就完事。
如果你嫌每次敲 -d centos7 烦,前面设了默认发行版之后,直接:
PowerShellwsl -- bash -c "cd /mnt/d/projects/myapp && go build -o myapp"
甚至可以写成脚本或者Makefile的目标,一键编译+上传,完全不用离开Windows终端。这就是WSL2最大的好处:Linux是工具,不是环境,用完即走。
写在最后
说白了,这篇文的核心就一句话:当你需要在特定Linux环境里编译或测试,又不想搞虚拟机的时候,WSL2 + Docker镜像导入是最轻量的方案。
至于手动还是用UI工具,看你心情。我个人的路径是:先手动走一遍理解原理,之后嫌烦了就用UI工具。毕竟我们折腾这些,不是为了折腾本身,是为了早点干完活下班。
如果你也在Windows上开发、部署到CentOS 7,试试这个方案,比折腾交叉编译参数省心多了。
