diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..1753b05 --- /dev/null +++ b/flake.lock @@ -0,0 +1,111 @@ +{ + "nodes": { + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1781152676, + "narHash": "sha256-RxWs5ND31KzTG7wvMM+PMfUjyNpmIEr999lqNARaM5o=", + "owner": "nix-community", + "repo": "disko", + "rev": "ff8702b4de27f72b4c78573dfb89ec74e36abdf1", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1782423922, + "narHash": "sha256-qPNd6lUohHP5gcJhqQ7rLV87RwIx0xYR2A4Frb9Zjc4=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "5d320ab301cfaaca7d32514f13815d19d109f5f4", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "nix-darwin": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1781761792, + "narHash": "sha256-rCPytmKNjctLloB6UgK5CRrHSwV4b0ygxtJLPPp8R14=", + "owner": "LnL7", + "repo": "nix-darwin", + "rev": "a1fa429e945becaf60468600daf649be4ba0350c", + "type": "github" + }, + "original": { + "owner": "LnL7", + "repo": "nix-darwin", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1782335603, + "narHash": "sha256-sZkQH1CkiZtdvcaLx4sGQD9Q9h+A8qB04DRpqQCN530=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "03c72920da828594fae523aaef96f33dff10b340", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "disko": "disko", + "home-manager": "home-manager", + "nix-darwin": "nix-darwin", + "nixpkgs": "nixpkgs", + "sops-nix": "sops-nix" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1782165805, + "narHash": "sha256-478kKQBvK6SYTOdN2h9jhKJv94nbXRbFMfuL1WshErg=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "56b24064fdcaedca53553b1a6d607fd23b613a24", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/hosts/muscari/default.nix b/hosts/muscari/default.nix index 519c33f..342905b 100644 --- a/hosts/muscari/default.nix +++ b/hosts/muscari/default.nix @@ -1,6 +1,49 @@ -{ ... }: -{ - networking.hostName = "muscari"; +# muscari — k3s single-node cluster на YC (Debian 12 → NixOS 25.11 через nixos-install в tmux) +# https://git.iscg.dev/mikl/nix-config +# +# Этот host перенесён из nix-config-legacy (см. commits в legacy repo). +# VM: 158.160.166.30, 2 vCPU / 8 GB / 64 GB SSD (network-ssd), Legacy BIOS - # TODO: migrate from nix-config-legacy/hosts/muscari +{ config, pkgs, lib, ... }: +{ + imports = [ + ./disk-config.nix + ./k3s.nix + ]; + + networking = { + hostName = "muscari"; + useDHCP = true; + firewall.allowedTCPPorts = [ + 22 # SSH + 80 # HTTP (Ingress через Traefik) + 443 # HTTPS (Ingress через Traefik) + # 6443 не открываем — kubectl через SSH-туннель + ]; + }; + + # Bootloader — GRUB (Legacy BIOS mode, см. PREREQUISITES.md check 5+11) + boot.loader.grub = { + enable = true; + device = "/dev/vda"; + useOSProber = false; + }; + boot.loader.systemd-boot.enable = lib.mkForce false; + boot.loader.efi.canTouchEfiVariables = lib.mkForce false; + + # SSH ключи для mikl: forgejo .keys endpoint с sha256-pinning + # + hardcoded fallback ключ для восстановления + users.users.mikl.openssh.authorizedKeys.keyFiles = [ + (pkgs.fetchurl { + url = "https://git.iscg.dev/mikl.keys"; + sha256 = "sha256-4n6QLUPozdhHOmsRCuFn7HR9BU3nF0/GR2E7s5Lpz+Q="; + }) + ]; + + # fileSystems — определяется через disko (см. disk-config.nix) + # Не задаём явно fileSystems."/" чтобы не конфликтовать с disko + + # После nixos-install первая установка 25.11, + # потом не трогаем (NixOS convention) + system.stateVersion = "25.11"; } \ No newline at end of file diff --git a/hosts/muscari/disk-config.nix b/hosts/muscari/disk-config.nix new file mode 100644 index 0000000..787156d --- /dev/null +++ b/hosts/muscari/disk-config.nix @@ -0,0 +1,44 @@ +# disk-config.nix для muscari — Yandex Cloud VM +# YC VM из образа Debian 12: один диск /dev/vda (virtio scsi), GPT +# Используем disko для переформатирования под NixOS: +# - 512M ESP (vfat) для /boot — не используется в BIOS mode (GRUB ставит в MBR), +# но если когда-нибудь переключимся на UEFI, раздел будет готов +# - остальное → ext4 root +# +# Bootloader: GRUB (BIOS mode, см. hosts/muscari/default.nix) +# +# Перенесено из nix-config-legacy (commit 231f9d5 — диск-фикс для disko 1.13+) + +{ lib, ... }: +{ + disko.devices = { + disk.disk1 = { + device = lib.mkDefault "/dev/vda"; + type = "disk"; + content = { + type = "gpt"; + partitions = { + ESP = { + name = "ESP"; + size = "512M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + root = { + name = "root"; + size = "100%"; # disko 1.13+ требует "100%" вместо "100%FREE" + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; +} \ No newline at end of file diff --git a/hosts/muscari/k3s.nix b/hosts/muscari/k3s.nix new file mode 100644 index 0000000..d201a5b --- /dev/null +++ b/hosts/muscari/k3s.nix @@ -0,0 +1,36 @@ +# k3s daemon для muscari (single-node + Cilium CNI) +# Traefik и servicelb остаются включены (встроенные в k3s) +# Cilium ставится отдельно через Helm после старта k3s + +{ config, pkgs, lib, ... }: +{ + services.k3s = { + enable = true; + extraFlags = [ + # CNI: отключаем встроенный flannel, ставим Cilium отдельно + "--flannel-backend=none" + "--disable-network-policy" # Cilium сам делает network policy + + # CIDR для подов и сервисов (default для k3s, но фиксируем явно) + "--cluster-cidr=10.42.0.0/16" + "--service-cidr=10.43.0.0/16" + + # TLS SANs для kubectl (если подключаемся не только по IP) + "--tls-san=muscari.iscg.dev" + ]; + }; + + # Firewall: доверяем Cilium veth интерфейсам + networking.firewall = { + trustedInterfaces = [ "cali+" ]; + checkReversePath = lib.mkDefault "loose"; + }; + + # k3s-specific пакеты (НЕ в common — только для хостов с k3s) + environment.systemPackages = with pkgs; [ + kubectl + kubernetes-helm + kustomize + sops # для шифрования k8s secrets (если будем через SOPS) + ]; +} \ No newline at end of file