前言
我们安装OpenWrt时如果只跑单个系统一般会选择物理机,这样最省资源,但这样就不能多开系统。多系统会选择虚拟机,但资源消耗相比其他占用比最大。或者Docker,Docker部署比物理机占用比高点,但是相比比虚拟机低很多了,但是我查找了一下有关教程,但大都只能设置为旁路由模式,但我又不用旁路由模式。后来在我接触PVE后才知道还有一种LXC容器部署方式,相比虚拟机最明显的就是,一般虚拟机启动至少得30秒左右才能启动完成,而lxc只需要5秒左右就可以完成启动,速度非常快。相比docker部署lxc容器部署资源占比更接近物理机。资源占用比:物理机<LXC<Docker<虚拟机。在我看来lxc部署程序实际就相当于安装一个软件,但系统文件和进程进行了隔离。既然LXC最省那就直接使用LXC,毕竟小主机性能是能省则省。因为我的需要是多系统,物理机自然是不行了,所以还是LXC。
环境
系统:PVE 8.0.3 内核:Linux 6.2.16-3-pve
准备
固件的选择
- tar.gz格式
如果你是自编译固件,可以选择生成“tar.gz”格式镜像,以x86平台为例,文件名一般会是:OpenWRT-x86-64-generic-rootfs.tar.gz,文件名中须包含“rootfs”。
- img格式
如果你不是自编译固件,我们在网站下载的一般是“img”格式的固件,一般格式会是OpenWRT-x86-64-generic-squashfs-rootfs.img或者OpenWRT-x86-64-generic-squashfs-combined.img亦或OpenWRT-x86-64-generic-ext4-rootfs.img这三种类型。
创建CT模板
PVE默认的模板路径为“/var/lib/vz/template/cache”,我们需要把模板上传到这个目录。
- tar.gz格式
tar.gz格式可以直接上传。
- img格式
第一种文件名带有squashfs-rootfs,这种需要使用squashfs-tools工具解压。首先安装squashfs-rootfs解包工具。
apt install squashfs-tools
解压img镜像。
unsquashfs OpenWRT-x86-64-generic-squashfs-rootfs.img
解压完成后你在同级目录下会得到squashfs-root文件夹,然后到squashfs-root文件夹打包解压后的文件到/var/lib/vz/template/cache目录。
tar zcf /var/lib/vz/template/cache/OpenWRT-x86-64-generic-rootfs.tar.gz ./*
第二种文件名不带rootfs,需要在PVE下通过挂载镜像,得到内部文件。
在PVE下开启nbd模块。
modprobe nbd
然后将img上传到pve,并挂载为设备。
qemu-nbd -c /dev/nbd0 -f raw OpenWRT-x86-64-generic-squashfs-combined.img
然后查看挂载。
lsblk -f /dev/nbd0
我们要挂载选择带有squashfs的分区。
然后创建一个要挂载的目录。
mkdir /mnt/openwrt
将带有squashfs的分区里的文件挂载到刚才创建的目录里。
mount /dev/nbd0p2 /mnt/openwrt
然后进入进入挂载的文件夹并将所有文件打包成tar.gz格式并放到模板目录里。
cd /mnt/openwrt
tar -czvf /var/lib/vz/template/cache/op.tar.gz *
然后退出挂载的openwrt文件夹,并卸载分区。
cd ..
umount /mnt/openwrt
最后卸载设备。
qemu-nbd -d /dev/nbd0
第三种是名称不带squashfs,而有ext4的img文件,例如:OpenWRT-x86-64-generic-ext4-rootfs.img,将img上传到pve里,然后挂载镜像至/mnt/openwrt。
mount -t ext4 -o loop OpenWRT-x86-64-generic-ext4-rootfs.img /mnt/openwrt
然后进入挂载后的文件夹将所有文件打包到/var/lib/vz/template/cache目录。
tar zcf /var/lib/vz/template/cache/OpenWRT-x86-64-generic-rootfs.tar.gz ./*
创建容器
PVE下执行以下命令创建容器。
pct create 100 local:vztmpl/openwrt-x86-64-generic-rootfs.tar.gz --rootfs local-lvm:5 --ostype unmanaged --hostname openwrt --arch amd64 --cores 2 --memory 1024 --swap 0 -net0 bridge=vmbr0,name=eth0
命令解释。
pct create | 创建容器命令 |
100 | 容器ID,可根据自己情况设定 |
local:vztmpl/OpenWRT-x86-64-generic-rootfs.tar.gz | 为上传到/var/lib/vz/template/cache目录的固件包名称 |
--rootfs | 模版为rootfs文件 |
local-lvm:1 | 后面的数字代表分配的磁盘大小,单位为:GB。比如我这里设置的为1,即为即将创建的容器分配1G的大小 |
--ostype unmanaged | 操作系统类型,好像只能填unmanaged,填别的会错误。因为pve官方没有完全适配OpenWRT,所以不能填写其他。 |
--hostname OpenWRT | 主机名,也就是容器的名称 |
--arch amd64 | 架构 |
--cores 2 | 分配给容器的核心数 |
--memory 1024 | 分配给容器最大的内存数量 |
--swap 0 | 交换分区设置为0 |
-net0 bridge=vmbr0,name=eth0 | 网卡,这里的意思是分配给容器OpenWRT名称为net0的网络,bridge至vmbr0虚拟接口,匹配OpenWRT的eth0接口。这里一般不要动,就这样设置! |
然后配置OpenWRT,将以下内容添加到/etc/pve/lxc/100.conf。
features: keyctl=1,mknod=1,nesting=1
hookscript: local:snippets/hookscript.pl
lxc.apparmor.profile: unconfined
lxc.include: /usr/share/lxc/config/openwrt.common.conf
lxc.cgroup2.devices.allow: a
lxc.cap.drop:
lxc.mount.auto: proc:mixed sys:ro cgroup:mixed
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
lxc.mount.entry: /dev/ppp dev/ppp none bind,create=file
#虚拟网口
# net1: name=eth1,bridge=vmbr1,hwaddr=00:11:22:33:44:1B,type=veth
# net2: name=eth2,bridge=vmbr2,hwaddr=00:11:22:33:44:2A,type=veth
# net3: name=eth3,bridge=vmbr3,hwaddr=00:11:22:33:44:2B,type=veth
#直通网口
lxc.net.1.type: phys
lxc.net.1.link: enp3s0
lxc.net.1.flags: up
lxc.net.2.type: phys
lxc.net.2.link: enp4s0
lxc.net.2.flags: up
lxc.net.3.type: phys
lxc.net.3.link: enp5s0
lxc.net.3.flags: up
hwaddr MAC地址 也可以不设置,不设置自动分配
type: phys 直通模式
type=veth 虚拟模式
flags: up 启用
这里的配置网口一定要根据自己的pve网络配置来配置,下图是我的PVE网络设备配置,在这个图中可以看到对应关系:enp*s0代表物理网口名称,vmbr*代表虚拟接口,LinuxBridge代表连接方式。
因为我们创建时已经将vmbr0分配给了OpenWrt容器网络net0,还有三个口,所以我们还需要将他们三个分配给openwrt,然后按照对应关系分配即可。
创建拨号的文件链接
创建snippets文件夹
mkdir /var/lib/vz/snippets
复制hookscript.pl配置文件
cp /usr/share/pve-docs/examples/guest-example-hookscript.pl /var/lib/vz/snippets/hookscript.pl
编辑hookscript.pl
vi /var/lib/vz/snippets/hookscript.pl
在第36行可以找到以下内容
# Second phase 'post-start' will be executed after the guest
# successfully started.
print "$vmid started successfully.\n";
修改为
# Second phase 'post-start' will be executed after the guest
# successfully started.
system("lxc-device add -n $vmid /dev/ppp");
system("lxc-device add -n $vmid /dev/net/tun");
print "$vmid started successfully.\n";
最后在pve控制台启动openwrt
配置OpenWrt
然后配置LAN口,这样就能除了WAN口任何一个口都能访问PVE后台了。