Convert lewis to kubernetes node

Install tmux on servers
Mount jellyfin media locally
This commit is contained in:
Pim Kunis 2024-05-26 14:34:19 +02:00
parent 266d7d905c
commit 007ff1e438
12 changed files with 39 additions and 153 deletions

View file

@ -80,6 +80,7 @@
fio fio
libva-utils libva-utils
jq jq
tmux
]; ];
boot = lib.mkIf (! machine.isRaspberryPi) { boot = lib.mkIf (! machine.isRaspberryPi) {

View file

@ -49,7 +49,7 @@
defaultDataPath = "/mnt/longhorn"; defaultDataPath = "/mnt/longhorn";
storageMinimalAvailablePercentage = 0; storageMinimalAvailablePercentage = 0;
allowRecurringJobWhileVolumeDetached = true; allowRecurringJobWhileVolumeDetached = true;
backupTarget = "nfs://lewis.dmz:/mnt/data/nfs/longhorn-backup"; backupTarget = "nfs://lewis.dmz:/mnt/longhorn/persistent/longhorn-backup";
}; };
persistence = { persistence = {

View file

@ -26,7 +26,7 @@ in
nfs = { nfs = {
server = "lewis.dmz"; server = "lewis.dmz";
path = "/mnt/data/nfs/${nfsVolume.path}"; path = "/mnt/longhorn/persistent/${nfsVolume.path}";
}; };
}; };
}) })

View file

@ -77,13 +77,24 @@
volumes = { volumes = {
config.persistentVolumeClaim.claimName = "jellyfin"; config.persistentVolumeClaim.claimName = "jellyfin";
media.persistentVolumeClaim.claimName = "media"; media.hostPath = {
path = "/mnt/longhorn/persistent/media";
type = "Directory";
};
}; };
securityContext = { securityContext = {
fsGroup = 0; fsGroup = 0;
fsGroupChangePolicy = "OnRootMismatch"; fsGroupChangePolicy = "OnRootMismatch";
}; };
affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms = [{
matchExpressions = [{
key = "hasMedia";
operator = "In";
values = [ "true" ];
}];
}];
}; };
}; };
}; };

View file

