xChar

什么是NisOS?

NixOS

参考:维基百科NixOS首页

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.

DevOps维基百科

准备工作

因为是服务器,不会用到桌面环境,所以使用最小化的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,进入分区界面,按照下面的分区方案进行分区:

  1. 选用GPT分区表
  2. 首先新建一个/boot分区,大小至少为512MB,文件系统为EFI System
  3. 如果内存较小,则创建swap分区,大小为内存的两倍,文件系统为Linux swap
  4. 创建一个/分区,用尽其余空间,文件系统为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,应该会看到类似下面的输出:

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。关于包管理器的更多用法,后面会讲到。

具体步骤如下:

  1. 找到users.users字段(在最小化安装的配置文件中,这个字段是被注释掉的)。

  2. 创建一个新用户,比如nk,并将其加入wheel组。即编写如下配置:

users.users.nk = {
  isNormalUser = true;
  extraGroups = [ "wheel" ];
};
  1. 保存配置文件,然后执行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上以便以后博主和读者使用。

最终配置文件下载链接

Loading comments...