利用容器技术在一个宿主机上运行OpenWrt(LEDE)
文章目录
在阅读本文之前,可以先了解下另外一篇文章容器核心技术详解。
容器技术所用到的技术主要是Linux Namespace和cgroup,目前最成功的方案就是Docker,我们也来试着利用Linux kernel的 Namespace来简单实现docker的部分功能,这里称之为假Docker。
本文相关的代码在这里 fake_docker,文章中对于比较长的代码会省略,可以在代码仓库中查看。
本文目标
实现在Ubuntu服务器上运行路由器系统lede/openwrt的包管理程序opkg,并进行软件安装、卸载操作。至于说路由器的其它功能,并没有实现,一个原因是需要的配置比较麻烦,我们的假Docker过于简单,不能满足要求,但是在另外一篇文章在树莓派上用Docker运行LEDE(OpenWrt)会尝试运行一个可用的lede系统。
启动一个LEDE Bash
用opkg安装软件
如何做
在知道docker原理的前提下,要想实现本文的目标,步骤就比较清晰了。
- 首先是找到lede系统的rootfs,也就是一个完整的lede系统的根目录结构和文件。
- 接着通过Linux Namespace各种特性,启动一个隔离的子进程
- 利用Network Namespace来为隔离子进程提供网络访问件。
- 这个隔离的子进程运行lede系统中的bin文件opkg
- 目的达成!!!
获取LEDE的rootfs
因为实验用的服务器是x86构架的CPU,所以我们选用的rootfs也该是x86,直接从lede仓库中就可以获得 lede-17.01.2-x86-generic-generic-rootfs.tar.gz
tar xvf
解压获得rootfs文件夹。另外github目录中已经存在fake_docker/rootfs
编译代码并设置capability
编译代码并设置可执行文件的capability
|
|
关于 Linux capability: 在使用user namespace时需要来做uid和did的映射,即将容器中的某个用户映射为宿主机的某个用户,因为容器中很多情况是需要root权限的,但是如果使用宿主机的root用户来执行,风险非常高,但是我们讲宿主机的普通用户应成为容器中的root用户,这样容器对容器内的所有操作有root权限,但是并不会对宿主产生超过普通用户权限的影响。
启动一个隔离的子进程
执行./fake_docker
进入容器,可以看到相关输出信息,执行该命令的uid,gid都是500,容器中的都是0,大家知道uid=0意味着是root用户。
|
|
配置网络
- 新开一个终端,处于宿主机环境下,执行代码中的脚本
sudo ./host_net.sh 13946
,脚本后的参数是容器进程在宿主机下真实pid。此时在宿主机新建了一个veth0的虚拟网卡并新建了一个peer的veth0.1,并将veth0.1按入容器的Namespace中。 - 将代码中的inner_net.sh复制到rootfs文件夹
- 返回已经进入容器的终端,执行
inner_net.sh
,这时初始化了按入容器的网卡veth0.1,并改为名字eth0。还有DNS服务器的配置,opkg的初始化。 - 宿主机设置NAT网络转发,讲veth0通过宿主机的eth0转发出去。网络结构: 容器eth0 <—peer—> 宿主veth0 <—NAT Forward—> 宿主eth0 <—> internet
此时我们可以通过ping命令检查网络是否正常,然后 opkg update & opkg install curl && curl www.baidu.com