분산 빌드 설정하기#

Author:

Jacek Galowicz @tfc

Editor:

Valentin Gagarin @fricklerhandwerk

Nix는 여러 대의 컴퓨터에 작업을 동시에 분산하여 빌드 속도를 높일 수 있습니다.

소개#

이 튜토리얼에서는 별도의 빌드 머신을 설정하고 로컬 머신이 빌드를 해당 머신에 넘기도록 설정합니다.

무엇을 배우게 됩니까?#

다음 방법을 배웁니다.

  • 로컬 머신에서 원격 빌더에 접근해 원격 빌드를 수행할 새 사용자 만들기

  • 지속 가능한 방식으로 원격 빌더 설정하기

  • 원격 빌더의 연결과 인증 테스트하기

  • 로컬 머신이 빌드를 자동으로 분산하도록 설정하기

무엇이 필요합니까?#

  • Nix 언어에 대한 이해

  • 모듈 시스템에 대한 이해

  • 로컬 머신(예시 호스트 이름: localmachine)

    다른 머신에 빌드를 분산하는, Nix가 설치된 컴퓨터입니다.

  • 원격 머신(예시 호스트 이름: remotemachine)

    로컬 머신으로부터 빌드 작업을 받는, NixOS가 실행 중인 컴퓨터입니다. 원격 NixOS 시스템을 설정하려면 SSH를 통한 원격 머신 프로비저닝의 안내를 따르십시오.

얼마나 걸립니까?#

  • 25분

SSH 키 쌍 만들기#

로컬 머신의 Nix 데몬은 root 사용자로 실행되며 원격 머신에 자신을 인증하려면 개인 키 파일이 필요합니다. 원격 머신이 로컬 머신을 식별하려면 공개 키가 필요합니다.

로컬 머신에서 root로 다음 명령을 실행하여 SSH 키 쌍을 만드십시오.

# ssh-keygen -f /root/.ssh/remotebuild

참고

키 쌍 파일의 이름과 위치는 자유롭게 정할 수 있습니다.

원격 빌더 설정하기#

원격 머신의 NixOS 설정 디렉터리에 remote-builder.nix 파일을 만드십시오.

{
  users.users.remotebuild = {
    isSystemUser = true;
    group = "remotebuild";
    useDefaultShell = true;

    openssh.authorizedKeys.keyFiles = [ ./remotebuild.pub ];
  };

  users.groups.remotebuild = {};

  nix.settings.trusted-users = [ "remotebuild" ];
}

remotebuild.pub 파일을 이 디렉터리에 복사하십시오.

이 설정 모듈은 홈 디렉터리가 없는 새 사용자 remotebuild를 만듭니다. 로컬 머신의 root 사용자는 앞에서 생성한 SSH 키를 사용하여 SSH로 원격 빌더에 로그인할 수 있게 됩니다.

새 NixOS 모듈을 원격 머신의 기존 설정에 추가하십시오.

{
  imports = [
    ./remote-builder.nix
  ];

  # ...
}

root로 새 설정을 활성화하십시오.

nixos-rebuild switch --no-flake --target-host root@remotemachine

인증 테스트#

SSH 연결과 인증이 제대로 작동하는지 확인하십시오. 로컬 머신에서 root로 다음을 실행하십시오:

# ssh remotebuild@remotemachine -i /root/.ssh/remotebuild "echo hello"
hello

hello 메시지가 보이면 인증이 작동하는 것입니다.

이 테스트 로그인은 원격 빌더의 호스트 키를 로컬 머신의 /root/.ssh/known_hosts 파일에도 추가합니다. 이후 로그인할 때는 호스트 키 확인으로 중단되지 않습니다.

분산 빌드 설정하기#

참고

로컬 머신이 NixOS를 실행 중이라면 이 섹션을 건너뛰고 모듈 옵션을 통해 Nix를 설정하십시오.

root로 Nix 설정 파일에 다음을 추가하여 Nix가 원격 빌더를 사용하도록 설정하십시오:

# cat << EOF >> /etc/nix/nix.conf
builders = ssh-ng://remotebuild@remotebuilder $(nix-instantiate --eval -E builtins.currentSystem) /root/.ssh/remotemachine - - nixos-test,big-parallel,kvm
builders-use-substitutes = true
자세한 설명

첫 번째 줄은 다음을 지정하여 원격 머신을 원격 빌더로 등록합니다.

  • 프로토콜, 사용자, 호스트 이름

  • 로컬 머신의 시스템 유형

    이렇게 하면 해당 시스템 유형의 작업이 원격 머신에 위임됩니다.

  • SSH 키의 위치

  • 지원되는 시스템 기능 목록

    컴파일러 빌드와 NixOS VM 테스트 실행을 원격 머신에 위임하려면 반드시 이 목록을 지정해야 합니다.

자세한 내용은 builders 설정에 대한 참조 문서를 참고하십시오.

두 번째 줄은 모든 원격 빌더가 로컬 머신 대신 자체 바이너리 캐시에서 의존성을 가져오도록 지시합니다. 이는 원격 빌더의 인터넷 연결이 로컬 머신의 인터넷 연결보다 느리지 않다고 가정합니다.

이 설정을 활성화하려면 Nix 데몬을 재시작하십시오:

systemd를 사용하는 Linux에서는 root로 다음을 실행하십시오:

# systemctl restart nix-daemon.service

macOS에서는 root로 다음을 실행하십시오:

# sudo launchctl stop org.nixos.nix-daemon
# sudo launchctl start org.nixos.nix-daemon

NixOS

로컬 머신이 NixOS를 실행 중이라면 설정 디렉터리에 distributed-builds.nix 파일을 만드십시오:

