diff --git a/Makefile b/Makefile index 6fc5b49..747688a 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,9 @@ -.PHONY: help deploy deploy-gateway deploy-fileserver install-gateway install-fileserver fetch-hwconfig-gateway fetch-hwconfig-fileserver all +.PHONY: help deploy deploy-gateway deploy-fileserver deploy-k8s-server install-gateway install-fileserver install-k8s-server fetch-hwconfig-gateway fetch-hwconfig-fileserver fetch-hwconfig-k8s-server all # Hosts GATEWAY_HOST := danlin@10.202.82.3 FILESERVER_HOST := danlin@10.202.82.6 +K8S_HOST := danlin@10.202.82.7 # Default target all: deploy @@ -14,15 +15,29 @@ help: @echo " make deploy Deploy to both gateway and fileserver" @echo " make deploy-gateway Deploy to gateway only" @echo " make deploy-fileserver Deploy to fileserver only" + @echo " make deploy-k8s-server Deploy to k8s-server only" @echo " make install-gateway Run installation script for gateway" @echo " make install-fileserver Run installation script for fileserver" + @echo " make install-k8s-server Run installation script for k8s-server" @echo " make fetch-hwconfig-gateway Fetch hardware config from gateway" @echo " make fetch-hwconfig-fileserver Fetch hardware config from fileserver" + @echo " make fetch-hwconfig-k8s-server Fetch hardware config from k8s-server" @echo "" # Deployment targets deploy: deploy-gateway deploy-fileserver +deploy-k8s-server: + @echo "======================================" + @echo "Deploying k8s-server..." + @echo "======================================" + @echo "Syncing files to k8s-server..." + rsync -av --delete --exclude '.git' ./ $(K8S_HOST):/tmp/infra-nix/ + @echo "Building and switching on k8s-server..." + ssh -tt $(K8S_HOST) "cd /tmp/infra-nix && sudo nixos-rebuild switch --flake '.#k8s-server'" + @echo "✓ k8s-server deployed successfully" + @echo "" + deploy-gateway: @echo "======================================" @echo "Deploying gateway..." @@ -90,6 +105,28 @@ install-fileserver: echo "✓ Update hosts/fileserver/configuration.nix with the correct IP if needed" @echo "" +install-k8s-server: + @echo "======================================" + @echo "Installing k8s-server..." + @echo "======================================" + @read -p "Enter k8s-server IP address: " IP; \ + if [ -z "$$IP" ]; then \ + echo "Error: IP address required"; \ + exit 1; \ + fi; \ + echo "Copying install script to $$IP..."; \ + scp install/install-k8s-server.sh root@$$IP:/tmp/; \ + echo "Connecting to $$IP..."; \ + ssh root@$$IP "bash /tmp/install-k8s-server.sh"; \ + echo ""; \ + echo "Fetching hardware config from $$IP..."; \ + scp root@$$IP:/mnt/etc/nixos/hardware-configuration.nix hosts/k8s-server/hardware-configuration.nix; \ + echo "✓ Hardware config saved to hosts/k8s-server/hardware-configuration.nix"; \ + scp root@$$IP:/mnt/etc/nixos/configuration.nix hosts/k8s-server/configuration.installer.nix; \ + echo "✓ Installer config saved to hosts/k8s-server/configuration.installer.nix"; \ + echo "✓ Update hosts/k8s-server/configuration.nix with the correct IP if needed" + @echo "" + # Fetch hardware configuration targets fetch-hwconfig-gateway: @echo "======================================" @@ -106,3 +143,11 @@ fetch-hwconfig-fileserver: scp $(FILESERVER_HOST):/etc/nixos/hardware-configuration.nix hosts/fileserver/ @echo "✓ Hardware config saved to hosts/fileserver/hardware-configuration.nix" @echo "" + +fetch-hwconfig-k8s-server: + @echo "======================================" + @echo "Fetching hardware config from k8s-server..." + @echo "======================================" + scp $(K8S_HOST):/etc/nixos/hardware-configuration.nix hosts/k8s-server/ + @echo "✓ Hardware config saved to hosts/k8s-server/hardware-configuration.nix" + @echo "" diff --git a/flake.nix b/flake.nix index 626bd6b..f1b9f66 100644 --- a/flake.nix +++ b/flake.nix @@ -24,6 +24,13 @@ ./hosts/gateway/configuration.nix ]; }; + + k8s-server = lib.nixosSystem { + inherit system; + modules = [ + ./hosts/k8s-server/configuration.nix + ]; + }; }; }; } \ No newline at end of file diff --git a/hosts/k8s-server/configuration.installer.nix b/hosts/k8s-server/configuration.installer.nix new file mode 100644 index 0000000..0159ae1 --- /dev/null +++ b/hosts/k8s-server/configuration.installer.nix @@ -0,0 +1,49 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./hardware-configuration.nix ]; + + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + security.sudo.wheelNeedsPassword = false; + + networking.hostName = "k8s-server"; + networking.useDHCP = false; + networking.interfaces.ens18.ipv4.addresses = [ + { + address = "10.202.82.7"; + prefixLength = 24; + } + ]; + networking.defaultGateway = "10.202.82.1"; + networking.nameservers = [ "10.202.82.3" "10.202.82.4" ]; + + time.timeZone = "Europe/Berlin"; + + services.openssh.enable = true; + + networking.firewall = { + enable = true; + allowedTCPPorts = [ 22 6443 ]; + allowedUDPPorts = [ 8472 ]; + }; + + users.users.danlin = { + isNormalUser = true; + extraGroups = [ "wheel" ]; + initialPassword = "changeme"; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAzAW0DTpdQJaQOWDC3YJCmPc/veBQ0R3e1q9nOlWgxC danlin@MacBook-Pro-von-Daniel.fritz.box" + ]; + }; + + users.users.root.initialPassword = "root"; + + environment.systemPackages = with pkgs; [ + vim + htop + ]; + + system.stateVersion = "25.05"; +} diff --git a/hosts/k8s-server/configuration.nix b/hosts/k8s-server/configuration.nix new file mode 100644 index 0000000..46998e5 --- /dev/null +++ b/hosts/k8s-server/configuration.nix @@ -0,0 +1,23 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./hardware-configuration.nix + ../../modules/common.nix + ../../modules/kubernetes.nix + ]; + + networking.hostName = "k8s-server"; + + networking.useDHCP = false; + networking.interfaces.ens18.ipv4.addresses = [ + { + address = "10.202.82.7"; + prefixLength = 24; + } + ]; + networking.defaultGateway = "10.202.82.1"; + networking.nameservers = [ "10.202.82.3" "10.202.82.4" ]; + + system.stateVersion = "25.05"; +} diff --git a/hosts/k8s-server/hardware-configuration.nix b/hosts/k8s-server/hardware-configuration.nix new file mode 100644 index 0000000..25fe881 --- /dev/null +++ b/hosts/k8s-server/hardware-configuration.nix @@ -0,0 +1,37 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ahci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/839f8ac5-3391-4bc2-bf64-9df42ae6613b"; + fsType = "ext4"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/D25C-46DC"; + fsType = "vfat"; + options = [ "fmask=0022" "dmask=0022" ]; + }; + + swapDevices = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.ens18.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/install/install-k8s-server.sh b/install/install-k8s-server.sh new file mode 100644 index 0000000..77b59c9 --- /dev/null +++ b/install/install-k8s-server.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +set -euo pipefail + +### CONFIG ### +OS_DISK=/dev/sda +HOSTNAME=k8s-server +STATE_VERSION="25.05" +TIMEZONE="Europe/Berlin" +USERNAME="danlin" +PASSWORD="changeme" +ROOT_PASS="root" + +echo ">>> WARNUNG: ALLE DATEN auf ${OS_DISK} werden GELÖSCHT!" +echo ">>> Warte 5 Sekunden... (STRG+C zum Abbrechen)" +sleep 5 + +echo ">>> Partitioniere OS-Disk (${OS_DISK}) für EFI + ROOT..." +parted "${OS_DISK}" --script mklabel gpt +parted "${OS_DISK}" --script mkpart ESP fat32 1MiB 513MiB +parted "${OS_DISK}" --script set 1 esp on +parted "${OS_DISK}" --script mkpart primary ext4 513MiB 100% + +echo ">>> Formatiere OS-Partitionen..." +mkfs.fat -F32 "${OS_DISK}1" +mkfs.ext4 -F "${OS_DISK}2" + +echo ">>> Mounten..." +mount "${OS_DISK}2" /mnt +mkdir -p /mnt/boot +mount "${OS_DISK}1" /mnt/boot + +echo ">>> Generiere NixOS-Config..." +nixos-generate-config --root /mnt + +CONFIG=/mnt/etc/nixos/configuration.nix + +cat > "${CONFIG}" <>> Starte nixos-install..." +nixos-install + +echo ">>> Fertig. Jetzt reboot ausführen." diff --git a/modules/gateway.nix b/modules/gateway.nix index 3816068..cd291b9 100644 --- a/modules/gateway.nix +++ b/modules/gateway.nix @@ -55,6 +55,7 @@ 80 # HTTP (Caddy) 443 # HTTPS (Caddy) 2222 # External SSH to Gitea + 6443 # Kubernetes API to k8s-server ]; networking.firewall.allowedUDPPorts = [ @@ -70,6 +71,7 @@ # Hairpin NAT for LAN clients hitting gateway:2222 so replies go back via gateway extraCommands = '' iptables -t nat -A POSTROUTING -p tcp -d 10.202.82.6 --dport 2222 -j MASQUERADE + iptables -t nat -A POSTROUTING -p tcp -d 10.202.82.7 --dport 6443 -j MASQUERADE ''; forwardPorts = [ { @@ -77,6 +79,11 @@ sourcePort = 2222; destination = "10.202.82.6:2222"; } + { + proto = "tcp"; + sourcePort = 6443; + destination = "10.202.82.7:6443"; + } ]; }; } \ No newline at end of file diff --git a/modules/kubernetes.nix b/modules/kubernetes.nix new file mode 100644 index 0000000..275e235 --- /dev/null +++ b/modules/kubernetes.nix @@ -0,0 +1,30 @@ +{ config, pkgs, ... }: + +{ + ######################################## + # k3s Single-Node (Traefik disabled) + ######################################## + services.k3s = { + enable = true; + role = "server"; + # Initialize single-server cluster and disable bundled Traefik ingress. + extraFlags = toString [ + "--cluster-init" + "--disable=traefik" + "--flannel-backend=vxlan" + ]; + }; + + ######################################## + # Firewall for k3s + ######################################## + networking.firewall.enable = true; + networking.firewall.allowedTCPPorts = [ + 6443 # Kubernetes API + 10250 # Kubelet metrics + ]; + + networking.firewall.allowedUDPPorts = [ + 8472 # flannel VXLAN + ]; +}