(nixos-vms)=

# NixOS 가상 머신

```{contributors}
:authors: olafklingt, domenkozar
:editors: fricklerhandwerk
```

NixOS의 가장 중요한 기능 중 하나는 설치할 패키지, 실행할 서비스, 그 밖의 설정과 옵션을 포함하여 시스템 전체를 선언적으로 설정할 수 있다는 점입니다.

NixOS 설정을 사용하면 가상 머신에서 NixOS를 테스트하고 사용할 수 있으며, 가상 머신은 완전한 "베어 메탈" 설치에 비해 더 가벼운 옵션입니다.

## 무엇을 배우게 됩니까?

이 튜토리얼은 NixOS 가상 머신을 만드는 방법을 소개합니다. 가상 머신은 NixOS 설정을 실험하거나 디버깅하는 데 유용한 도구입니다.

## 무엇이 필요합니까?

- 가상화를 지원하는 Linux 시스템
- (선택 사항) 그래픽 가상 머신을 실행하기 위한 그래픽 환경
- 정상적으로 동작하는 [Nix 설치](https://nix.dev/install-nix)
- [Nix 언어](reading-nix-language)에 대한 기본 지식

:::{important}
NixOS 설정은 [NixOS 모듈](https://nixos.org/manual/nixos/stable/index.html#sec-writing-modules) 규약을 따르는 Nix 언어 함수입니다. 모듈 시스템에 대한 자세한 설명은 [](module-system-deep-dive) 튜토리얼을 확인하십시오.
:::

## 기본 NixOS 설정에서 시작하기

:::{note}
이 튜토리얼은 `configuration.nix`를 기본 원리부터 차근차근 작성하며 각 단계를 설명합니다. 원하시면 [샘플 설정](sample-nixos-config) 절로 바로 건너뛸 수 있습니다.
:::

최소한의 `configuration.nix`에서 시작합니다:

```nix
{ config, pkgs, ... }:

{
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  system.stateVersion = "24.05";
}
```

로그인할 수 있도록 반환되는 속성 집합에 다음 줄을 추가하십시오:

```nix
  users.users.alice = {
    isNormalUser = true;
    extraGroups = [ "wheel" ];
  };
```

또한 이 사용자의 비밀번호를 지정해야 합니다. 시연 목적으로만, 사용자 설정에 `initialPassword` 옵션을 추가하여 안전하지 않은 평문 비밀번호를 지정합니다:

```nix
   initialPassword = "test";
```

예시로 가벼운 프로그램 두 개를 추가합니다:

```nix
  environment.systemPackages = with pkgs; [
    cowsay
    lolcat
  ];
```

:::{warning}
무엇을 하는지 정확히 알지 못한다면 이 예시 밖에서는 평문 비밀번호를 사용하지 마십시오. 더 안전한 대안은 [`initialHashedPassword`](https://nixos.org/manual/nixos/stable/options.html#opt-users.extraUsers._name_.initialHashedPassword) 또는 [`ssh.authorizedKeys`](https://nixos.org/manual/nixos/stable/options.html#opt-users.extraUsers._name_.openssh.authorizedKeys.keys)를 참고하십시오.
:::

(sample-nixos-config)=
### 샘플 설정

완성된 `configuration.nix` 파일은 다음과 같습니다:

```nix
{ config, pkgs, ... }:
{
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  users.users.alice = {
    isNormalUser = true;
    extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
    initialPassword = "test";
  };

  environment.systemPackages = with pkgs; [
    cowsay
    lolcat
  ];

  system.stateVersion = "24.05";
}
```

## NixOS 설정으로 QEMU 기반 가상 머신 만들기

NixOS 가상 머신은 `nix-build` 명령으로 생성합니다:

```shell-session
$ nix-build '<nixpkgs/nixos>' -A vm -I nixpkgs=channel:nixos-24.05 -I nixos-config=./configuration.nix
```

이 명령은 상대 경로로 지정한 NixOS 설정을 사용하여 NixOS `nixos-24.05` 릴리스의 `vm` 속성을 빌드합니다.

::::{dropdown} 자세한 설명

- [`nix-build`](https://nix.dev/manual/nix/stable/command-ref/nix-build.html)의 위치 인수는 빌드할 derivation의 경로입니다. 이 경로는 [derivation으로 평가되는 Nix 표현식](derivations)에서 얻을 수 있습니다.

  가상 머신 빌드 헬퍼는 [`nixpkgs` 저장소](https://github.com/NixOS/nixpkgs)의 일부인 NixOS에 정의되어 있습니다. 따라서 [조회 경로](lookup-path-tutorial) `<nixpkgs/nixos>`를 사용합니다.

- [`-A` 옵션](https://nix.dev/manual/nix/stable/command-ref/opt-common.html#opt-attr)은 제공된 Nix 표현식 `<nixpkgs/nixos>`에서 선택할 속성을 지정합니다.

  가상 머신을 빌드하기 위해 [`nixos/default.nix`](https://github.com/NixOS/nixpkgs/blob/7c164f4bea71d74d98780ab7be4f9105630a2eba/nixos/default.nix#L19)에 정의된 `vm` 속성을 선택합니다.

- [`-I` 옵션](https://nix.dev/manual/nix/stable/command-ref/opt-common.html#opt-I)은 검색 경로 앞에 항목을 추가합니다.

  여기서는 `nixpkgs`가 [특정 버전의 Nixpkgs](ref-pinning-nixpkgs)를 가리키도록 설정하고, `nix-config`를 현재 디렉터리의 `configuration.nix` 파일로 설정합니다.
::::

## 가상 머신 실행하기

이전 명령은 작업 디렉터리에 `result`라는 이름의 링크를 생성했습니다. 이 링크는 가상 머신이 들어 있는 디렉터리를 가리킵니다.

```shell-session
$ ls -R ./result
result:
bin  system

result/bin:
run-nixos-vm
```

가상 머신을 실행하십시오:

```shell-session
$ QEMU_KERNEL_PARAMS=console=ttyS0 ./result/bin/run-nixos-vm -nographic; reset
```

이 명령은 `-nographic` 옵션 때문에 현재 터미널에서 QEMU를 실행합니다. 또한 `console=ttyS0` 옵션으로 인해 부팅 과정이 표시되며, 부팅 과정은 콘솔 로그인 화면에서 끝납니다.

비밀번호 `test`를 사용하여 `alice`로 로그인하십시오. 지정한 대로 프로그램을 실제로 사용할 수 있는지 확인하십시오:

```shell-session
$ cowsay hello | lolcat
```

가상 머신을 종료하여 빠져나오십시오:

```shell-session
$ sudo poweroff
```

:::{note}
사용자를 `wheel`에 추가하는 것을 잊었거나 비밀번호를 설정하지 않았다면, 다른 터미널에서 가상 머신을 중지하십시오:

```shell-session
$ sudo pkill qemu
```
:::

가상 머신을 실행하면 현재 디렉터리에 `nixos.qcow2` 파일이 생성됩니다. 이 디스크 이미지 파일에는 가상 머신의 동적 상태가 들어 있습니다. 이 파일은 사용자 비밀번호와 같은 이전 실행의 상태를 유지하므로 디버깅에 방해가 될 수 있습니다.

설정을 변경할 때는 이 파일을 삭제하십시오:

```shell-session
$ rm nixos.qcow2
```

## 그래픽 VM에서 GNOME 실행하기

그래픽 사용자 인터페이스가 있는 가상 머신을 만들려면 설정에 다음 줄을 추가하십시오:

```nix
  # Enable the X11 windowing system.
  services.xserver.enable = true;

  # Enable the GNOME Desktop Environment.
  services.xserver.displayManager.gdm.enable = true;
  services.xserver.desktopManager.gnome.enable = true;
```

이 세 줄은 X11, (로그인할 수 있도록) GDM 디스플레이 관리자, 그리고 데스크톱 관리자로 Gnome을 활성화합니다.

:::{tip}

`installation-cd-graphical-gnome.nix` 모듈을 사용하여 설정 파일을 처음부터 생성할 수도 있습니다:

```shell-session
nix-shell -I nixpkgs=channel:nixos-24.05 -p "$(cat <<EOF
  let
    pkgs = import <nixpkgs> { config = {}; overlays = []; };
    iso-config = pkgs.path + /nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix;
    nixos = pkgs.nixos iso-config;
  in nixos.config.system.build.nixos-generate-config
EOF
)"
```

```shell-session
$ nixos-generate-config --dir ./
```

::::

완성된 `configuration.nix` 파일은 다음과 같습니다:

```nix
{ config, pkgs, ... }:
{
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  services.xserver.enable = true;

  services.xserver.displayManager.gdm.enable = true;
  services.xserver.desktopManager.gnome.enable = true;

  users.users.alice = {
    isNormalUser = true;
    extraGroups = [ "wheel" ];
    initialPassword = "test";
  };

  system.stateVersion = "24.05";
}
```

그래픽 출력을 얻으려면 특별한 옵션 없이 가상 머신을 실행하십시오:

```shell-session
$ nix-build '<nixpkgs/nixos>' -A vm -I nixpkgs=channel:nixos-24.05 -I nixos-config=./configuration.nix
$ ./result/bin/run-nixos-vm
```

## VM에서 Wayland 컴포지터로 Sway 실행하기

Wayland 컴포지터로 바꾸려면 `services.xserver.desktopManager.gnome`을 비활성화하고 `programs.sway`를 활성화하십시오:

```{code-block} diff
:caption: configuration.nix
-  services.xserver.desktopManager.gnome.enable = true;
+  programs.sway.enable = true;
```

:::{note}
가상 머신에서 Wayland 컴포지터를 실행하면 QEMU가 사용하는 디스플레이 드라이버 때문에 문제가 생길 수 있습니다. 사용 가능한 드라이버 중에서 Sway와 호환되는 드라이버를 선택해야 합니다. 옵션은 [QEMU 사용자 문서](https://www.qemu.org/docs/master/system/qemu-manpage.html)를 참조하십시오. 한 가지 방법은 `virtio-vga` 드라이버를 사용하는 것입니다:

```shell-session
$ ./result/bin/run-nixos-vm -device virtio-vga
```

QEMU에 전달할 인수는 설정 파일에도 추가할 수 있습니다:

```nix
{ config, pkgs, ... }:
{
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  services.xserver.enable = true;

  services.xserver.displayManager.gdm.enable = true;
  programs.sway.enable = true;

  imports = [ <nixpkgs/nixos/modules/virtualisation/qemu-vm.nix> ];
  virtualisation.qemu.options = [
    "-device virtio-vga"
  ];

  users.users.alice = {
    isNormalUser = true;
    extraGroups = [ "wheel" ];
    initialPassword = "test";
  };

  system.stateVersion = "24.05";
}
```

:::

NixOS 매뉴얼의 [X11](https://nixos.org/manual/nixos/stable/#sec-x11) 및 [Wayland](https://nixos.org/manual/nixos/stable/#sec-wayland) 장에는 대체 창 관리자 목록이 있습니다.

## 참고 자료

- [NixOS 매뉴얼: NixOS 설정](https://nixos.org/manual/nixos/stable/index.html#ch-configuration).
- [NixOS 매뉴얼: 모듈](https://nixos.org/manual/nixos/stable/index.html#sec-writing-modules).
- [NixOS 매뉴얼 옵션 참조](https://nixos.org/manual/nixos/stable/options.html).
- [NixOS 매뉴얼: 설정 변경하기](https://nixos.org/manual/nixos/stable/#sec-changing-config).
- [NixOS 소스 코드: `tools.nix`의 `configuration template`](https://github.com/NixOS/nixpkgs/blob/4e0525a8cdb370d31c1e1ba2641ad2a91fded57d/nixos/modules/installer/tools/tools.nix#L122-L226).
- [NixOS 소스 코드: `default.nix`의 `vm` 속성](https://github.com/NixOS/nixpkgs/blob/master/nixos/default.nix).
- [Nix 매뉴얼: `nix-build`](https://nix.dev/manual/nix/stable/command-ref/nix-build.html).
- [Nix 매뉴얼: 공통 명령줄 옵션](https://nix.dev/manual/nix/stable/command-ref/opt-common.html).
- 더 많은 런타임 옵션은 [QEMU 사용자 문서](https://www.qemu.org/docs/master/system/qemu-manpage.html)를 참고하십시오
- 선언적 가상 머신 설정은 [NixOS 옵션 검색: `virtualisation.qemu`](https://search.nixos.org/options?query=virtualisation.qemu)를 참고하십시오

## 다음 단계

- [](module-system-deep-dive)
- [](integration-testing-vms)
- [](bootable-iso-image)
