什麼是 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 上以便以後博主和讀者使用。