什么是 NisOS?#
Nix 是一个采取独特方法进行包管理和系统配置的工具。能够制作可重复的、声明性的和可靠的系统。
NixOS 是一个建立在 Nix 软件包管理器之上的 Linux 发行版。它使用声明式配置,并允许可靠的系统升级。Nix 提供了几个官方软件包「频道」,包括目前的稳定版和跟随最新发展的不稳定版。NixOS 有专门用于 DevOps 和部署任务的工具。
为什么是 NixOS?#
现在,你有这样的一个需求:你想要在本地测试服务器部署一个项目,在测试完毕之后部署在云服务器(例如 AWS)上,那么如何保证你的测试是有效的呢?
换句话说,如何保证两台服务器的环境一致?你可能会想到使用 Docker,但是 Docker 的缺点是它的镜像是不可变的,更新镜像需要重新构建,十分麻烦。那么是否有办法保持环境一致的同时,又不会损失灵活性?答案是 NixOS。
NixOS 的包管理器十分特别。它是声明式的,所有包均位于/etc/nixos/configuration.nix
中,你可以在其中声明你需要的包,然后运行nixos-rebuild switch
即可安装。如果想要保持环境一致,只需要将/etc/nixos/configuration.nix
复制到另一台服务器上,然后运行nixos-rebuild switch
即可。
使用 NixOS 部署开源项目是 DevOps 的一个很好的练习,这篇文章介绍的是如何安装适用于服务器的最小化 NixOS.
准备工作#
因为是服务器,不会用到桌面环境,所以使用最小化的 NixOS。NixOS 镜像的下载链接在 https://nixos.org/download.html。
博主的测试服务器使用 ESXi (ESX) 作为虚拟化平台,使用的 NixOS 版本为22.11
。
虚拟机配置为:
- CPU: 4vCPU(EPYC 7302)
- RAM: 8GB
- Disk: 50GB(HDD)
- UEFI 启动
安装#
最小化镜像的安装没有图形界面,只有命令行界面,这对 Linux 新手来说可能有些困难。但是,只要按照下面的步骤操作,应该不会有太大问题。
打开虚拟机电源,进入 UEFI 界面,选择NixOS 22.11.4426 Installer
(默认选项),进入安装环境。
由于版本差异,可能会有所不同。
如果一切顺利,应该会在经过<<< NixOS Stage 1 >>>
和<<< NixOS Stage 2 >>>
之后,进入命令行界面。
输入sudo su
切换到 root 用户,以便后续操作。
分区#
输入cfdisk
,进入分区界面,按照下面的分区方案进行分区:
- 选用 GPT 分区表
- 首先新建一个
/boot
分区,大小至少为512MB
,文件系统为EFI System
- 如果内存较小,则创建 swap 分区,大小为内存的两倍,文件系统为
Linux swap
- 创建一个
/
分区,用尽其余空间,文件系统为Linux filesystem
第一个分区必须是
EFI System
,因为 NixOS 需要 EFI 分区来引导。
以下是一个分区示例:
在分区完成之后,务必在 Write 之后再 Quit,否则分区不会生效。
可以使用lsblk
命令查看分区情况。
接下来,格式化分区。
mkfs.ext4 -L nixos /dev/sda3
。格式化/
分区,并且给它一个 label,方便后续操作。- 如果有 swap 分区,输入命令
mkswap -L swap /dev/sda2
,格式化 swap 分区。 mkfs.fat -F 32 -n boot /dev/sda1
。格式化/boot
分区。
注意:以上分区是博主的分区,如果你的分区不是这个,需要修改命令中的分区号。
接下来,挂载分区。
mount /dev/disk/by-label/nixos /mnt
mkdir -p /mnt/boot
mount /dev/disk/by-label/boot /mnt/boot
swapon /dev/sda2
输入lsblk
,应该会看到类似下面的输出:
生成文件#
接下来,生成 NixOS 配置文件。
nixos-generate-config --root /mnt
现在,输入nixos-install
,开始安装。
安装过程需要用到网络,务必保持网络畅通。安装过程预期持续时间为 5-10 分钟,具体时间取决于网络速度、CPU 性能等因素。
在安装过程的最后环节,会提示你输入 root 密码。输入密码后,安装过程就结束了。
输入reboot
重启,然后拔掉安装介质。
(临时)添加用户#
重启之后,会进入命令行界面,输入之前的密码登录 root 用户。
nixos login: root
password:
输入密码时,不会显示任何字符,这是正常现象。
建议创建一个新用户,便于日常操作。root 用户只用于系统管理。
使用非 root 用户是一个好习惯,能够避免安全隐患和破坏性误操作。
但这里展示的操作并不是 NixOS 的最佳实践,因为 NixOS 的用户管理是声明式的,不应该在命令行中创建用户。
正确的做法请参考下一节「添加用户到 sudoer 列表」
useradd -c 'admin' -m nk
passwd sh # 设置密码
useradd
命令的参数含义如下:
-c
:用户的备注信息
-m
:创建用户的 home 目录
nk
:用户名(可以自定义)
现在,可以使用exit
命令退出 root 用户,然后使用新用户登录了。
nk
是用户名,如果你的用户名不是nk
,请修改。
最后,输入uname -a
,应该会看到类似下面的输出:
Linux nixos 5.15.133 #1-NixOS SMP Wed May 24 16:36:55 UTC 2023 x86_64 GNU/Linux
如果你看到的内核版本不是
5.15.133
,请不要惊慌,这是因为 NixOS 的内核是动态生成的,每次安装都会生成一个新的内核。
添加用户到 sudoer 列表#
为了方便,需要将新用户加入 sudoer 列表。你可能会想修改 sudoer 列表,但在 NixOS 中,不需要修改 sudoer 列表,只需要将用户加入wheel
组即可。而在 NixOS 中,这个操作的正确做法是修改/etc/nixos/configuration.nix
文件。
你可能会想用 vim 来修改配置文件,但是 NixOS 默认没有安装 vim 而是默认安装了 nano。所以可能需要先用
nix-shell -p vim
临时安装 vim。关于包管理器的更多用法,后面会讲到。
具体步骤如下:
-
找到
users.users
字段(在最小化安装的配置文件中,这个字段是被注释掉的)。 -
创建一个新用户,比如
nk
,并将其加入wheel
组。即编写如下配置:
users.users.nk = {
isNormalUser = true;
extraGroups = [ "wheel" ];
};
- 保存配置文件,然后执行
nixos-rebuild switch
命令,使配置生效。
记得用
passwd
命令设置新用户的密码。
常用工具的安装#
NixOS 的独特之处在于包管理器的特殊性,我们需要先简单了解一下 NixOS 的包管理器。
NixOS 的包管理器是 Nix,它有 3 种安装方式:
nix-env
:安装到用户目录,只对当前用户有效。nix-shell
:临时安装,只对当前 shell 有效。- 修改
.nix
配置文件:安装到系统目录,对所有用户有效。
不能像使用apt
那样用nix-env
,因为这种做法有一些弊端:
- 依赖关系错误:
nix-env
命令默认会尝试解析软件包的依赖关系并自动安装依赖项。然而,这种自动解析可能会导致不一致或不可预测的结果。 - 环境隔离和版本管理失控:使用
nix-env
命令手动管理软件包环境可能会导致环境混乱或冲突。 - 损失共享性和可复现性:使用
nix-env
命令管理软件包的方式可能不够明确和可读。配置文件可以包含更详细的文档和注释,可以更好地记录和分享软件包环境的信息。
考虑到我们使用 NixOS 的目的,我们首选修改.nix
配置文件的方式。
用修改配置文件的方式安装#
作为服务器,显然大多数人都需要安装的软件有:
- openssh
- vim
- wget
- curl
在默认的 NixOS 配置文件中找到environment.systemPackages
,在其中添加上面的软件包。也就是做如下修改:
你可能会想用 vim 来修改配置文件,但是 NixOS 默认没有安装 vim(不然你为什么要安装它),所以你需要先用
nix-shell -p vim
临时安装 vim。
在environment.systemPackages
字段中添加如下内容:
environment.systemPackages = with pkgs; [
vim
wget
curl
openssh
];
这部分默认被注释了,你需要先取消注释,然后在其中添加上面的内容。
environment.systemPackages = with pkgs;
是默认写法,不要改动。
这样一来,就安装好了除了 openssh 之外的软件。openssh 的安装稍微复杂一些,需要继续修改配置文件。
配置 openssh#
在services.openssh
字段中添加如下内容:
最小化安装的 NixOS 中没有这部分配置,你需要自己添加。
services.openssh = {
enable = true;
permitRootLogin = "no"; // 可选:禁用Root用户登录
passwordAuthentication = true; // 可选:启用密码身份验证
};
保存配置文件后,执行nixos-rebuild switch
命令,使配置生效。
你可以运行这个命令来查看 openssh 的状态:
sudo systemctl status sshd
如果 SSH 服务正在运行,你应该会看到它的状态为「active」。
考虑到以后可能会需要用到这个配置文件,特意将这个配置文件放置于 IPFS 上以便以后博主和读者使用。