Nix是一个采取独特方法进行包管理和系统配置的工具。能够制作可重复的、声明性的和可靠的系统。
NixOS是一个建立在Nix软件包管理器之上的Linux发行版。它使用声明式配置,并允许可靠的系统升级。Nix提供了几个官方软件包「频道」,包括目前的稳定版和跟随最新发展的不稳定版。NixOS有专门用于DevOps和部署任务的工具。
现在,你有这样的一个需求:你想要在本地测试服务器部署一个项目,在测试完毕之后部署在云服务器(例如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
。
虚拟机配置为:
最小化镜像的安装没有图形界面,只有命令行界面,这对Linux新手来说可能有些困难。但是,只要按照下面的步骤操作,应该不会有太大问题。
打开虚拟机电源,进入UEFI界面,选择NixOS 22.11.4426 Installer
(默认选项),进入安装环境。
由于版本差异,可能会有所不同。
如果一切顺利,应该会在经过<<< NixOS Stage 1 >>>
和<<< NixOS Stage 2 >>>
之后,进入命令行界面。
输入sudo su
切换到root用户,以便后续操作。
输入cfdisk
,进入分区界面,按照下面的分区方案进行分区:
/boot
分区,大小至少为512MB
,文件系统为EFI System
Linux swap
/
分区,用尽其余空间,文件系统为Linux filesystem
第一个分区必须是
EFI System
,因为NixOS需要EFI分区来引导。
以下是一个分区示例:
在分区完成之后,务必在Write之后再Quit,否则分区不会生效。
可以使用lsblk
命令查看分区情况。
接下来,格式化分区。
mkfs.ext4 -L nixos /dev/sda3
。格式化/
分区,并且给它一个label,方便后续操作。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列表,但在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
配置文件的方式。
作为服务器,显然大多数人都需要安装的软件有:
在默认的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的安装稍微复杂一些,需要继续修改配置文件。
在services.openssh
字段中添加如下内容:
最小化安装的NixOS中没有这部分配置,你需要自己添加。
services.openssh = {
enable = true;
permitRootLogin = "no"; // 可选:禁用Root用户登录
passwordAuthentication = true; // 可选:启用密码身份验证
};
保存配置文件后,执行nixos-rebuild switch
命令,使配置生效。
你可以运行这个命令来查看openssh的状态:
sudo systemctl status sshd
如果SSH服务正在运行,你应该会看到它的状态为「active」。
考虑到以后可能会需要用到这个配置文件,特意将这个配置文件放置于IPFS上以便以后博主和读者使用。