1. 为什么还要折腾 Ubuntu 16.04 这个老版本
先把话说在前头:Ubuntu 16.04 在 2021 年 4 月就已经结束标准支持了,官方源早就挪进了 old-releases 仓库。现在还在碰这个版本的人,基本不是图新鲜,而是被现实逼的——手头有个老项目只能在 16.04 上跑,某个编译工具链只认这个版本的 glibc,或者团队里那套祖传构建脚本换系统就炸。我自己就遇到过好几次,客户丢过来一个压缩包,里面全是 2017 年前后的依赖,装到 20.04 上各种报错,最后老老实实退回 16.04。
所以这篇东西不是教你“怎么装最新系统”,而是解决一个很具体的场景:在 Windows 的 WSL 子系统里,把 Ubuntu 16.04 跑起来,并且能正常联网、换源、装软件。适合谁看?手上有老项目要维护的开发者、需要复现历史构建环境的同学、以及想拿 WSL 当轻量级 Linux 沙箱但被版本卡住的人。整个过程不需要虚拟机,不需要双系统,开个终端就能干活。
WSL 这块要分清楚,微软现在有两代:WSL1 是系统调用翻译层,WSL2 是跑在轻量虚拟机里的真内核。Ubuntu 16.04 这个老发行版,只适合装在 WSL1 上,WSL2 对它的支持很别扭,后面会细说。另外微软商店里早就下架了 16.04 的官方镜像,得走手动导入的路子。下面我按实际操作的顺序,把每一步的坑和理由都讲清楚。
2. 装之前的整体思路和方案选型
2.1 为什么不用商店直接装
微软商店(Microsoft Store)里现在能直接搜到的 Ubuntu 版本,最低也是 18.04 起步,16.04 的官方 appx 包在 2020 年前后就陆续下架了。你可能会想,那我去网上找个 appx 包双击安装不就行了?实测下来这条路现在很难走通,原因是商店安装机制会校验签名和来源,老包在新版 Windows 上经常报“无法安装此应用”或者装完启动直接闪退。
更稳的做法是手动导入 rootfs 文件系统。所谓 rootfs,就是一个打包好的 Linux 根文件系统压缩包,WSL 拿到它之后解压到指定目录,注册成一个可启动的发行版。这个方式绕开了商店,也不依赖 appx 签名,可控性最高。微软官方其实也提供了 Ubuntu 16.04 的 rootfs 下载,只是藏得比较深,不在商店页面上。
2.2 WSL1 和 WSL2 到底选哪个
这里必须掰扯清楚,因为选错了后面全是坑。
| 对比项 | WSL1 | WSL2 |
|---|---|---|
| 内核 | 无独立内核,系统调用翻译 | 真 Linux 内核(虚拟机) |
| 对老发行版兼容 | 好,16.04 能正常跑 | 差,16.04 常出网络和启动问题 |
| 文件系统性能 | 跨系统访问快 | 跨系统访问慢,Linux 内部快 |
| 网络 | 直接共享主机网络 | 独立虚拟网卡,需端口转发 |
| 内存占用 | 低 | 较高 |
结论很直接:装 Ubuntu 16.04,用 WSL1。WSL2 的内核版本比较新,16.04 里那套老的 init 系统和网络配置脚本跟它配合得不好,典型症状是启动后没有网络、systemd 相关服务起不来。WSL1 虽然性能上不是最强,但对这种老系统的兼容性反而最好,装完基本开箱能用。
2.3 前置条件检查
动手之前先确认几件事,省得白忙活:
- Windows 10 版本号至少 1709 以上(WSL1 的最低要求),建议 1903 以上更稳。按
Win + R输入winver就能看。 - 已经开启了“适用于 Linux 的 Windows 子系统”这个可选功能。没开的话,在“控制面板 → 程序 → 启用或关闭 Windows 功能”里勾上,重启生效。
- 磁盘留出至少 5GB 空间,rootfs 解压后加上后续装软件,占用会慢慢涨。
- 有个能解压 tar.gz 的工具,7-Zip 或者系统自带的 tar 命令都行。
提示:如果你之前装过别的 WSL 发行版,不影响,多个发行版可以共存,各自独立。但导入前最好确认目标目录是空的,避免文件冲突。
3. 核心细节:rootfs 获取与导入的实操要点
3.1 拿到 Ubuntu 16.04 的 rootfs
rootfs 文件一般叫ubuntu-base-16.04.x-base-amd64.tar.gz这种名字,是官方发布的精简根文件系统。获取渠道有两个方向:一是从官方镜像站的历史归档里找,二是用第三方整理好的 WSL 专用包。我建议优先找官方 base 包,干净、体积小(大概 30MB 出头),没有多余的东西。
拿到手之后先别急着导入,校验一下文件完整性。老包在下载过程中容易损坏,导入时报“解压失败”十有八九是包坏了。用certutil -hashfile 文件名 SHA256算一下哈希,跟来源页面给的对比。这一步很多人跳过,结果卡在导入环节反复试,浪费时间。
3.2 导入命令的每个参数都要搞懂
导入用的是wsl --import命令,格式是这样:
wsl --import <发行版名称> <安装目录> <rootfs文件路径> --version 1逐个拆解:
<发行版名称>:你自己起的名字,比如Ubuntu-16.04。这个名字后面启动、卸载都要用,起个认得出的。<安装目录>:解压后文件系统放哪。建议放在非系统盘,比如D:\wsl\ubuntu1604,路径里不要有中文和空格,否则容易出幺蛾子。<rootfs文件路径>:就是刚下载的那个 tar.gz 的完整路径。--version 1:强制用 WSL1。这个参数很关键,不加的话新版 Windows 可能默认按 WSL2 导入,那就掉坑里了。
一个实际的例子:
wsl --import Ubuntu-16.04 D:\wsl\ubuntu1604 D:\downloads\ubuntu-base-16.04.6-base-amd64.tar.gz --version 1执行完没有任何报错,就说明导入成功了。可以用wsl -l -v查看列表,确认版本那列显示的是 1。
3.3 首次启动和用户设置
导入后的发行版默认用 root 登录,这跟商店装的体验不一样(商店装完会让你设用户名密码)。直接wsl -d Ubuntu-16.04进去,你会发现提示符是#,说明是 root。
长期用 root 不是个好习惯,建议建个普通用户:
adduser yourname usermod -aG sudo yourname然后设置默认登录用户。WSL 这边改默认用户稍微绕一点,需要在/etc/wsl.conf里配置:
[user] default=yourname写完保存,退出 WSL,用wsl --terminate Ubuntu-16.04关掉再重进,就生效了。
注意:
/etc/wsl.conf这个文件默认可能不存在,直接新建就行。改完必须 terminate 重启,光退出终端不生效,这是很多人改了没反应的原因。
4. 换源与联网:老系统最容易翻车的地方
4.1 官方源失效的真相
Ubuntu 16.04 的标准支持结束后,官方把它的软件包从主镜像站移到了old-releases.ubuntu.com。你如果还用默认的archive.ubuntu.com,执行apt update会大量报 404,提示找不到 Release 文件。这不是网络问题,是源地址变了。
所以第一件事就是换源。编辑/etc/apt/sources.list,把里面所有archive.ubuntu.com和security.ubuntu.com替换成old-releases.ubuntu.com。可以用 sed 一把梭:
sudo sed -i 's/archive.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list sudo sed -i 's/security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list改完执行sudo apt update,如果能看到一堆Get和Hit,没有大面积 404,就说明源通了。
4.2 国内镜像源还能不能用
有人会想,那我换成国内镜像是不是更快?这里要泼盆冷水:大部分国内镜像站早就把 16.04 的包删了,因为它们只保留还在支持期内的版本。你换成某国内源,大概率还是 404。少数镜像站保留了 old-releases 的同步,但速度优势不明显,而且稳定性看运气。
我的建议是:直接用 old-releases 官方源,虽然服务器在国外,但 WSL1 走的是主机网络,速度取决于你本机的网络环境,一般够用。真要加速,可以试试那些明确标注保留历史版本的镜像,但换之前先apt update测一下,别盲目改。
4.3 DNS 和网络排查
WSL1 的网络是共享主机网络的,正常情况下不需要额外配置。但如果你apt update报“无法解析域名”,那就是 DNS 的问题。检查/etc/resolv.conf,里面应该有类似nameserver 8.8.8.8或者主机 DNS 的条目。
如果这个文件是空的或者不对,可以手动写一个:
sudo sh -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'但要注意,WSL 有时会自动覆盖这个文件。想让它别乱改,可以在/etc/wsl.conf里加:
[network] generateResolvConf = false然后再手动维护 resolv.conf。这个配置在 WSL1 上效果比较稳定。
提示:改完网络配置同样要 terminate 重启 WSL 才生效。排查网络问题的顺序是:先 ping 网关,再 ping 外网 IP,最后 ping 域名,一层层定位是路由问题还是 DNS 问题。
5. 装完之后的常用配置和工具补齐
5.1 基础开发环境搭建
系统跑起来、源换好之后,就可以装东西了。16.04 自带的软件版本都比较老,装的时候心里要有数。常用的几样:
sudo apt install -y build-essential git curl vim python3 python3-pipbuild-essential是编译工具链,gcc、make 这些都在里面,老项目编译基本都要它。git 和 curl 不用多说。python3 在 16.04 里是 3.5 版本,比较老,如果项目需要更高版本,得自己编译或者用第三方源,这个后面单独说。
装完验证一下:
gcc --version python3 --version5.2 时区和语言环境
新导入的系统时区默认可能是 UTC,跟本地时间对不上,看日志很别扭。设置成东八区:
sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime语言环境如果没配好,终端里中文可能显示成乱码。装一下语言包:
sudo apt install -y language-pack-zh-hans然后在~/.bashrc里加上export LANG=zh_CN.UTF-8,重新加载配置。不过说实话,服务器环境我一般保持英文,避免各种编码问题,这个看个人习惯。
5.3 和 Windows 互访文件
WSL1 的一个大优势就是文件系统互通。Windows 的盘符挂载在/mnt/下面,比如 C 盘是/mnt/c,D 盘是/mnt/d。你在 Linux 里可以直接访问 Windows 文件:
cd /mnt/d/projects ls反过来,在 Windows 资源管理器地址栏输入\\wsl$\Ubuntu-16.04\home\yourname就能访问 Linux 里的文件。这个互访能力在 WSL1 上性能很好,几乎感觉不到跨系统,这也是我坚持用 WSL1 跑老系统的原因之一。
注意:在
/mnt/下操作文件时,权限位可能不太准,因为 NTFS 和 Linux 权限模型不一样。如果项目对文件权限敏感,建议把代码放在 Linux 自己的文件系统里(比如/home/yourname/),别放/mnt/下。
6. 常见问题排查速查表
实际折腾下来,问题就那么几类,整理成表方便对照:
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 导入报“解压失败” | rootfs 包损坏 | 重新下载并校验哈希 |
| 启动后无网络 | DNS 未配置或 WSL2 误用 | 检查 resolv.conf,确认用 WSL1 |
| apt update 大量 404 | 源地址未换成 old-releases | 替换 sources.list 里的域名 |
| 改 wsl.conf 不生效 | 没 terminate 重启 | 执行 wsl --terminate 后重进 |
| 中文显示乱码 | 缺语言包或 LANG 未设 | 装 language-pack 并设 LANG |
| 默认用户还是 root | wsl.conf 配置未生效 | 确认文件路径和格式,重启 WSL |
| 磁盘占用越来越大 | 日志和缓存堆积 | 定期 apt clean,清理 /var/log |
再补充几个我踩过的坑。有一次导入完死活启动不了,报一个很模糊的错误,最后发现是安装目录路径里带了个空格,改成纯英文无空格路径就好了。还有一次 apt 一直超时,折腾半天发现是主机上某个安全软件拦了 WSL 的网络请求,关掉就正常了。这类问题没有通用解,只能靠排除法。
另外,别在 16.04 上装太新的软件。有些第三方源提供的包依赖新版 glibc,装上去会把系统搞崩。老系统就老老实实用它自带的版本,或者自己从源码编译,别图省事乱加源。
7. 我个人的几点实操体会
折腾这套东西的次数多了,慢慢就摸出一些门道。首先,rootfs 包一定要留个备份,放在一个固定的地方。因为 WSL 用久了难免出问题,重装的时候如果有现成的包,几分钟就能恢复,不用重新去找下载链接。我一般会把包和导入命令写成一个批处理脚本,需要的时候双击就跑,省得每次敲命令。
其次,给每个老项目单独建一个 WSL 发行版。别把所有东西都塞进一个 16.04 里,项目之间依赖冲突的时候你会想哭。WSL 支持导入多个实例,各自独立,互不干扰,磁盘占用也没想象中那么大。用完wsl --unregister就能干净卸载,不留垃圾。
最后说个容易被忽略的点:WSL1 的内存和 CPU 是动态共享主机的,不像 WSL2 有独立配额。跑编译任务的时候,如果主机内存吃紧,WSL 里的进程可能被系统干掉。所以编译大项目之前,先看看主机内存够不够,别一边开着虚拟机一边编译,那样容易出玄学问题。
这套流程我前后在好几台机器上复现过,只要按步骤来,基本一次成功。真正花时间的不是安装本身,而是换源和网络那几步,把这两块搞定了,剩下的就是正常用 Linux 的体验。老系统有老系统的麻烦,但把它关在 WSL 这个沙箱里,既不影响主机,又能满足项目需求,算是目前比较省心的方案了。