SSH를 통한 원격 머신 프로비저닝#

Author:

Jacek Galowicz @tfc

Editor:

Valentin Gagarin @fricklerhandwerk

nixos-anywhere와 disko를 사용하면 실행 중인 시스템에서 어떤 Linux 설치든 NixOS 설정으로 교체할 수 있습니다.

소개#

이 튜토리얼에서는 실행 중인 컴퓨터에 NixOS 설정을 배포합니다.

무엇을 배우게 됩니까?#

다음 방법을 배웁니다.

  • 선언적 디스크 레이아웃과 SSH 접근을 갖춘 최소한의 NixOS 설정을 지정하는 방법

  • 설정이 유효한지 확인하는 방법

  • 원격 머신에 NixOS 설정을 배포하고 업데이트하는 방법

무엇이 필요합니까?#

무인 설치를 성공적으로 수행하려면 대상 머신이 다음 조건을 충족하는지 확인하십시오.

  • Linux를 실행하는 QEMU 가상 머신이어야 합니다

    • kexec를 지원해야 합니다

    • x86-64 또는 aarch64 명령어 집합 아키텍처(ISA)여야 합니다

    • RAM이 최소 1GB 이상이어야 합니다

    NixOS 설치 프로그램처럼 USB로 부팅한 라이브 시스템이어도 됩니다.

  • IP 주소가 DHCP로 자동 설정되어야 합니다

  • SSH로 로그인할 수 있어야 합니다

    • 공개 키 인증(권장) 또는 비밀번호를 사용해야 합니다

    • root 사용자 또는 sudo 권한이 있는 다른 사용자로 로그인해야 합니다

로컬 머신에는 정상적으로 동작하는 Nix 설치만 있으면 됩니다.

이 튜토리얼에서는 대상 머신을 target-machine이라고 부릅니다. 이를 실제 호스트 이름 또는 IP 주소로 바꾸십시오.

환경 준비하기#

새 프로젝트 디렉터리를 만들고 셸에서 해당 디렉터리로 이동하십시오.

mkdir remote
cd remote

nixpkgs, disko, nixos-anywhere에 대한 의존성을 지정하십시오.

$ nix-shell -p npins
[nix-shell:remote]$ npins init
[nix-shell:remote]$ npins add github nix-community disko
[nix-shell:remote]$ npins add github nix-community nixos-anywhere

고정된 의존성을 사용하여 필요한 모든 도구를 제공하는 새 파일 shell.nix를 만드십시오.

let
  sources = import ./npins;
  pkgs = import sources.nixpkgs {};
in

pkgs.mkShell {
  nativeBuildInputs = with pkgs; [
    npins
    nixos-anywhere
    nixos-rebuild
  ];
  shellHook = ''
    export NIX_PATH="nixpkgs=${sources.nixpkgs}:nixos-config=$PWD/configuration.nix"
  '';
}

이제 임시 환경을 종료하고 새로 지정한 환경에 진입하십시오.

[nix-shell:remote]$ exit
$ nix-shell

이 셸 환경에서는 nixos-anywhere 및 nixos-rebuild와 함께 명확하게 정의된 버전의 Nixpkgs를 사용할 수 있습니다.

중요

이후의 모든 명령은 이 환경에서 실행하십시오.

NixOS 설정 만들기#

새 NixOS 설정은 일반 시스템 설정과 디스크 레이아웃 명세로 구성됩니다.

이 예제의 디스크 레이아웃은 마스터 부트 레코드(MBR)와 EFI 시스템 파티션(ESP) 파티션, 그리고 남은 가용 공간 전체를 차지하는 루트 파일 시스템을 갖춘 단일 디스크를 기술합니다. 이 레이아웃은 EFI 시스템과 BIOS 시스템 모두에서 동작합니다.

디스크 레이아웃 명세를 담은 새 파일 single-disk-layout.nix를 만드십시오:

 1{ ... }:
 2
 3{
 4  disko.devices.disk.main = {
 5    type = "disk";
 6    content = {
 7      type = "gpt";
 8      partitions = {
 9        MBR = {
10          priority = 0;
11          size = "1M";
12          type = "EF02";
13        };
14        ESP = {
15          priority = 1;
16          size = "500M";
17          type = "EF00";
18          content = {
19            type = "filesystem";
20            format = "vfat";
21            mountpoint = "/boot";
22          };
23        };
24        root = {
25          priority = 2;
26          size = "100%";
27          content = {
28            type = "filesystem";
29            format = "ext4";
30            mountpoint = "/";
31          };
32        };
33      };
34    };
35  };
36}

디스크 레이아웃 정의를 가져오고 포맷할 디스크를 지정하는 파일 configuration.nix를 만드십시오:

팁

대상 디스크의 장치 식별자를 모른다면 lsblk로 대상 머신의 모든 장치를 나열하십시오:

