nixos-and-flakes-book/docs/zh/faq/index.md
2023-07-08 00:32:56 +08:00

43 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 常见问题 FAQ
## NixOS 的回滚能力与 btrfs / zfs 系统快照回滚有何不同?
很多使用 Arch Linux / Ubuntu 等常规 Linux 发行版的用户,习惯于使用 btrfs / zfs 等文件系统提供的快照作为「后悔药」,这样系统出了问题能回滚修复。
而本书介绍的 NixOS 也提供了系统状态回滚能力,因此很容易会有这样的疑问:这两种系统回滚功能有何不同?
这里简单解释下,主要区别在于,系统快照的内容是不可复现的,快照内容不包含如何从零构建这个快照的「知识」,是**不可解释的**。
而 NixOS 的配置是一份从零构建出一个一模一样的 OS 的「知识」,是**可解释的**而且可以通过简单几行命令就自动完成这个构建。NixOS 配置本身既是一份记录你的 OS 都做过哪些变更的文档,也是用于自动构建出这个 OS 的配置。
NixOS 的配置文件就像是程序的**源代码**,只要源代码没丢,修改程序、审查程序,或者重新构建出一个一模一样的程序都很简单。
而系统快照就像是源代码编译出来的二进制程序,要对它做修改、审查,都要难得多。而且这个快照很大,分享或者迁移它的成本都要比源代码高得多。
但这并不是说有了 NixOS 就不需要系统快照了,本书第一章就介绍了 NixOS 只能保证在声明式配置中声明的所有内容都是可复现的,而其他未声明式配置覆盖到的系统状态是不受它管辖的。比如 MySQL/PostgreSQL 的动态数据、用户上传的文件、系统日志等等,用户 Home 目录下的视频、音乐、图片等等,这些内容都还是需要文件系统快照或者其他手段来备份。
## Nix 与 Ansible 等传统的系统运维工具相比有何优劣?
Nix 不仅可用于管理桌面电脑的环境也有很多人用它批量管理云服务器Nix 官方的 [NixOps](https://github.com/NixOS/nixops) 与社区的 [deploy-rs](https://github.com/serokell/deploy-rs) 都是专为这个场景开发的工具。
Nix 与 Ansible 这类被广泛应用的传统工具比,主要优势就在:
1. Nix 的声明式配置屏蔽了底层细节,使用户只需要关心自己最核心的需求,从而带来了高度便捷的系统自定义能力。而使用 Ansible 这类传统工具,用户需要自己去处理所有的实现细节。
1. 如果你有使用过 terraform/kubernetes 等声明式配置工具,应该很容易理解这一点。需求越是复杂的情况下,声明式配置带来的好处就越大。
2. Nix 通过声明式配置声明了自己的目标状态,而 Nix Flakes 通过一个版本锁文件 `flake.lock` 锁定了所有依赖的 hash 值、版本号、数据源等信息,这极大地提升了系统的可复现能力。而传统的 Ansible 等工具的可复现能力是很差的,这也是为什么 Docker 这么受欢迎的原因——它以较低的代价提供了 Ansible 等传统运维工具提供不了的**完全一致的运行环境**。
## Nix 与 Docker 容器技术相比有何优势?
Nix 与以 Docker 为代表的容器技术的应用场景也存在一定重合,比如说:
1. 有很多人用 Nix 来管理开发编译环境,本书就对此做过介绍。但另一方面也有像 [Dev Containers](https://github.com/devcontainers/spec) 这种基于容器搭建开发环境的技术,而且非常流行。
2. 目前整个 DevOps/SRE 领域基本已经是基于 Dockerfile 的容器技术的天下,容器中常用 Ubuntu/Debian 等发行版,宿主机也同样有很多成熟的发行版可选,改用 NixOS 有什么明显的优势呢?
其中第一点「管理开发编译环境」Nix 创建的开发环境体验非常接近直接在宿主机进行开发,这要比 Dev Containers 好很多,举例如下:
1. Nix 不使用名字空间进行文件系统、网络环境等各方面的隔离,在 Nix 创建的开发环境中也可以很方便地与宿主机文件系统(包括 /dev 宿主机外接设备)、网络环境等等进行交互。而容器要通过各种映射才能宿主机文件系统互通,即使这样也可能会遇到一些文件权限问题。
2. 因为没做啥强隔离Nix 开发环境对 GUI 程序的支持也没任何问题,在这个环境中跑个 GUI 程序的体验就跟在系统环境中跑个 GUI 程序没任何区别。
也就是说Nix 能提供最接近宿主机的开发体验,不存在什么强隔离,开发人员能在这个环境中使用各种熟悉的开发调试工具,过往的开发经验基本都能无痛迁移过来。
而如果使用 Dev Containers那开发人员很可能会遭遇强隔离导致的各种文件系统不互通、网络环境问题、用户权限问题、无法使用 GUI 调试工具等等各种毛病。
而如果我们决定了使用 Nix 来管理所有的开发环境,那么在构建 Docker 容器时也基于 Nix 去构建,显然能提供最强的一致性,同时所有环境都统一了技术架构,这也能明显降低整个基础设施的维护成本。
这就回答了前面提到的第二点,在使用 Nix 管理开发环境的前提下,容器基础镜像与云服务器都使用 NixOS 会存在明显的优势。