NixOS em Produção

Table of Contents

1 INTRO

Este é um post curto sumarizando o que eu gostaria de saber quando comecei a usar o NixOS em produção. Espero que outras pessoas achem isso útil a fim de evitar as armadilhas em que caí.

Os principais problemas com NixOS é que o manual recomenda um fluxo de trabalho que não é adequado para a implantação em produção. Especificamente o manual encoraja a

  • manter os códigos Nix na máquina de destino (i.e. /etc/nixos/{hardware-,}configuration.nix)
  • executar a construção na máquina destino
  • usar o sistema de canais do Nix para obter os códigos do Nixpkgs

Neste post eu descreverei como você pode, em vez disso,

  • construir um fechamento binário livre de fonte em uma máquina de construção
  • transferir e implantar este fechamento binário para uma máquina destino diferente

Este guia se sobrepõe substancialmente ao que o NixOps faz e você pode pensar neste guia como uma maneira de transplantar um subconjunto limitado do que NixOps faz a fim de trabalhar com outras ferramentas de provisão (como o Terraform).

Você pode também julgar este guia útil mesmo que use NixOS como um sistema operacional de desktop para lidar com cenários mais exóticos não cobertos pela ferramenta nixos-rebuild.

2 Montando o Fechamento

Vamos montar a solução final modificando passo a passo o fluxo de trabalho recomendado no manual NixOS.

Suponha que você já tenha um arquivo /etc/nixos/configuration.nix e use o comando nixos-rebuild switch a fim de implantar seu sistema. Você pode apartar-se do comando nixos-rebuild montando o fecho binário do próprio sistema. Em outras palavras, você pode reimplementar o nixos-rebuild build do zero.

A fim de fazer isso, crie o arquivo a seguir no seu sistema:

# ./nixos.nix

import <nixpkgs/nixos> {
  system = "x86_64-linux";

  configuration = {
    imports = [
      /etc/nixos/configuration.nix
    ];
  };
}

Então execute:

$ nix-build --attr system ./nixos.nix

Parabéns, você acabou de construir um fecho binário para seu sistema!

3 Implantando o Fechamento

nix-build deposita um link simbólico no diretório atual apontando para o fecho binário recém-obtido. A fim de implantar o sistema corrente para casar com o fecho obtido, execute o comando:

$ sudo ./result/bin/switch-to-configuration switch

Parabéns, você acaba de fazer o equivalente ao nixos-rebuild switch!

Como o comando acima sugere, o fecho contém um ./bin/switch-to-configuration que compreende um subconjunto de comandos que o nixos-rebuild faz. Em particular, o script switch-to-configuration aceita esses comandos:

$ ./result/bin/switch-to-configuration --help
Usage: ../../result/bin/switch-to-configuration [switch|boot|test]

switch:       make the configuration the boot default and activate now
boot:         make the configuration the boot default
test:         activate the configuration, but don't make it the boot default
dry-activate: show what would be done if this configuration were activated

4 Adicionando um Perfil

O comando nixos-rebuild realmente faz mais uma coisa além de construir o fecho binário e implantar o sistema. O comando nixos-rebuild também cria um link apontando para a configuração corrente do sistema de forma que você possa retroceder a esta configuração mais tarde. O link também funciona como uma raiz do coletor de lixo, impedindo o sistema de ser reciclado até que você remova o link (seja usando rm diretamente ou usando um utilitário de alto nível como o nix-collect-garbage)

Você pode salvar a configuração do sistema da mesma forma que o nixos-rebuild usando o comando nix-env:

$ nix-env --profile /nix/var/nix/profiles/system --set ./result

5 Inquirindo as Opções do Sistema

Você pode usar o mesmo arquivo nixos.nix para inquirir que opções você estabeleceu em seu sistema, bem como o utilitário nixos-option. Por exemplo, se você quer computar o valor final da opção networking.firewall.allowedTCPPorts, então pode executar este comando:

