OpenWrt上运行LXC容器

什么是LXC,为什么选LXC?

LXC简介

在开始之前我们先来介绍一下什么是LXC。

LXC的是Linux容器Linux Containers的缩写,是一种操作系统级虚拟化技术。允许在 Linux 主机上创建和管理多个独立的容器。每个容器都可以运行一个完整的 Linux 系统,包括其自己的进程空间、网络空间、文件系统以及用户空间。

LXC 提供了一个轻量级的虚拟化解决方案,与传统的虚拟机相比,它更加高效,因为容器共享主机操作系统的内核,减少了资源占用和启动时间。

LXC 允许用户在单个物理主机上运行多个容器,每个容器可以独立配置,就像一个独立的虚拟机一样。它们可以用于隔离应用程序、测试环境、开发环境等,提供了更好的资源利用率和更快的部署速度。

LXC vs. 传统虚拟机 vs. Docker

说到虚拟化技术,大家一定首先想到的是虚拟机或者Docker,那LXC相较于这两者有什么区别和优势呢,我们可以从以下几个方面来进行对比说明:

对比项 传统虚拟机 LXC容器 Docker容器
资源占用 每个虚拟机都包含完整的操作系统,资源占用较多。 容器共享主机操作系统的内核,资源占用较少,更轻量级。 Docker 利用层级文件系统和容器镜像,资源占用相对较少。
性能损耗 由于每个虚拟机都运行自己的内核,因此可能会有较大的性能损失,尤其是在 I/O 和网络访问方面。 由于它们共享宿主机的内核,因此性能损失较小,尤其在 I/O 和网络访问方面。 由于它们共享宿主机的内核,因此性能损失较小,尤其在 I/O 和网络访问方面。
隔离性 每个虚拟机拥有独立的内核和资源,提供较高的隔离性。 虽然容器之间相互隔离,但共享主机内核,隔离性稍弱。 Docker 使用 Linux 内核的命名空间和控制组实现隔离,提供较好的隔离性。
部署方式和生态系统 部署相对独立,通常需要使用虚拟机镜像。 支持容器镜像和注册表,但生态系统相对较小。 Docker 提供了强大的容器镜像和注册表,具有完善的生态系统和易用性。
启动时间 需要较长时间来启动,通常需要几分钟。 由于共享内核,启动速度更快,通常在几秒钟内完成。 Docker 容器启动速度也非常快,与 LXC 相当。
数据持久化 数据通常持久化在虚拟硬盘中,这可以确保数据的持久性和安全性。 容器本身是短暂的,当容器被删除时,容器中的数据也会一并丢失。因此,为了持久化数据,通常需要将数据卷挂载到容器内部或使用其他持久化解决方案。 容器本身是短暂的,当容器被删除时,容器中的数据也会一并丢失。因此,为了持久化数据,通常需要将数据卷挂载到容器内部或使用其他持久化解决方案。
适用场景 适用于需要完全隔离和独立操作系统的场景。 适用于对资源消耗和性能要求较高的场景,以及需要轻量级虚拟化的环境。 适用于构建、部署和运行分布式应用程序,以及需要快速迭代和扩展的场景。

综上所述,LXC 提供了介于传统虚拟机和 Docker 之间的轻量级虚拟化解决方案。在资源消耗和性能方面有较高要求的情况下,LXC 可能是更好的选择。而对于需要快速部署、迭代和扩展的应用程序,则 Docker 提供了更加便捷的解决方案。

LXC 通常可与其他工具(例如 LXD,可以理解LXD 是 LXC 的一个高级管理工具和 API)结合使用,以提供更高级的容器管理功能,如容器镜像、快照、集群管理等,因本文只是在OpenWrt上安装使用LXC,没有太过复杂高级的需要,所以就不介绍LXD了。

为什么是LXC

首先因为是在OpenWrt上运行,所以资源利用率和性能是首选,由此阿七首先就排除了传统虚拟机。

然后从容器的完整性(Docker是进程级的虚拟化)和安全性(当OpenWrt作为主路由或者DMZ主机时,Docker如果配置不恰当很容易导致端口暴露)两个方面考虑,阿七推荐使用LXC,可玩性更高。