$ ssh target-machine lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda      8:0    0   256G  0 disk
├─sda1   8:1    0 248.5G  0 part /nix/store
│                                /
└─sda2   8:2    0   7.5G  0 part [SWAP]
sr0     11:0    1  1024M  0 rom

이 예제에서 디스크 이름은 sda입니다. 따라서 블록 장치 경로는 /dev/sda입니다. 나중을 위해 이 값을 기록해 두십시오.

 1{ modulesPath, ... }:
 2
 3let
 4  diskDevice = "/dev/sda";
 5  sources = import ./npins;
 6in
 7{
 8  imports = [
 9    (modulesPath + "/profiles/qemu-guest.nix")
10    (sources.disko + "/module.nix")
11    ./single-disk-layout.nix
12  ];
13
14  disko.devices.disk.main.device = diskDevice;
15
16  boot.loader.grub = {
17    devices = [ diskDevice ];
18    efiSupport = true;
19    efiInstallAsRemovable = true;
20  };
21
22  services.openssh.enable = true;
23
24  users.users.root.openssh.authorizedKeys.keys = [
25    "<your SSH key here>"
26  ];
27
28  system.stateVersion = "24.11";
29}

중요

/dev/sda를 사용하는 디스크의 블록 장치 경로로 바꾸십시오.

<your SSH key here> 문자열을 앞으로 root 사용자로 로그인할 때 사용할 SSH 공개 키로 바꾸십시오.

자세한 설명

let 블록의 diskDevice 변수는 디스크 블록 장치의 경로를 정의합니다:

3let
4  diskDevice = "/dev/sda";
5  sources = import ./npins;
6in

이 변수는 디스크 레이아웃 명세에 기술된 대로 파티션 분할과 포맷의 대상을 지정하는 데 사용됩니다. 또한 부트 로더 설정에서도 사용되어 레거시 BIOS와 UEFI 시스템 모두에서 부팅할 수 있게 합니다:

14  disko.devices.disk.main.device = diskDevice;
15
16  boot.loader.grub = {
17    devices = [ diskDevice ];
18    efiSupport = true;
19    efiInstallAsRemovable = true;
20  };

qemu-guest.nix 모듈은 이 시스템이 QEMU 가상 머신 안에서 실행될 수 있도록 호환성을 제공합니다:

 8  imports = [
 9    (modulesPath + "/profiles/qemu-guest.nix")
10    (sources.disko + "/module.nix")
11    ./single-disk-layout.nix
12  ];

disko 라이브러리는 디스크 레이아웃 명세로부터 파티션 분할 스크립트와, 부팅 시 파티션을 그에 맞게 마운트하는 NixOS 설정 부분을 생성합니다. 첫 번째 줄은 라이브러리를 가져오고, 두 번째 줄은 디스크 레이아웃을 적용합니다:

 8  imports = [
 9    (modulesPath + "/profiles/qemu-guest.nix")
10    (sources.disko + "/module.nix")
11    ./single-disk-layout.nix
12  ];

디스크 레이아웃 테스트하기#

디스크 레이아웃이 유효한지 확인하십시오:

nix-build -E "((import <nixpkgs> {}).nixos [ ./configuration.nix ]).installTest"

이 명령은 disko 모듈이 제공하는 installTest 속성의 derivation을 빌드하여 가상 머신에서 전체 설치 과정을 실행합니다.

시스템 배포하기#

시스템을 배포하려면 설정과 그에 해당하는 디스크 포맷 스크립트를 빌드한 뒤, 그 결과를 사용하여 nixos-anywhere를 실행하십시오:

중요

target-host를 대상 머신의 호스트 이름 또는 IP 주소로 바꾸십시오.

toplevel=$(nixos-rebuild build --no-flake)
diskoScript=$(nix-build -E "((import <nixpkgs> {}).nixos [ ./configuration.nix ]).diskoScript")
nixos-anywhere --store-paths "$diskoScript" "$toplevel" root@target-host

참고

공개 키 인증을 사용하지 않는 경우: 환경 변수 SSH_PASS에 비밀번호를 설정한 다음 nixos-anywhere 명령에 --env-password 플래그를 덧붙이십시오.

이제 nixos-anywhere가 대상 시스템에 로그인하여 디스크를 파티션 분할, 포맷, 마운트하고 NixOS 설정을 설치합니다. 그런 다음 시스템을 재부팅합니다.

시스템 업데이트하기#

시스템을 업데이트하려면 npins를 실행하고 설정을 다시 배포하십시오:

npins update nixpkgs
nixos-rebuild switch --no-flake --target-host root@target-host

디스크 레이아웃을 변경하려는 경우가 아니라면 nixos-anywhere는 더 이상 필요하지 않습니다.

다음 단계#

참고 자료#