$ nix-instantiate --eval --strict --attr config.networking.firewall.allowedTCPPorts nixos.nix
[ 22 ]

6 Fixando Nixpkgs

Agora que você tomou controle da construção, você pode fazer coisas mais criativas, como fixar o nixpkgs para uma versão específica, de modo a não precisar mais usar os canais ou o NIX_PATH:

let
  nixpkgs = builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/b74b1cdb2fecc31ff7a127c5bc89771f887c93bb.tar.gz";
    sha256 = "0ncr4g29220amqm4riaa1xf4jz55v2nmh9fi16f1gzhww1gplk8h";
  };
in
  import "${nixpkgs}/nixos" {
    configuration = {
      imports = [
        /etc/nixos/configuration.nix
      ];
    };
    system = "x86_64-linux";
  }

De fato, isto torna sua construção completamente insensível ao NIX_PATH, eliminando uma fonte potencial de não-determinismo da construção.

7 Construindo Remotamente

Agora que você removeu nixos-rebuild da equação, você pode montar o fecho binário em uma máquina separada daquela na qual o implantará. Você pode colocar seus arquivos nixos.nix, configuration.nix e hardware-configuration.nix em um sistema controle de versão e montar o sistema via nix-build em qualquer máquina que possa conferir sua configuração no sistema de controle. Tudo o que tem que fazer é modificar o caminho de importação para um caminho relativo ao configuration.nix no mesmo repositório, em vez de um caminho absoluto:

# ./nixos.nix

let
  nixpkgs = builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/b74b1cdb2fecc31ff7a127c5bc89771f887c93bb.tar.gz";
    sha256 = "0ncr4g29220amqm4riaa1xf4jz55v2nmh9fi16f1gzhww1gplk8h";
  };
in
  import "${nixpkgs}/nixos" {
    configuration = {
      imports = [
        ./relative/path/to/configuration.nix
      ];
    };

    system = "x86_64-linux";
  }

Então tudo que sua máquina de montagem tem que fazer é:

$ git clone "[email protected]:${OWNER}/${REPOSITORY}.git"
$ nix-build --attr system "./${REPOSITORY}/path/to/nixos.nix"

Para implantar o fecho binário para outra máquina, use nix copy. Se você tem acesso via SSH à máquina de destino, então é possível copiar diretamente:

$ nix copy --to "${USER}@${MACHINE}" ./result

Se você não tem acesso SSH à máquina de destino, você pode em vez disso usar nix copy para criar um arquivo binário contendo o fecho de seu sistema:

$ # Na maquina de construção
$ nix copy --to 'file:///tmp/system' ./result

… e carregar o arquivo binário localizado em /tmp/system para a máquina destino usando seu método preferido.. Daí, importar o arquivo binário para o /nix/store na máquina destino usando nix copy:

$ # Na máquina destino
$ nix copy --from 'file:///tmp/system' ./result

Uma vez que o fecho binário está na máquina, você o instala da mesma forma que antes:

$ sudo /nix/store/.../bin/switch-to-configuration switch

… substituindo /nix/store/... com o caminho /nix/store/ do seu fecho (já que não existe link resultante na máquina destino).

8 Conclusão

É isso! Agora você deve ser capaz de salvar sua configuração NixOS num controle de versão, montar um fecho binário como parte de uma integração contínua, e implantar o fecho binário numa máquina de destino separada. Você pode agora também fixar sua construção para uma revisão específica do Nixpkgs de forma que sua montagem seja mais determinística.

Eu gostaria de dar os créditos ao meu colega de time Parnell Springmeyer que me ensinou o truque do ./result/bin/switch-to-configuration para implantar um sistema NixOS e codificou tudo isso na ferramenta nix-deploy. Também gostaria de creditar Remy Goldschmidt que treinou nosso time no verão passado e me ensinou como fixar Nixpkgs confiavelmente,

9 META

Author: Tradutor Bastardo

Created: 2020-04-04 sáb 03:17

Validate