LWN:使用loopfs来把loop设备变成容器私有的!

LoopFS是一个新提出的虚拟文件系统,旨在解决容器环境中Loop设备共享带来的安全和隔离性问题。通过创建独立的Loop设备实例,LoopFS允许每个应用程序或容器拥有自己的专用Loop设备,从而避免了资源争抢和数据泄露的风险。此外,LoopFS还支持非特权用户挂载Loop设备,只需结合系统调用拦截技术即可实现。

关注了就能看到更多这么棒的文章哦~

Private loop devices with loopfs

May 7, 2020

This article was contributed by Marta Rybczyńska

原文来自:https://lwn.net/Articles/819625/

主译:DeepL

loop device这种设备是内核里面抽象出来的一个虚拟设备,可以把文件呈现为一个物理上的块设备(physical block device)一样。lopp device的典型用途是把存放在一个文件里面的文件系统影响给mount出来。loop device是全局性的,各个用户之间都可以看到,这对于container容器工作场景来说会有一些问题,因为在这些场景中,实例(instance)之间应该要保证相互隔离的。Christian Brauner一直在研究这个问题。他发布了一个patch set,通过添加一个名为loopfs的小虚拟文件系统来解决这个问题。

loop device通常都出现在/dev下,其名称如/dev/loopN这样。可以用一个专门设置的/dev/loop-control文件来创建和销毁loop device,或用它来找到第一个可用的loop device。如果需要把某个文件跟指定的loop device关联起来,或者想设置其他参数比如偏移(offset)或块大小(block size),都可以通过loop device本身的ioctl() 调用来完成。loop(4) 的man page上有关于其工作原理的细节介绍。

用户一般不需要指定使用某个特定的loop device,他们常用的方式是使用一个mount参数来配置loop device。

mount /tmp/myimage.img /mnt/disk -o loop

mount就会去找一个可用的loop device,将其与/tmp/myimage.img关联,然后将该设备挂载到/mnt/disk上。有些管理员可能更喜欢使用一些与此类似的命令参数,可以控制得更精确:

mount /tmp/myimage.img /mnt/disk -o loop=/dev/loop1

管理员用这种参数就可以指定要使用哪个loop device。如果管理员需要对loop device进行更多的控制,也可以使用losetup命令查询和设置loop device的属性。

如上所述,loop device是全局可见的,并且在用户之间是公用的。也就是说/dev/loop3在所有namespace中都是同一个设备。如果一个应用程序需要一个自己私有的loop device,它没有办法请求一个loop device给自己一个人用。loop device在容器之间也是共享的,因此一个容器就可以监控到其他容器的操作,或者访问到其他容器的数据。