{ pkgs, ... }:
{
  nix.distributedBuilds = true;
  nix.settings.builders-use-substitutes = true;

  nix.buildMachines = [
    {
      hostName = "remotebuilder";
      sshUser = "remotebuild";
      sshKey = "/root/.ssh/remotebuild";
      system = pkgs.stdenv.hostPlatform.system;
      supportedFeatures = [ "nixos-test" "big-parallel" "kvm" ];
    }
  ];
}
자세한 설명

이 설정 모듈은 분산 빌드를 활성화하고 다음을 지정하여 원격 빌더를 추가합니다:

  • SSH 호스트 이름과 사용자 이름

  • SSH 키의 위치

  • 어떤 로컬 머신의 시스템 유형

    이렇게 하면 해당 시스템 유형의 작업이 원격 머신에 위임됩니다.

  • 지원되는 시스템 기능 목록

    컴파일러 빌드와 NixOS VM 테스트 실행을 원격 머신에 위임하려면 반드시 이 목록을 지정해야 합니다.

자세한 내용은 nix.buildMachines에 대한 NixOS 옵션 문서를 참조하십시오.

builders-use-substitutes는 모든 원격 빌더가 로컬 머신 대신 자체 바이너리 캐시에서 의존성을 가져오도록 지시합니다. 이는 원격 빌더의 인터넷 연결 속도가 로컬 머신의 인터넷 연결 속도 이상이라고 가정합니다.

기존 머신 설정에 새 NixOS 모듈을 추가하십시오:

{
  imports = [
    ./distributed-builds.nix
  ];

  # ...
}

root 권한으로 새 설정을 활성화하십시오:

# nixos-rebuild switch

분산 빌드 테스트하기#

로컬 머신에서 새 derivation을 빌드해 보십시오:

$ nix-build --max-jobs 0 -E "$(cat << EOF
(import <nixpkgs> {}).writeText "test" "$(date)"
EOF
)"
this derivation will be built:
  /nix/store/9csjdxv6ir8ccnjl6ijs36izswjgchn0-test.drv
building '/nix/store/9csjdxv6ir8ccnjl6ijs36izswjgchn0-test.drv' on 'ssh://remotebuilder'...
copying 0 paths...
copying 1 paths...
copying path '/nix/store/hvj5vyg4723nly1qh5a8daifbi1yisb3-test' from 'ssh://remotebuilder'...
/nix/store/hvj5vyg4723nly1qh5a8daifbi1yisb3-test

결과 derivation은 현재 시스템 시간에 의존하므로 호출할 때마다 달라지며, 따라서 로컬 캐시에는 절대 존재할 수 없습니다. --max-jobs 0 명령줄 인수는 Nix가 이를 원격 빌더에서 빌드하도록 강제합니다.

마지막 출력 줄에는 출력 경로가 포함되어 있으며, 이는 빌드 배포판이 예상대로 동작함을 나타냅니다.

원격 빌더 설정 최적화하기#

병렬성을 극대화하고, 자동 가비지 컬렉션을 활성화하고, Nix 빌드가 모든 메모리를 소비하지 않도록 하려면 remote-builder.nix 설정 모듈에 다음 줄을 추가하십시오:

 {
   users.users.remotebuild = {
     isNormalUser = true;
     createHome = false;
     group = "remotebuild";

     openssh.authorizedKeys.keyFiles = [ ./remotebuild.pub ];
   };

   users.groups.remotebuild = {};

-  nix.settings.trusted-users = [ "remotebuild" ];
+  nix = {
+    nrBuildUsers = 64;
+    settings = {
+      trusted-users = [ "remotebuild" ];
+
+      min-free = 10 * 1024 * 1024;
+      max-free = 200 * 1024 * 1024;

+      max-jobs = "auto";
+      cores = 0;
+    };
+  };

+  systemd.services.nix-daemon.serviceConfig = {
+    MemoryAccounting = true;
+    MemoryMax = "90%";
+    OOMScoreAdjust = 500;
+  };
}

팁

nix.settings에서 사용할 수 있는 옵션에 대한 자세한 내용은 Nix 참조 매뉴얼을 참조하십시오.

원격 빌더마다 성능 특성이 다를 수 있습니다. 각 nix.buildMachines 항목에 대해 원격 빌더별로 maxJobs, speedFactor, supportedFeatures 속성을 올바르게 설정하십시오. 이렇게 하면 로컬 머신의 Nix가 빌드를 최적의 방식으로 분산하는 데 도움이 됩니다.

팁

자세한 내용은 nix.buildMachines에 대한 NixOS 옵션 문서를 참조하십시오.

중간자 공격 시나리오로부터 빌드 배포판을 보호하려면 nix.buildMachines.*.publicHostKey 필드를 각 원격 빌더의 공개 호스트 키로 설정하십시오.

다음 단계#

여러 빌더를 설정하려면 각 원격 빌더에 대해 원격 빌더 설정하기 섹션의 안내를 반복하십시오. 새 원격 빌더를 모두 분산 빌드 설정하기 섹션에 나온 nix.buildMachines 속성에 추가하십시오.

팁

외부 트래픽을 줄이려면 원격 빌드 머신이 바이너리 캐시를 호스팅하도록 설정하고, 이를 우선 바이너리 캐시로 사용하십시오.

대안#

  • nixbuild.net - 서비스형 Nix 원격 빌더

  • Hercules CI - 자동 빌드 배포판을 갖춘 지속적 통합

  • garnix - 빌드 배포판을 갖춘 호스팅형 지속적 통합

참고 자료#