From 7109768862e51cfe0413c0dfd565e38711c8de21 Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sun, 24 Mar 2024 21:23:17 +0100 Subject: [PATCH 1/4] deploy metallb use helmnix for helm deployments --- flake.lock | 198 +++++++++++++++++++++++++++++- flake.nix | 7 +- kubernetes/kubenix-namespace.yaml | 4 - nix/flake/kubenix.nix | 100 +++++++++------ 4 files changed, 259 insertions(+), 50 deletions(-) delete mode 100644 kubernetes/kubenix-namespace.yaml diff --git a/flake.lock b/flake.lock index 33b0b4a..fa0e44f 100644 --- a/flake.lock +++ b/flake.lock @@ -189,6 +189,41 @@ "type": "github" } }, + "flake-utils_4": { + "inputs": { + "systems": "systems_6" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "id": "flake-utils", + "type": "indirect" + } + }, + "flake-utils_5": { + "inputs": { + "systems": "systems_7" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "home-manager": { "inputs": { "nixpkgs": [ @@ -220,15 +255,16 @@ "treefmt": "treefmt" }, "locked": { - "lastModified": 1705801181, - "narHash": "sha256-vH+n5qMnwFCx3LMON2hQMi9PjMpmTraGYXe1czJTfAg=", - "owner": "hall", + "lastModified": 1711308696, + "narHash": "sha256-Epx4yztlFp3mNPhMKWgiiSp6Q067pxW9o50ak6WFwxg=", + "owner": "pizzapim", "repo": "kubenix", - "rev": "76b8053b27b062b11f0c9b495050cc55606ac9dc", + "rev": "4ee31f48510b89743d83b7681faea1077fe925b7", "type": "github" }, "original": { - "owner": "hall", + "owner": "pizzapim", + "ref": "fix-protocol", "repo": "kubenix", "type": "github" } @@ -255,6 +291,66 @@ "type": "github" } }, + "nix-github-actions": { + "inputs": { + "nixpkgs": [ + "nixhelm", + "poetry2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1698974481, + "narHash": "sha256-yPncV9Ohdz1zPZxYHQf47S8S0VrnhV7nNhCawY46hDA=", + "owner": "nix-community", + "repo": "nix-github-actions", + "rev": "4bb5e752616262457bc7ca5882192a564c0472d2", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-github-actions", + "type": "github" + } + }, + "nix-kube-generators": { + "locked": { + "lastModified": 1702548734, + "narHash": "sha256-2pREm/iZ1FyyFuukt/B3nud2NYTUImy5vqc2tESoP9g=", + "owner": "farcaller", + "repo": "nix-kube-generators", + "rev": "fb7a70a8cd76aa76fdf3281123582693aec486a7", + "type": "github" + }, + "original": { + "owner": "farcaller", + "repo": "nix-kube-generators", + "type": "github" + } + }, + "nixhelm": { + "inputs": { + "flake-utils": "flake-utils_4", + "nix-kube-generators": "nix-kube-generators", + "nixpkgs": [ + "nixpkgs" + ], + "poetry2nix": "poetry2nix" + }, + "locked": { + "lastModified": 1711242197, + "narHash": "sha256-UWOb8Aj10O8XshwKA6xVivU0wFfQwVNqLERocVXRgUk=", + "owner": "farcaller", + "repo": "nixhelm", + "rev": "8523ddbdf40f833d3c1421546767513ca57bceea", + "type": "github" + }, + "original": { + "owner": "farcaller", + "repo": "nixhelm", + "type": "github" + } + }, "nixos-hardware": { "locked": { "lastModified": 1710783728, @@ -319,6 +415,31 @@ "type": "github" } }, + "poetry2nix": { + "inputs": { + "flake-utils": "flake-utils_5", + "nix-github-actions": "nix-github-actions", + "nixpkgs": [ + "nixhelm", + "nixpkgs" + ], + "systems": "systems_8", + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1702365004, + "narHash": "sha256-IRFvmyP1uk1hchRVxaXTqu6YoZCvMM/NVtUf2hD2Tag=", + "owner": "nix-community", + "repo": "poetry2nix", + "rev": "c12ac880114d52a3cad5fa02b00f2e2090e89982", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "poetry2nix", + "type": "github" + } + }, "root": { "inputs": { "agenix": "agenix", @@ -328,6 +449,7 @@ "flake-utils": "flake-utils_2", "kubenix": "kubenix", "microvm": "microvm", + "nixhelm": "nixhelm", "nixos-hardware": "nixos-hardware", "nixpkgs": "nixpkgs_2", "nixpkgs-unstable": "nixpkgs-unstable" @@ -423,6 +545,50 @@ "type": "github" } }, + "systems_6": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_7": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_8": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "id": "systems", + "type": "indirect" + } + }, "treefmt": { "inputs": { "nixpkgs": [ @@ -444,6 +610,28 @@ "type": "github" } }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nixhelm", + "poetry2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1699786194, + "narHash": "sha256-3h3EH1FXQkIeAuzaWB+nK0XK54uSD46pp+dMD3gAcB4=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "e82f32aa7f06bbbd56d7b12186d555223dc399d1", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, "utils": { "inputs": { "systems": "systems_2" diff --git a/flake.nix b/flake.nix index 76a0d4b..0a3f9e0 100644 --- a/flake.nix +++ b/flake.nix @@ -29,7 +29,12 @@ }; kubenix = { - url = "github:hall/kubenix"; + url = "github:pizzapim/kubenix/fix-protocol"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + nixhelm = { + url = "github:farcaller/nixhelm"; inputs.nixpkgs.follows = "nixpkgs"; }; }; diff --git a/kubernetes/kubenix-namespace.yaml b/kubernetes/kubenix-namespace.yaml deleted file mode 100644 index 37ce8b6..0000000 --- a/kubernetes/kubenix-namespace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: kubenix diff --git a/nix/flake/kubenix.nix b/nix/flake/kubenix.nix index f6b5762..1d67f18 100644 --- a/nix/flake/kubenix.nix +++ b/nix/flake/kubenix.nix @@ -1,60 +1,80 @@ -{ self, flake-utils, kubenix, ... }: flake-utils.lib.eachDefaultSystem +{ self, flake-utils, kubenix, nixhelm, ... }: flake-utils.lib.eachDefaultSystem (system: { kubenix = kubenix.packages.${system}.default.override { specialArgs.flake = self; module = { kubenix, ... }: { - imports = [ kubenix.modules.k8s ]; + imports = [ kubenix.modules.k8s kubenix.modules.helm ]; kubernetes.kubeconfig = "~/.kube/config"; kubenix.project = "home"; - kubernetes.resources = { - deployments.cyberchef.spec = { - replicas = 3; - selector.matchLabels.app = "cyberchef"; + kubernetes = { + namespace = "kubenix"; - template = { - metadata.labels.app = "cyberchef"; + resources = { + namespaces = { + kubenix = { }; - spec = { - containers.cyberchef = { - image = "mpepping/cyberchef"; + metallb-system.metadata.labels = { + "pod-security.kubernetes.io/enforce" = "privileged"; + "pod-security.kubernetes.io/audit" = "privileged"; + "pod-security.kubernetes.io/warn" = "privileged"; + }; + }; - ports = [{ - containerPort = 8000; - protocol = "TCP"; - }]; + + deployments.cyberchef.spec = { + replicas = 3; + selector.matchLabels.app = "cyberchef"; + + template = { + metadata.labels.app = "cyberchef"; + + spec = { + containers.cyberchef = { + image = "mpepping/cyberchef"; + + ports = [{ + containerPort = 8000; + protocol = "TCP"; + }]; + }; }; }; }; - }; - services.cyberchef.spec = { - selector.app = "cyberchef"; + services.cyberchef.spec = { + selector.app = "cyberchef"; - ports = [{ - protocol = "TCP"; - port = 80; - targetPort = 8000; - }]; - }; - - ingresses.cyberchef.spec = { - ingressClassName = "traefik"; - - rules = [{ - host = "cyberchef.kun.is"; - - http.paths = [{ - path = "/"; - pathType = "Prefix"; - - backend.service = { - name = "cyberchef"; - port.number = 80; - }; + ports = [{ + protocol = "TCP"; + port = 80; + targetPort = 8000; }]; - }]; + }; + + ingresses.cyberchef.spec = { + ingressClassName = "traefik"; + + rules = [{ + host = "cyberchef.kun.is"; + + http.paths = [{ + path = "/"; + pathType = "Prefix"; + + backend.service = { + name = "cyberchef"; + port.number = 80; + }; + }]; + }]; + }; + }; + + helm.releases.metallb = { + chart = nixhelm.chartsDerivations.${system}.metallb.metallb; + namespace = "metallb-system"; }; }; }; From b4d6a9f46d7ff9b8ed80d3ae26db31be962fbc07 Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sun, 24 Mar 2024 22:11:12 +0100 Subject: [PATCH 2/4] add demo of metallb working --- kubernetes/ip-address-pool.yaml | 8 +++++++ kubernetes/l2-advertisement.yaml | 5 +++++ kubernetes/loadbalancer-test.yaml | 35 +++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 kubernetes/ip-address-pool.yaml create mode 100644 kubernetes/l2-advertisement.yaml create mode 100644 kubernetes/loadbalancer-test.yaml diff --git a/kubernetes/ip-address-pool.yaml b/kubernetes/ip-address-pool.yaml new file mode 100644 index 0000000..98f7820 --- /dev/null +++ b/kubernetes/ip-address-pool.yaml @@ -0,0 +1,8 @@ +apiVersion: metallb.io/v1beta1 +kind: IPAddressPool +metadata: + name: main + namespace: metallb-system +spec: + addresses: + - 192.168.40.100-192.168.40.253 diff --git a/kubernetes/l2-advertisement.yaml b/kubernetes/l2-advertisement.yaml new file mode 100644 index 0000000..f304fdc --- /dev/null +++ b/kubernetes/l2-advertisement.yaml @@ -0,0 +1,5 @@ +apiVersion: metallb.io/v1beta1 +kind: L2Advertisement +metadata: + name: main + namespace: metallb-system diff --git a/kubernetes/loadbalancer-test.yaml b/kubernetes/loadbalancer-test.yaml new file mode 100644 index 0000000..dd83b9f --- /dev/null +++ b/kubernetes/loadbalancer-test.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +kind: Service +metadata: + name: loadbalancer-test + # annotations: + # metallb.universe.tf/loadBalancerIPs: 192.168.1.100 +spec: + ports: + - port: 80 + targetPort: 8000 + selector: + app: loadbalancer-test + type: LoadBalancer +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: loadbalancer-test + labels: + app: loadbalancer-test +spec: + replicas: 3 + selector: + matchLabels: + app: loadbalancer-test + template: + metadata: + labels: + app: loadbalancer-test + spec: + containers: + - name: loadbalancer-test + image: mpepping/cyberchef + ports: + - containerPort: 8000 From 3124436b4670d78e6c79b41cdc32b17ba56467a5 Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Mon, 25 Mar 2024 21:25:43 +0100 Subject: [PATCH 3/4] add dummy custom types for metallb manage metallb ip address pool and l2advertisements in nix --- docker_swarm/playbooks/stacks.yml | 1 + kubernetes/ip-address-pool.yaml | 8 -------- kubernetes/l2-advertisement.yaml | 5 ----- nix/flake/kubenix.nix | 28 ++++++++++++++++++++++++++++ 4 files changed, 29 insertions(+), 13 deletions(-) delete mode 100644 kubernetes/ip-address-pool.yaml delete mode 100644 kubernetes/l2-advertisement.yaml diff --git a/docker_swarm/playbooks/stacks.yml b/docker_swarm/playbooks/stacks.yml index 862a97a..ced4d6c 100644 --- a/docker_swarm/playbooks/stacks.yml +++ b/docker_swarm/playbooks/stacks.yml @@ -3,6 +3,7 @@ hosts: manager roles: - {role: traefik, tags: traefik} + - {role: freshrss, tags: freshrss} - {role: forgejo, tags: forgejo} - {role: radicale, tags: radicale} - {role: hedgedoc, tags: hedgedoc} diff --git a/kubernetes/ip-address-pool.yaml b/kubernetes/ip-address-pool.yaml deleted file mode 100644 index 98f7820..0000000 --- a/kubernetes/ip-address-pool.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: metallb.io/v1beta1 -kind: IPAddressPool -metadata: - name: main - namespace: metallb-system -spec: - addresses: - - 192.168.40.100-192.168.40.253 diff --git a/kubernetes/l2-advertisement.yaml b/kubernetes/l2-advertisement.yaml deleted file mode 100644 index f304fdc..0000000 --- a/kubernetes/l2-advertisement.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: metallb.io/v1beta1 -kind: L2Advertisement -metadata: - name: main - namespace: metallb-system diff --git a/nix/flake/kubenix.nix b/nix/flake/kubenix.nix index 1d67f18..31c2742 100644 --- a/nix/flake/kubenix.nix +++ b/nix/flake/kubenix.nix @@ -11,6 +11,26 @@ kubernetes = { namespace = "kubenix"; + customTypes = { + # HACK: These are dummy custom types. + # This is needed, because the CRDs imported as a chart are not available as Nix modules + # There is no validation whatsoever on resources defined using these types! + # See: https://github.com/hall/kubenix/issues/34 + ipaddresspool = { + attrName = "ipaddresspools"; + group = "metallb.io"; + version = "v1beta1"; + kind = "IPAddressPool"; + }; + + l2advertisement = { + attrName = "l2advertisements"; + group = "metallb.io"; + version = "v1beta1"; + kind = "L2Advertisement"; + }; + }; + resources = { namespaces = { kubenix = { }; @@ -70,11 +90,19 @@ }]; }]; }; + + ipaddresspools.main = { + metadata.namespace = "metallb-system"; + spec.addresses = [ "192.168.40.100-192.168.40.253" ]; + }; + + l2advertisements.main.metadata.namespace = "metallb-system"; }; helm.releases.metallb = { chart = nixhelm.chartsDerivations.${system}.metallb.metallb; namespace = "metallb-system"; + includeCRDs = true; }; }; }; From bef9d8c474be383bd970932e31fc133bf412114e Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Tue, 26 Mar 2024 20:26:02 +0100 Subject: [PATCH 4/4] wip k3s cluster --- docker_swarm/roles/traefik/services.yml | 4 +- flake.nix | 2 +- .../{kubenix.nix => kubenix/default.nix} | 48 ++++----- nix/flake/kubenix/freshrss.nix | 97 +++++++++++++++++++ nix/modules/k3s/default.nix | 4 +- 5 files changed, 129 insertions(+), 26 deletions(-) rename nix/flake/{kubenix.nix => kubenix/default.nix} (67%) create mode 100644 nix/flake/kubenix/freshrss.nix diff --git a/docker_swarm/roles/traefik/services.yml b/docker_swarm/roles/traefik/services.yml index 8f75e2a..5a99eed 100644 --- a/docker_swarm/roles/traefik/services.yml +++ b/docker_swarm/roles/traefik/services.yml @@ -3,7 +3,9 @@ http: k3s: loadBalancer: servers: - - url: http://jefke.dmz + # TODO: This WILL break when the cluster is reprovisioned and another IP addrss is chosen. + # The load balancer service for Traefik is automatically provisioned by k3s, unsure how to statically assign the IP address. + - url: http://192.168.40.101 esrom: loadBalancer: servers: diff --git a/flake.nix b/flake.nix index 0a3f9e0..d3137c5 100644 --- a/flake.nix +++ b/flake.nix @@ -52,7 +52,7 @@ ./nix/flake/checks.nix ./nix/flake/deploy.nix ./nix/flake/nixos.nix - ./nix/flake/kubenix.nix + ./nix/flake/kubenix ] // (flake-utils.lib.eachDefaultSystem (system: { formatter = nixpkgs.legacyPackages.${system}.nixfmt; })); diff --git a/nix/flake/kubenix.nix b/nix/flake/kubenix/default.nix similarity index 67% rename from nix/flake/kubenix.nix rename to nix/flake/kubenix/default.nix index 31c2742..312fd52 100644 --- a/nix/flake/kubenix.nix +++ b/nix/flake/kubenix/default.nix @@ -4,27 +4,31 @@ specialArgs.flake = self; module = { kubenix, ... }: { - imports = [ kubenix.modules.k8s kubenix.modules.helm ]; + imports = [ + kubenix.modules.k8s + kubenix.modules.helm + # ./freshrss.nix + ]; kubernetes.kubeconfig = "~/.kube/config"; kubenix.project = "home"; kubernetes = { - namespace = "kubenix"; + # namespace = "kubenix"; customTypes = { # HACK: These are dummy custom types. - # This is needed, because the CRDs imported as a chart are not available as Nix modules - # There is no validation whatsoever on resources defined using these types! + # This is needed, because the CRDs imported as a chart are not available as Nix modules. + # There is no nix-based validation on resources defined using these types! # See: https://github.com/hall/kubenix/issues/34 - ipaddresspool = { - attrName = "ipaddresspools"; + ipAddressPool = { + attrName = "ipAddressPools"; group = "metallb.io"; version = "v1beta1"; kind = "IPAddressPool"; }; - l2advertisement = { - attrName = "l2advertisements"; + l2Advertisement = { + attrName = "l2Advertisements"; group = "metallb.io"; version = "v1beta1"; kind = "L2Advertisement"; @@ -32,16 +36,15 @@ }; resources = { - namespaces = { - kubenix = { }; - - metallb-system.metadata.labels = { - "pod-security.kubernetes.io/enforce" = "privileged"; - "pod-security.kubernetes.io/audit" = "privileged"; - "pod-security.kubernetes.io/warn" = "privileged"; - }; - }; + # namespaces = { + # kubenix = { }; + # metallb-system.metadata.labels = { + # "pod-security.kubernetes.io/enforce" = "privileged"; + # "pod-security.kubernetes.io/audit" = "privileged"; + # "pod-security.kubernetes.io/warn" = "privileged"; + # }; + # }; deployments.cyberchef.spec = { replicas = 3; @@ -91,17 +94,18 @@ }]; }; - ipaddresspools.main = { - metadata.namespace = "metallb-system"; - spec.addresses = [ "192.168.40.100-192.168.40.253" ]; + ipAddressPools.main = { + # metadata.namespace = "metallb-system"; + spec.addresses = [ "192.168.40.100-192.168.40.254" ]; }; - l2advertisements.main.metadata.namespace = "metallb-system"; + # l2Advertisements.main.metadata.namespace = "metallb-system"; + l2Advertisements.main.metadata = { }; }; helm.releases.metallb = { chart = nixhelm.chartsDerivations.${system}.metallb.metallb; - namespace = "metallb-system"; + # namespace = "metallb-system"; includeCRDs = true; }; }; diff --git a/nix/flake/kubenix/freshrss.nix b/nix/flake/kubenix/freshrss.nix new file mode 100644 index 0000000..62d8b08 --- /dev/null +++ b/nix/flake/kubenix/freshrss.nix @@ -0,0 +1,97 @@ +{ + kubernetes.resources = { + configMaps.freshrss.data = { + TZ = "Europe/Amsterdam"; + CRON_MIN = "2,32"; + ADMIN_EMAIL = "pim@kunis.nl"; + PUBLISHED_PORT = "443"; + }; + + secrets.freshrss.stringData.adminPassword = "ref+file:///home/pim/.config/home/vals.yaml"; + + persistentVolumeClaims.freshrss.spec = { + accessModes = [ "ReadWriteOnce" ]; + storageClassName = "local-path"; + resources.requests.storage = "1Mi"; + }; + + deployments.freshrss = { + metadata.labels.app = "freshrss"; + + spec = { + selector.matchLabels.app = "freshrss"; + + template = { + metadata.labels.app = "freshrss"; + + spec = { + containers.freshrss = { + image = "freshrss/freshrss:edge"; + + ports = [{ + containerPort = 80; + protocol = "TCP"; + }]; + + envFrom = [{ configMapRef.name = "freshrss"; }]; + env = [ + { + name = "ADMIN_PASSWORD"; + valueFrom.secretKeyRef = { + name = "freshrss"; + key = "adminPassword"; + }; + } + { + name = "ADMIN_API_PASSWORD"; + valueFrom.secretKeyRef = { + name = "freshrss"; + key = "adminPassword"; + }; + } + ]; + + volumeMounts = [{ + name = "data"; + mountPath = "/var/www/FreshRSS/data"; + }]; + }; + + volumes = [{ + name = "data"; + persistentVolumeClaim.claimName = "freshrss"; + }]; + }; + }; + }; + }; + + services.freshrss.spec = { + selector.app = "freshrss"; + + ports = [{ + protocol = "TCP"; + port = 80; + targetPort = 80; + }]; + }; + + ingresses.freshrss.spec = { + ingressClassName = "traefik"; + + rules = [{ + host = "freshrss.k3s.kun.is"; + + http.paths = [{ + path = "/"; + pathType = "Prefix"; + + backend.service = { + name = "freshrss"; + port.number = 80; + }; + }]; + }]; + }; + }; +} diff --git a/nix/modules/k3s/default.nix b/nix/modules/k3s/default.nix index 51f121d..a8730c3 100644 --- a/nix/modules/k3s/default.nix +++ b/nix/modules/k3s/default.nix @@ -20,7 +20,7 @@ in { services.k3s = { enable = true; role = "server"; - extraFlags = "--tls-san ${config.networking.fqdn} --data-dir ${config.lab.storage.dataMountPoint}/k3s"; + extraFlags = "--tls-san ${config.networking.fqdn}"; }; system.activationScripts.k3s-bootstrap.text = @@ -30,7 +30,7 @@ in { }).config.kubernetes.result; in '' - ln -sf ${k3sBootstrapFile} ${config.lab.storage.dataMountPoint}/k3s/server/manifests/k3s-bootstrap.json + ln -sf ${k3sBootstrapFile} /var/lib/rancher/k3s/server/manifests/k3s-bootstrap.json ''; }; }