尼克斯:一个时机已经成熟的想法

2022-02-20 17:40:26

Erlang的创建者之一乔·阿姆斯特朗(Joe Armstrong)曾将Erlang描述为对“编写一次,永远运行”的程序的追求相比之下,Nix可能是对随时随地运行的程序的追求。Nix经常让新手和经验丰富的开发人员感到害怕,因为它提出了一个相当彻底的改革,来改变我们对包管理的看法,以及我们如何运行软件。在这篇文章中,我将说明Nix解决了哪些问题,并认为这种视角的变化对软件工具有着深远的影响。

与包经理打交道是当今开发人员体验的核心,但仍然充满陷阱。我们倾向于将我们的信任外包给一个包缓存,比如NPM或Hex,然后将它们返回的任何东西合并到我们的系统中。大多数情况下,这很好,因为包经理有诚实行事的动机。例如,当这个中心故障点出现问题时,攻击者可以修改软件包,将恶意软件包括在所谓的数字供应链攻击中。我们真正想要的,也是当今任何软件包经理都无法提供的,是可复制性。

所谓可复制性,我们指的是在你自己的系统上一点一点地重建一个软件包的能力。无论抛出什么包,您都可以在本地重建它,并检查是否具有预期的生成输出。这类似于通过计算从Web下载的二进制文件的sha256哈希值,并将其与二进制文件发布者提供的哈希值进行比较,从而验证二进制文件。然而,在Nix的例子中,您是从源代码构建包的。为什么这很重要?因为它消除了对提供商的信任,并使开发人员检测故障或攻击的成本大大降低。可再现性意味着系统和应用程序的安全,以及开发人员的安心。

一个人达到这种可复制状态的方式是不考虑当地环境。Nix中的所有内容都必须由用户明确声明。大多数构建工具或环境都依赖于对本地环境的假设,并试图尽可能地处理它,但如果你想提供一种在任何地方构建任何东西的方法,你必须放弃与本地环境的任何束缚。Nix通过强制您声明所需的包以及如何将它们组合在一起来实现这一点。因为环境或构建的每个部分都是明确的,所以可以实现隔离和再现性。

Nix既是一个包管理器——一个可以下载和运行的预构建包的来源——也是一种功能性语言,帮助我们以可复制的方式编写“构建表达式”。Nix表达式是一个有一个副作用的函数:创建构建本身的规范。

“Nix方法的主要思想是将软件组件彼此隔离地存储在一个中央组件存储中,路径名包含构建组件所涉及的所有输入的密码散列”——Eelco Dolstra的博士论文

首先,使用Nix构建的所有东西都会放在一个中央存储中,默认情况下为“/Nix/store”,这与Linux FHS(文件系统层次结构标准)不同。对于以传统方式安装在系统上的软件包,您知之甚少:它是如何构建的?这取决于什么?Nix使包定义变得独立。

其次,每个构建的工件都用一个散列来标识,散列是包的完整依赖关系图的摘要标识符、涉及的特定于平台的构建步骤,以及定义如何构建它的Nix表达式。例如,我的本地版本“bat”v.0.18.3是“cat”的流行cli替代品,它存储在以下路径下:“/nix/store/fm6m39f7fr94bch5q1nssrrv6w6c8d2n-bat-0.18.3/bin/bat”,并带有以下依赖关系图。

该图完整地描述了依赖关系的流程。更改bat的顺序或任何依赖项,输出哈希就会更改,从而在nix存储中产生一个新条目。就尼克斯而言,这将是一个全新的方案。因为在构建输出之前就知道了输出的哈希值,所以不需要备份包本身,只需要备份它们的构建表达式。这意味着您可以与同事共享本地环境的完整规范,并且知道它将完全按照在您的机器上运行的方式执行。这意味着你可以有多个环境,一个软件包的多个版本,在你的机器上和平共存。它为您提供了跨语言和跨平台的保证:您获得了打包软件的统一界面,以及运行软件所需的一切。大多数时候,它“只是起作用”。

这本身就是一个受欢迎的发展,但另一个可能不太受欢迎的好处是,虽然今天通过空间共享软件很容易,但通过时间共享软件往往要困难得多。举一个虚构的例子,假设您的公司维护一个25年前用当时的C编译器构建的工具。它无法安全升级,因为如果升级,整个世界的银行系统都会崩溃。也许你会用一台专用笔记本电脑作为数字时间胶囊来维护这个工具。相反,你可以用你需要的任何版本的工具创建一个Nix外壳,这些工具是固定的,从来没有升级过。这个环境是隔离的,可以很好地与系统上的所有其他C版本配合使用,因为它只是另一个Nix包。你可以与任何人共享这个环境,他们只需一个`nix shell`命令,就可以拥有与你相同的环境。

“我们用建造城市的方式建造计算机——随着时间的推移,没有计划,在废墟之上。”——艾伦·乌曼

尼克斯无疑有着陡峭的学习曲线,这有两个原因。首先,使用Nix需要重新思考许多公认的智慧和实践,这些智慧和实践已成为开发人员的第二天性。忘却学习很难。其次,Nix揭示了构建软件所涉及的所有复杂性,并迫使您处理它。为了使构建真正可复制,这在很大程度上是不可避免的。但是,一旦“尼克斯方式”被集成,社区工具被利用,你的系统就会变得非常透明。不再需要在您的系统和各种语言中追踪配置和构建工具。您将获得一个统一的界面,用于处理跨生态系统的软件构件的构建、组合和共享。没有什么是瞒着你的,你可以随心所欲地改变。从这个意义上讲,它完全属于Linux自由和开放源码软件的传统。

Nix已经脱离了“科学实验阶段”,但仍在发展中。然而,许多公司在今天的生产中使用了Nix,例如Target、Replit和Shopify。虽然尼克斯的复杂性可能令人望而生畏,但我怀疑我们会在20年后回顾,并想知道没有它我们会如何相处。同时,享受领先几年的生活:)。