在这个patch set的讨论中过程中提到了loop device的许多不同使用场景。Dmitry Vyukov举了一个例子(https://lwn.net/ml/linux-kernel/CACT4Y+aDeSAARG0b9FjDFyWuhjb=YVxpGtsvBmoKnHo+0TF4gA@mail.gmail.com/  )就是在测试进程使用loop device时可以确保这些测试进程相互隔离。他描述了他所遇到的问题如下:

目前,所有的loop device和loop-control都是全局的,导致测试进程相互争抢,这又会导致测试中覆盖不全,也会出现一些不可重现的crash。

Brauner也从container的应用中举了一些例子。例如,systemd-nspawn就不支持loop device,因为loop device不能被动态发现并被容器所占用。Chromium OS不允许使用loop device。Kubernetes也遇到了由loop device的全局性而导致的问题:一个文件在用户退出后,可能还继续绑定在原来的loop device上。

loopsfs

于是就创建了这个内核内的新虚拟文件系统loopfs,它实现了那些loop device和loop-control文件。这个文件系统可以被多次挂载,每个实例中的loop device与所有其他实例中的所有其他loop device是独立的。这样,可以为应用程序和容器提供私有专用的loop device。loopfs中的loop device和loop-control文件都可以使用传统的loop device相同的操作方式。

loopfs的一个好处是可以保证兼容旧有的应用程序的兼容,只是替换成了新增的virtualized loop-device文件而已。在这种情况下,管理员可以正常mount文件系统,然后把缺省的loop control文件替换成loopfs中的文件。考虑可以看一下下面这个来源于patch cover letter里面的例子:

    # Mount a new loopfs instance in /dev/loopfs/
    mount -t loop loop /dev/loopfs/

    # Replace the standard loop control file with the ones from loopfs
    ln -sf /dev/loopfs/loop-control /dev/loop-control

    # Find the first available loop device
    loopdev=`losetup -f`     	  # will be something like /dev/loop0
    deventry=`basename $loopdev`  # now just "loop0"

    # Redirect that loop device to loopfs
    ln -sf /dev/loopfs/$deventry /dev/$deventry

    # mount an image
    mount -o loop /image.img /mnt/disk

还可以使用/proc/sys/user/max_loop_devices来控制在每个 loopfs 实例中可以创建的loop device的最大数量。

Christoph Hellwig不同意loopfs这种方法,他说代码量太大,而它提供的好处不足以证明需要这么大的改动。Brauner解释了loopfs能带来的新的用法,但讨论到此就结束了。对于这个提议,目前并没有太大的反对意见。

Loopfs不只是创建了一个可以独立使用的loop-device池,它还可以有助于非特权用户来挂载loop device。这只需要将loopfs与Brauner早期做过的系统调用拦截的工作相结合就可以。后者(https://lwn.net/ml/linux-kernel/20190920083007.11475-1-christian.brauner%40ubuntu.com/)会使用seccomp来建立一个独立的进程,用来决定哪些操作是可以允许的。搭建好这样的环境之后,非特权用户就可以像往常一样运行mount,而拦截系统调用的特权进程将执行实际操作动作。

Jann Horn提出了非特权应用使用loop device可能存在的一个问题:大多数文件系统的实现里面没有考虑过如何处理恶意的文件系统映像。虽然已经做了一些工作,但文件系统映像一般仍被视为可信数据;这也是为什么之前有人提出允许非特权用户进行mount文件系统操作的时候,遭到人们反对的原因。如果攻击者能访问到loop device并mount,同时也有能力在运行时修改映像,那么问题就会变得更加复杂。

Stéphane Graber 指出,基于系统调用拦截的实现方式不需要直接mount文件系统,可以使用基于 FUSE 的mount。这样就可以防止任何文件系统级的漏洞转化为内核漏洞。LXD 的实现里面就允许这两种类型的mount。

Next steps

Loopfs似乎解决了用户在实践中遇到的一个真实问题。它在一周的时间里已经进行了三次迭代,解决了review期间收到的意见。它可能还需要一些时间才能被批准进入mainline kernel。不过,很明显,有许多用户在等待能解决loop device共享问题。

全文完

LWN文章遵循CC BY-SA 4.0许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注LWN深度文章以及开源社区的各种新近言论~

内容概要:本文档为《Hibernate 全套完整学习笔记(完整版·无遗漏)》,系统整合了 Hibernate 框架从基础到高级的全部核心知识点,涵盖前置知识、环境搭建、实体映射、关联关系、查询体系、缓存机制、事务与锁、性能优化、框架整合(Spring/SpringBoot/JPA)、企业实战功能及高频面试题。深入讲解了 Hibernate 的 ORM 映射原理、主键生成策略、延迟加载与抓取策略、N+1 问题根治方案、乐观锁与悲观锁机制、二级缓存集成 Redis、Envers 审计、自定义类型、批量操作优化等关键内容,并提供大量可运行代码示例与企业级最佳实践。; 适合人群:具备 Java 和数据库基础,从事或希望从事 Java EE 开发、SSH/SSM 框架开发,尤其是使用 Hibernate 或 JPA 的中高级研发人员(工作年限1-5年),以及准备相关技术面试的开发者。; 使用场景及目标:① 掌握 Hibernate 核心机制如一级/二级缓存、脏检查、延迟加载与 N+1 问题解决方案;② 理解并应用主键策略、关联映射、事务隔离、锁机制等高级特性;③ 实现企业级性能优化,如批量处理、投影查询、抓取策略调优;④ 完成与 Spring Boot、Redis 的整合实战;⑤ 高效应对 Hibernate 相关面试考察。; 阅读建议:本资料结构清晰、层次分明,建议按照“基础→核心→高级→实战”顺序系统学习,重点理解懒加载与抓取策略、N+1 问题、缓存体系等高频难点,结合代码动手实践,调试 SQL 输出与缓存行为,强化对框架底层机制的理解。
内容概要:本文围绕虚拟电厂与电动汽车之间的主从博弈关系展开研究,创新性地引入条件风险价值(CVaR)理论以量化和管理电力系统中因不确定性因素带来的潜在风险。通过构建严谨的数学模型,并结合Matlab编程实现,深入探讨了在开放电力市场环境下,作为领导者的虚拟电厂与作为跟随者的电动汽车群体之间的动态博弈过程。研究不仅建立了完整的Stackelberg博弈框架,还重点剖析了CVaR在优化目标函数、提升决策鲁棒性方面的作用,旨在制定兼顾经济效益与系统可靠性的协同调度策略。文中详细阐述了模型的构建逻辑、求解算法的设计流程以及关键参数的设置依据。; 适合人群:具备电力系统分析、博弈论基础及Matlab编程能力,从事能源互联网、智能电网、电动汽车调度、电力市场运营或风险管理等领域研究的高校研究生、科研机构研究人员及企业研发工程师。; 使用场景及目标:①用于学习和构建虚拟电厂与用户侧资源(如电动汽车)间的主从博弈模型;②掌握CVaR等现代风险度量工具在电力系统优化调度中的应用方法;③为应对新能源出力与负荷需求双重不确定性,提供提升调度策略稳健性的技术参考与解决方案; 阅读建议:建议读者在充分理解博弈论和风险度量基本概念的基础上,结合所提供的Matlab代码进行复现和调试,通过改变模型参数和场景设置,深入探究不同风险偏好下博弈均衡结果的变化规律,从而加深对理论模型与实际应用之间联系的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值