LXC能干啥?

这是个好问题!LXC最大的好处就是隔离性,阿七主要从以下两个方面考虑:

功能隔离,保证网络稳定

不管OpenWrt是作为主路由还是旁路由,那么他都会或多或少的影响你的网络,所以我们首要任务是要保证OpenWrt的稳定性,较低的维护难度,但是大家往往又忍不住在OpenWrt安装配置各种插件,如果技术不够硬,很容易一失手成键盘跪,哦。。不。。是千古恨。

所以网络稳定性和大家日益严重的电子插件仓鼠综合症之间的矛盾变得越来越难调和,但并不是不可调和,而LXC的隔离特性就不失为一剂良方。将除基本网络之外的插件安排进LXC容器,那么当插件崩溃时将不会影响做为母机的OpenWrt,从而保证网络的稳定性。

统计隔离,精细化统计、降低全局影响
OpenWrt有很多流量类插件,但基本都不原生支持流量统计,需要依赖其他的统计插件,那么问题就来了,如果有多种流量需要分开统计呢。嗯。。。统计插件就无能为力了,这时LXC就可以派上用场了。

用一句话概括就是分而治之。

前置准备工作

OpenWrt母机

嗯。。安装前。。因为是在OpenWrt是套娃,所以我们首先得有个已经能正常运行的OpenWrt。

挂载LXC分区

这个操作不是必须的,默认情况下,lxc会将容器存放在/srv/lxc/下,一般一个容器几百兆左右,所以如果空间够大,也可默认不处理即可。

不过我们使用LXC的目的就是为了隔离,可以最好能将LXC容器与母机存储隔离开,比如我们可以把其他磁盘挂载到/srv/目录,这样后续如果母机要重新刷机,只要刷好机重新挂载目录,之前所有的LXC容器就又回来了,而不用担心母机刷新而丢失LXC容器及数据。

安装LXC

废话就不多说了,我们现在就进入主题,登录OpenWrt Web管理界面,打开ttyd网页终端并登录:

安装LXC所需组件

按照以下顺序将命令复制到网页终端后回车执行,有时可能因为网络问题会失败,多重试。

更新依赖

opkg update

安装依赖工具

opkg install xz tar liblzma gnupg

安装kernel模块

opkg install kmod-ikconfig kmod-veth

安装cgroups工具

opkg install cgroupfs-mount cgroup-tools

安装LXC组件

opkg install liblxc luci-i18n-lxc-zh-cn luci-app-lxc lxc lxc-attach lxc-auto lxc-autostart lxc-cgroup lxc-checkconfig getopt \
lxc-common lxc-config lxc-configs lxc-console lxc-copy lxc-create lxc-destroy lxc-device lxc-execute \
lxc-freeze lxc-hooks lxc-info lxc-init lxc-ls lxc-monitor lxc-monitord lxc-snapshot lxc-start lxc-stop \
lxc-templates lxc-top lxc-unfreeze lxc-unprivileged lxc-unshare lxc-user-nic lxc-usernsexec lxc-wait rpcd-mod-lxc

验证安装结果

安装完成后需要重新启动下OpenWrt以便于自动挂载一些组件,重启后通过以下方式验证是否安装成功。

菜单

如果上述命令都正确无误的执行了,那么刷新页面后,我们在服务菜单下应该可以看到LXC容器子菜单

v2-2ad5953e22cb4810a011f7cb51eeed52_1440w

命令检测

在网页终端输入命令检测支持状态:

lxc-checkconfig

v2-09dc27b71b4b054c58a15e0c281e8691_1440w

从结果我们可以看到,目前OpenWrt23上的LXC支持到5.0.3版本,大部分检查项目都是Enable(即支持),仅有少数是missing(即不支持),不用担心,常规使用这些基本都够了,要支持那些mission项目基本都要自定义编译OpenWrt固件,对小白不太友好。

如果要搞嵌套虚拟化,就得自编译固件了。

安装容器

通过界面安装

我们一般通过LXC管理界面就可以通过选择不同的模板安装相应的容器:

v2-89690b37f5fcd3419debd8d0f44f6bcb_1440w

注意:这里需要钩选启用SSL,否则不会出现模板列表。

