about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/virtualisation/lxd.nix
blob: 53b89a9f55b13a50ab66e66b4bf20f9ad68eae28 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# Systemd services for lxd.

{ config, lib, pkgs, ... }:

with lib;

let

  cfg = config.virtualisation.lxd;
  zfsCfg = config.boot.zfs;

in

{
  ###### interface

  options = {

    virtualisation.lxd = {
      enable = mkOption {
        type = types.bool;
        default = false;
        description = ''
          This option enables lxd, a daemon that manages
          containers. Users in the "lxd" group can interact with
          the daemon (e.g. to start or stop containers) using the
          <command>lxc</command> command line tool, among others.
        '';
      };

      package = mkOption {
        type = types.package;
        default = pkgs.lxd;
        defaultText = "pkgs.lxd";
        description = ''
          The LXD package to use.
        '';
      };

      lxcPackage = mkOption {
        type = types.package;
        default = pkgs.lxc;
        defaultText = "pkgs.lxc";
        description = ''
          The LXC package to use with LXD (required for AppArmor profiles).
        '';
      };

      zfsPackage = mkOption {
        type = types.package;
        default = with pkgs; if zfsCfg.enableUnstable then zfsUnstable else zfs;
        defaultText = "pkgs.zfs";
        description = ''
          The ZFS package to use with LXD.
        '';
      };

      zfsSupport = mkOption {
        type = types.bool;
        default = false;
        description = ''
          Enables lxd to use zfs as a storage for containers.

          This option is enabled by default if a zfs pool is configured
          with nixos.
        '';
      };
      recommendedSysctlSettings = mkOption {
        type = types.bool;
        default = false;
        description = ''
          enables various settings to avoid common pitfalls when
          running containers requiring many file operations.
          Fixes errors like "Too many open files" or
          "neighbour: ndisc_cache: neighbor table overflow!".
          See https://lxd.readthedocs.io/en/latest/production-setup/
          for details.
        '';
      };
    };
  };

  ###### implementation

  config = mkIf cfg.enable {

    environment.systemPackages = [ cfg.package ];

    security.apparmor = {
      enable = true;
      profiles = [
        "${cfg.lxcPackage}/etc/apparmor.d/usr.bin.lxc-start"
        "${cfg.lxcPackage}/etc/apparmor.d/lxc-containers"
      ];
      packages = [ cfg.lxcPackage ];
    };

    systemd.services.lxd = {
      description = "LXD Container Management Daemon";

      wantedBy = [ "multi-user.target" ];
      after = [ "systemd-udev-settle.service" ];

      path = lib.optional cfg.zfsSupport cfg.zfsPackage;

      preStart = ''
        mkdir -m 0755 -p /var/lib/lxc/rootfs
      '';

      serviceConfig = {
        ExecStart = "@${cfg.package}/bin/lxd lxd --group lxd";
        Type = "simple";
        KillMode = "process"; # when stopping, leave the containers alone
        LimitMEMLOCK = "infinity";
        LimitNOFILE = "1048576";
        LimitNPROC = "infinity";
        TasksMax = "infinity";
      };
    };

    users.groups.lxd.gid = config.ids.gids.lxd;

    users.users.root = {
      subUidRanges = [ { startUid = 1000000; count = 65536; } ];
      subGidRanges = [ { startGid = 1000000; count = 65536; } ];
    };

    boot.kernel.sysctl = mkIf cfg.recommendedSysctlSettings {
      "fs.inotify.max_queued_events" = 1048576;
      "fs.inotify.max_user_instances" = 1048576;
      "fs.inotify.max_user_watches" = 1048576;
      "vm.max_map_count" = 262144;
      "kernel.dmesg_restrict" = 1;
      "net.ipv4.neigh.default.gc_thresh3" = 8192;
      "net.ipv6.neigh.default.gc_thresh3" = 8192;
      "kernel.keys.maxkeys" = 2000;
    };
  };
}