@ -4,10 +4,6 @@
kubernetesNodeLabels.storageType = "slow"; kubernetesNodeLabels.storageType = "slow";
nixosModule.lab = { nixosModule.lab = {
storage = {
kubernetesNode = true;
};
k3s = { k3s = {
enable = true; enable = true;
serverAddr = "https://jefke.dmz:6443"; serverAddr = "https://jefke.dmz:6443";

View file

@ -4,10 +4,6 @@
kubernetesNodeLabels.storageType = "fast"; kubernetesNodeLabels.storageType = "fast";
nixosModule.lab = { nixosModule.lab = {
storage = {
kubernetesNode = true;
};
k3s = { k3s = {
enable = true; enable = true;
clusterInit = true; clusterInit = true;

View file

@ -1,15 +1,19 @@
{ {
machines.lewis = { machines.lewis = {
arch = "x86_64-linux"; arch = "x86_64-linux";
kubernetesNodeLabels = {
storageType = "fast";
hasMedia = "true";
};
nixosModule = { nixosModule = {
lab = { lab = {
backups.enable = true; backups.enable = true;
data-sharing.enable = true; data-sharing.enable = true;
storage = { k3s = {
osDisk = "/dev/sda"; enable = true;
dataPartition = "/dev/nvme0n1p1"; serverAddr = "https://jefke.dmz:6443";
}; };
}; };
}; };

View file

@ -1,19 +1,12 @@
{ pkgs, lib, config, ... }: { pkgs, lib, config, ... }:
let let
cfg = config.lab.backups; cfg = config.lab.backups;
beforeEverything = pkgs.writeShellScriptBin "beforeEverything" ''
if [ -d "${cfg.snapshotLocation}" ]; then
${pkgs.btrfs-progs}/bin/btrfs subvolume delete ${cfg.snapshotLocation}
fi
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r ${cfg.subvolumeLocation} ${cfg.snapshotLocation}
'';
borgmaticConfig = pkgs.writeTextFile { borgmaticConfig = pkgs.writeTextFile {
name = "borgmatic-config.yaml"; name = "borgmatic-config.yaml";
text = lib.generators.toYAML { } { text = lib.generators.toYAML { } {
source_directories = [ cfg.snapshotLocation ]; source_directories = [ "/mnt/longhorn/persistent/longhorn-backup" ];
repositories = [ repositories = [
{ {
@ -26,16 +19,12 @@ let
} }
]; ];
exclude_patterns = [ "${cfg.snapshotLocation}/media" ];
ssh_command = "${pkgs.openssh}/bin/ssh -i ${config.age.secrets."borgbase.pem".path} -o StrictHostKeychecking=no"; ssh_command = "${pkgs.openssh}/bin/ssh -i ${config.age.secrets."borgbase.pem".path} -o StrictHostKeychecking=no";
keep_daily = 7; keep_daily = 7;
keep_weekly = 4; keep_weekly = 4;
keep_monthly = 12; keep_monthly = 12;
keep_yearly = -1; keep_yearly = -1;
encryption_passcommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets."borg_passphrase".path}"; encryption_passcommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets."borg_passphrase".path}";
before_everything = [ "${beforeEverything}/bin/beforeEverything" ];
postgresql_databases = [ ];
}; };
}; };
in in
@ -50,32 +39,16 @@ in
}; };
repoLocation = lib.mkOption { repoLocation = lib.mkOption {
default = "${config.lab.storage.dataMountPoint}/backups/nfs.borg"; default = "/mnt/longhorn/persistent/nfs.borg";
type = lib.types.str; type = lib.types.str;
description = '' description = ''
Location of the Borg repository to back up to. Location of the Borg repository to back up to.
''; '';
}; };
subvolumeLocation = lib.mkOption {
default = "${config.lab.storage.dataMountPoint}/nfs";
type = lib.types.str;
description = ''
Location of the btrfs subvolume holding the data.
'';
};
snapshotLocation = lib.mkOption {
default = "${config.lab.storage.dataMountPoint}/snapshot-nfs";
type = lib.types.str;
description = ''
Location to (temporary) create a snapshot of the subvolume.
'';
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [ borgbackup postgresql ]; environment.systemPackages = with pkgs; [ borgbackup ];
# Converted from: # Converted from:
# https://github.com/borgmatic-collective/borgmatic/tree/84823dfb912db650936e3492f6ead7e0e0d32a0f/sample/systemd # https://github.com/borgmatic-collective/borgmatic/tree/84823dfb912db650936e3492f6ead7e0e0d32a0f/sample/systemd
systemd.services.borgmatic = { systemd.services.borgmatic = {
@ -84,7 +57,6 @@ in
after = [ "network-online.target" ]; after = [ "network-online.target" ];
unitConfig.ConditionACPower = true; unitConfig.ConditionACPower = true;
preStart = "${pkgs.coreutils}/bin/sleep 10s"; preStart = "${pkgs.coreutils}/bin/sleep 10s";
path = with pkgs; [ postgresql ];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
@ -95,7 +67,6 @@ in
IOWeight = 100; IOWeight = 100;
Restart = "no"; Restart = "no";
LogRateLimitIntervalSec = 0; LogRateLimitIntervalSec = 0;
EnvironmentFile = config.age.secrets."database_passwords.env".path;
Environment = "BORG_PASSPHRASE_FILE=${config.age.secrets."borg_passphrase".path}"; Environment = "BORG_PASSPHRASE_FILE=${config.age.secrets."borg_passphrase".path}";
}; };
@ -113,7 +84,6 @@ in
}; };
age.secrets = { age.secrets = {
"database_passwords.env".file = ../secrets/database_passwords.env.age;
"borg_passphrase".file = ../secrets/borg_passphrase.age; "borg_passphrase".file = ../secrets/borg_passphrase.age;
"borgbase.pem".file = ../secrets/borgbase.pem.age; "borgbase.pem".file = ../secrets/borgbase.pem.age;
}; };

View file

@ -3,18 +3,18 @@ let
cfg = config.lab.data-sharing; cfg = config.lab.data-sharing;
nfsShares = [ nfsShares = [
"/media" "/mnt/longhorn/persistent/media"
"/media/books" "/mnt/longhorn/persistent/media/books"
"/media/movies" "/mnt/longhorn/persistent/media/movies"
"/media/music" "/mnt/longhorn/persistent/media/music"
"/media/shows" "/mnt/longhorn/persistent/media/shows"
"/longhorn-backup" "/mnt/longhorn/persistent/longhorn-backup"
]; ];
nfsExports = lib.strings.concatLines ( nfsExports = lib.strings.concatLines (
builtins.map builtins.map
(share: (share:
"${cfg.nfsRoot}${share} 192.168.30.0/16(rw,sync,no_subtree_check,no_root_squash)" "${share} 192.168.30.0/16(rw,sync,no_subtree_check,no_root_squash) 127.0.0.1/8(rw,sync,no_subtree_check,no_root_squash)"
) )
nfsShares nfsShares
); );
@ -28,20 +28,11 @@ in
Configure this server to serve our data using NFS and PostgreSQL. Configure this server to serve our data using NFS and PostgreSQL.
''; '';
}; };
nfsRoot = lib.mkOption {
default = "/mnt/data/nfs";
type = lib.types.str;
description = ''
Root directory of NFS data.
'';
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
networking.firewall.allowedTCPPorts = [ networking.firewall.allowedTCPPorts = [
2049 # NFS 2049 # NFS
5432 # PostgeSQL
111 # NFS 111 # NFS
20048 # NFS 20048 # NFS
]; ];

View file

@ -8,47 +8,16 @@ in {
The disk to be used for the machine's operating system. The disk to be used for the machine's operating system.
''; '';
}; };
dataPartition = lib.mkOption {
default = null;
type = lib.types.nullOr lib.types.str;
description = ''
Partition to be used for data storage on this machine.
'';
};
dataMountPoint = lib.mkOption {
default = "/mnt/data";
type = lib.types.str;
description = ''
Mount point of the machine's data partition.
'';
};
kubernetesNode = lib.mkOption {
default = false;
type = lib.types.bool;
description = ''
Whether to apply the Kubernetes disk setup.
'';
};
}; };
config = { config = {
fileSystems = lib.attrsets.mergeAttrsList [ fileSystems."/" = lib.mkIf machine.isRaspberryPi {
(lib.optionalAttrs ((! machine.isRaspberryPi) && (! cfg.kubernetesNode)) { device = "/dev/disk/by-label/NIXOS_SD";
"${cfg.dataMountPoint}".device = cfg.dataPartition; fsType = "ext4";
}) options = [ "noatime" ];
(lib.optionalAttrs machine.isRaspberryPi { };
"/" = {
device = "/dev/disk/by-label/NIXOS_SD";
fsType = "ext4";
options = [ "noatime" ];
};
})
];
disko = lib.mkIf (! machine.isRaspberryPi) (if cfg.kubernetesNode then { disko = lib.mkIf (! machine.isRaspberryPi) {
devices = { devices = {
disk = { disk = {
nvme = { nvme = {
@ -148,41 +117,6 @@ in {
}; };
}; };
}; };
} else { };
# TODO: Rename this to 'osDisk'. Unfortunately, we would need to run nixos-anywhere again then.
devices.disk.vdb = {
device = cfg.osDisk;
type = "disk";
content = {
type = "gpt";
partitions = {
swap.size = "100%";
ESP = {
type = "EF00";
size = "500M";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
end = "-4G";
content = {
type = "filesystem";
format = "btrfs";
mountpoint = "/";
};
};
};
};
};
});
}; };
} }

View file

@ -1,16 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 UwNSRQ XKuX/onJklTJ1ws0svIwJy1PZN1MHsf5+N3z7XGvCyY
JkyemSdV/ZcbjWLrwYLhKCE4Ln2seLR0WyYXGMepgBw
-> ssh-ed25519 JJ7S4A 9wzkTABOPcmTG7LNWvZa7dKG0Ingf+KDckZ1tL2c3QQ
IkxcStI4kwXkWj+j3PWl7FdyoVMVsiH9SZBnyffbcYQ
-> ssh-ed25519 aqswPA 3i/v1qWLseD+FrPrnAXtSoK98a6Nrb3XrHinp2QPTn0
RxuPM1oICEoF5oZAyQlCm+fOivI9sfZenZSlOGBIZK8
-> ssh-ed25519 LAPUww MkvAMN/fZiV66+ub4Q/CDTIxJ3N3cMWBT0SQajespR0
uh6SGtxR3BvsU/fTTTOnsNXD+bHNYMhTAFoc3QUtMr8
-> ssh-ed25519 vBZj5g Jiu1sEmlws4eFPriuL2oS99Q9tFCyf4Zkv/khLONvT0
cLLHcvmIb1Nb7eVmKJyYdvfulgbcZ73N0x6GWyKeJPs
-> ssh-ed25519 QP0PgA A1Raf1CiVJ5tnJXRIeS0VpCUNX/iYNzGozQxApY9KGM
998c6IZfPNW8uMttkK8xGp1hgKXBcrwuBOgOpXWPCu8
--- /Qv6sfhphlYb9WtWdmPt6RZJPHxBO4jCSgauazsHIt8
1kYiL7¸<37>Áª-Ç}—`ýŠƒÇNƒVoäCñ'ÞÛ§ýhßô[øvDŠU€pv×½¶Òõ¦~e‰Â0yœ¦ÿ—ÑÄ2`•Ý<E280A2>ºîƱŽïÑ¥ÂÔåú8/´ª ¸
÷MEÐŽh·sÈqÌâ¤|ß kتí<Ó°¡+ÊÍ9eË0óŸ¸;­)Ï?IL-ëÓJY¾gðpk+ÛíúˆHRûé5ÔÍÉÛ¥ú”§„Ø× :8·ùo©þ1¥zâs—`•_MSÒí«Q˜;Q_o]·

View file

@ -8,7 +8,6 @@ let
]; ];
encryptedFileNames = [ encryptedFileNames = [
"database_passwords.env.age"
"borg_passphrase.age" "borg_passphrase.age"
"borgbase.pem.age" "borgbase.pem.age"
"k3s-server-token.age" "k3s-server-token.age"