如果界面上模板列表没有列出来的话,可以多等等,有可能是网络原因。当然低版本的OpenWrt因为LXC Bug也是可能无法展示列表的,这种情况下也可以采用命令行安装。

通过命令行安装
除了界面安装外,我们也可以通过命令行安装LXC容器,命令格式如下:

lxc-create –name 自定义容器名称 –template download — –dist 要安装的操作系统 –release 要安装的操作系统发行版本 –arch 系统架构
比如我要在x86 64位的OpenWrt上安装OpenWrt 23.05,命令行如下:

lxc-create –name openwrt2305test –template download — –dist openwrt –release 23.05 –arch amd64

配置容器

通过LXC管理界面,可以看到LXC的配置文件:

v2-9b68dcb73b5722c454b42253786f5bfe_1440w

LXC容器菜单

v2-04ca0af5efda0efcf2c4e2c58246400d_1440w

LXC容器配置文件内容

从界面上看貌似可以修改配置,但很遗憾,目前阿七装过多个版本都未能成功从界面上修改配置,会报ActionFailed。如果有小伙伴找到原因,还烦请告诉阿七一下。

界面操作不行那我们就只能从命令行下手了,前面说到LXC安装的容器,默认存放在/srv/lxc目录下,如果你正确安装了容器后,将在该目录下看到与容器名称对应的目录:

v2-25ba707a8f52961264779c95e825cd30_1440w

容器安装目录

在每个容器目录下都有一个config目录,我们编辑这个config目录并保存即可:

v2-5aa7dcb9c09ef31446c58d0d9e00cab0_1440w

编辑配置文件

网络配置

做为最基础的尝试,我们只需要将配置文件中的lxcbr0改为br-lan保存即可。

v2-328f47950a1e791adef6f8f8c253cfb7_1440w

也可以直接修改LXC的默认模板配置文件/etc/lxc/default.conf文件中的网卡配置lxc.net.0.link = br-lan,这样所有新建的LXC容器网卡都会配置为lxc.net.0.link = br-lan

保存配置文件后,我们就可以通过界面对容器进行启动、停止、重启等操作,目前非自编译固件是不是支持冻结操作的,还记得前面安装结果检测里面那个红色的mission吗?

v2-c00b912bdd8c19a58b140fe3f40058b6_1440w

lXC容器操作菜单

资源限制
一般来说LXC容器对资源的利用率是极高的,但也难免有对容器资源限制的需求,此时我们只需要在配置文件加入相应命令即可:

# Source limits
lxc.cgroup.cpuset.cpus=1,3
lxc.cgroup.memory.soft_limit_in_bytes=192M
lxc.cgroup.memory.limit_in_bytes=256M

自动启动

到这里,你安装的容器应该都能正常启动了,如果是安装的OpenWrt的容器,应该也可以通过其分配到的IP地址访问到Web管理界面了。

但我想大家都不愿意每次母机重启后都要手工把容器启动一遍吧,说好的简化运维呢。。。?

此时我们需要简单的几行命令即可设置容器自动启动,其中openwrt2305test为你的容器名称,30秒是延迟(在母机启动好后多久启动容器)。

uci show lxc-auto
uci add lxc-auto container
uci set lxc-auto.@container[-1].name=openwrt2305test
uci set lxc-auto.@container[-1].timeout=30
uci show lxc-auto
uci commit lxc-auto

常用命令

很多小伙伴会说,如果安装的是OpenWrt这样自带管理界面的,已经可以通过IP访问到管理界面了,那如果我安装的是Debian这种没有界面的呢,咋整呢?

莫方,常用运维命令给大家准备好了:

#启动容器,在母机上执行
lxc-start 容器名

#附加容器,在母机上执行,执行完后会进入容器命令行
lxc-attach 容器名

#在容器内执行,执行完成后会退出容器并回到母机,容器会继续运行
exit

#在容器内执行,执行完成后会退出容器并回到母机,容器会重启,若要再次进入容器需要重新执行lxc-attach命令
reboot

#停止容器,在母机上执行
lxc-stop 容器名

#列出所有容器,在母机上执行
lxc-ls

#列出所有的资源开销
lxc-top

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注