问题来源
N5105 软路由准备安装docker,但是提示空间不够。系统安装在128G
硬盘上,闲置空间没有利用起来。
环境:
- 安装镜像:
immortalwrt-24.10.2-x86-64-generic-squashfs-combined-efi.img.gz
- ROM:128G
- RAM:8G
一、官方镜像分区表结构
启动后可以看到如下 GPT 分区(128 GB 盘为例):
分区 | 大小 | 文件系统 | 作用 |
---|---|---|---|
/dev/sda1 | 32 MB | FAT32 | EFI/GRUB + kernel(只读) |
/dev/sda2 | ≈ 300 MB | SquashFS | 真正的固件(只读) |
/dev/sda128 | 239 KB | - | BIOS boot 用,可忽略 |
剩余空间 | 127 GB+ | 未分区 | 待扩容 |
根目录 /
实际通过 overlay 把 sda2 里的一个环回文件 rootfs_data 挂载成可写层,所以 df -h
只会看到 200~300 MB 可用空间,这就是需要扩容的地方。
二、需要扩容的目标
唯一需要扩容的是 overlay 可写层我们进行在线扩容(推荐,不用拔盘): 把剩余空间新建一个 ext4 分区 → 拷旧 /overlay → 改 fstab → 重启,最安全,官方 squashfs 也能升级不丢数据。
overlay 做大的直接好处就是可以装Dokcer/Podman、缓存什么的;大 overlay 的副作用就是sysupgrade
升级固件时,官方脚本不会自动迁移整个 /overlay
,你得手动备份/还原。
三、在线扩容实操
装工具
1 2
opkg update opkg install cfdisk e2fsprogs blkid
创建新分区(示例把剩余 127 GB 全用)
1 2
cfdisk /dev/nvme0n1 # 选中 Free space → New → Write → quit
这write完成的,检查一下容量,记住Device名称
nvme0n1p3
,后边执行命令别用错了。1 2
# 新建 /dev/nvme0n1p3 占剩余全部空间 mkfs.ext4 -L data /dev/nvme0n1p3
挂载点规划
- /overlay 需要 30 GB 左右放软件、配置
- /mnt/docker 留 80 GB+ 给镜像、卷 一次把 118.9 GB 分成两段最省事:
1 2 3 4 5 6
mkdir -p /mnt/data mount /dev/nvme0n1p4 /mnt/data # 在 /mnt/data 里创建两个子目录,既能当 overlay 又能当 docker 根目录 mkdir -p /mnt/data/overlay /mnt/data/docker
开机自动挂载 & 指向
编辑
/etc/config/fstab
追加两行:config mount option device '/dev/nvme0n1p3' option target '/mnt/data' option fstype 'ext4' option options 'rw,noatime' option enabled '1' config mount option device '/dev/nvme0n1p3' option target '/overlay' option options 'rw,noatime' option enabled '1'
重启生效:
1 2
reboot df -h # 应该看到 /overlay 已变成 100+ GB
四、Docker指向修改
Docker默认使用的opt/data
做的数据根目录,我们上边给他分了数据目录/mnt/data/docker
,现在要指向它。
配置数据指向
1 2 3 4 5 6 7 8 9
mkdir -p /etc/docker cat > /etc/docker/daemon.json <<EOF { "data-root": "/mnt/data/docker", "log-driver": "json-file", "log-opts": {"max-size": "10m", "max-file": "3"} } EOF
安装docker
1 2
opkg update opkg install docker dockerd
启动并开机自启
1 2
/etc/init.d/dockerd enable /etc/init.d/dockerd start
验证
1
docker info | grep "Docker Root Dir" # 应输出 /overlay/docker
⚠️不出意外的话这里就出意外了,你大概率会看到如下输出信息:
1 2 3
root@ImmortalWrt:~# docker info | grep "Docker Root Dir" WARNING: No swap limit support Docker Root Dir: /opt/docker
没错,就是没变。这是因为
/etc/init.d/dockerd
里有顽固的硬编码。好像是116行附近config_get data_root globals data_root "/opt/docker/"
,脚本优先使用 UCI 配置里的data_root
值,默认就是/opt/docker/
,所以/etc/docker/daemon.json
被完全忽略。用 UCI 把路径改掉
1 2
uci set dockerd.globals.data_root='/overlay/docker' uci commit dockerd
重启Docker
1
/etc/init.d/dockerd restart
再次验证
1 2
docker info | grep "Docker Root Dir" # 应该输出:Docker Root Dir: /overlay/docker