热补丁需要可重现的构建 – 而容器是答案

我们知道热补丁具有实际好处,因为它显著减少了与频繁补丁相关的停机时间。但是,热补丁相对难以实现,而且容易引起其他问题,因此热补丁的实施频率不如预期。毕竟,系统管理员最不希望的就是导致系统崩溃的热补丁。
可重现的构建是帮助开发人员一致且安全地实施热补丁的工具之一。在本文中,我将解释为什么可重现的构建对于热补丁至关重要,可重现的构建究竟是什么,以及容器如何发挥救援作用。
热补丁:关键的威胁管理工具
补丁是系统维护的关键部分,因为补丁修复了错误和有缺陷的代码。更重要的是,安全团队依靠补丁来堵塞安全漏洞,而且这非常紧迫。等待方便的维护窗口进行补丁是危险的,因为它为黑客利用漏洞留下了机会。
这造成了一个难题:保持高可用性但承担安全风险,还是频繁打补丁但最终导致利益相关者感到沮丧。热补丁弥合了这一差距。通过热补丁,在进程正在运行时,有问题的代码会被替换掉,而无需重启依赖于该进程的应用程序或服务。
实施热补丁并非易事
热补丁的实现并非那么简单直接——插入的代码必须以“完全相同”的方式“适配”,否则可能会发生各种不良情况。如果出错,应用程序——或者整个服务器——将会崩溃。
运行进程背后的代码通常来自二进制可执行文件——一个从源代码编译而来的机器可读代码块。例如,内核有数千个源文件,所有这些文件都被编译成几个二进制文件。
使用热补丁时,热补丁代码必须在精确的级别上适配。是的,包含补丁代码的二进制文件将与包含错误代码的二进制文件不同。尽管如此,新代码必须精确地插入到位,并且必须依赖于相同版本的导入库。热补丁代码还必须使用相同的编译器选项和标志进行编译。位序也很重要——二进制文件必须以完全相同的方式排序。
原则上,所有这些都是可以实现的——但在实践中,这是一个挑战。例如,日常系统更新通常会影响库。这些库可能略有不同,反过来在编译代码时会产生略有不同的二进制文件。
如果在系统上创建的补丁,其中只有一个库存在细微差异,则该补丁很容易使应用它的进程崩溃。如果是内核补丁,则可能导致整个系统崩溃。
为什么可重现的构建对于热补丁至关重要
换句话说,开发补丁的环境非常重要。在开发补丁时,重要的是重现正在修补的代码的环境。在没有任何指导的情况下,这可能非常具有挑战性。
对于支持代码的开源团队来说,这可能更直接,因为这些团队应该有记录原始环境状态的记录,软件供应商也是如此。但有时软件背后的开发人员可能不会及时发布补丁。
当组织或任何其他第三方尝试在内部创建补丁时,尝试复制原始构建环境的过程可能非常具有挑战性、耗时且不可预测,需要一定程度的反复试验。
这就是为什么软件开发人员一直在努力开发一种更轻松地重现原始构建环境的方法——以及为什么一种称为可重现构建的方法应运而生,成为前进的方向。
那么,什么是可重现的构建?
简单来说,当两个独立的软件开发人员有能力将人类可读的源代码编译成机器可读的代码,从而使两次独立的尝试产生按位相同的二进制文件时,构建就是可重现的。
在 Reproducible Builds网站上,作者提出了可重现构建的三个关键标准。首先,构建过程必须是确定性的:不记录日期或时间等变量,并且输出必须以相同的顺序生成——这是对位序的引用。
其次,重现构建环境所需的工具必须以精确的细节提供或描述。最后,开发人员需要能够验证他们生成的构建。
可以说,最重要的要素之一是重现构建环境的能力——但考虑到构建环境中涉及的许多变化因素,这也是最难实现的要素之一。
可重现的构建并不是一个全新的概念,GNU 项目自 20 世纪 90 年代以来一直在使用可重现的构建,但可重现构建的实用性可能比以往任何时候都更大。
如果做得正确,您的可重现构建将确保您可以生成一个补丁,该补丁可以插入到活动进程中而不会破坏任何东西。您还可以依靠可重现的构建过程来确保您正在使用的二进制代码没有被篡改。事实上,这确保了从源代码到输出二进制文件的直接路径可以被验证。
容器:热补丁的哥伦布彩蛋…
我已经解释了为什么可重现的构建是一个很棒的概念,但也解释了为什么可重现的构建可能难以实现。一种使持续重现构建环境更容易的途径是使用虚拟机。开发人员实际上将整个构建环境打包并在虚拟机中分发。
然而,虚拟机管理起来很麻烦——VM 文件很大,并且需要启动整个操作系统才能适应更改请求,或者查看 VM“内部”以分析构建环境。当有多个团队参与时,VM 可能会成为真正的麻烦。
容器是一种更轻便、更敏捷的方式来模拟原始构建环境。与 VM 相比,容器提供操作系统级别的虚拟化,这意味着容器镜像更加紧凑。
以 Docker 为例,Docker 是一种流行的产品,可以实现容器化。当开发人员想要模拟原始构建环境时,开发人员只需下载容器的配置文件——称为 Dockerfile。在此配置文件中,有一组指令可以重现精确的构建环境。
与管理大型 VM 文件不同,对构建环境的任何更改都只需写入 Dockerfile 中,该文件与重现构建所需的所有其他代码一起存储。容器使开发人员能够绕过可重现构建带来的许多困难,同时还提供了一个可以审计的构建过程。
将热补丁作为日常实践
重现相同的二进制包——可重现的构建——的能力对于使热补丁工作至关重要。然而,可重现的构建一直难以实现,这反过来限制了热补丁的可用性。
容器使生成适用于热补丁的补丁的工作变得更加容易。它为企业用户打开了大门,使他们能够开发补丁,并且知道这些补丁将实时插入到位——而不会造成任何中断。
这意味着热补丁可以更广泛地部署——使众多组织免受补丁停机的破坏性影响,并因此提高其整体安全态势,因为现在可以根据需要快速且频繁地进行补丁。