Setting up K3s on NIX#
Flake.nix#
Below is the flake I am using for this project.
You may note I have a couple different outputs, including one configuration, and two packages (images using nixosgenerators).
Being able to use QEMU to quickly launch an image from my local pc using the ./result/bin/ folder.
The other two outputs are actual qcow and vhd images for use within my other testing environments (virt-manager and aws).
{
description = "K3s on NIXOS";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; # or unstable if you prefer
nixos-generators.url = "github:nix-community/nixos-generators";
};
outputs = {
self,
nixpkgs,
nixos-generators,
}: let
system = "x86_64-linux";
in {
nixosConfigurations = {
qemu = nixpkgs.lib.nixosSystem {
inherit system;
modules = [
./configuration.nix
{
virtualisation.vmVariant = {
virtualisation = {
emptyDiskImages = [4096];
memorySize = 2048;
diskSize = 8192;
forwardPorts = [
{
from = "host";
host.port = 10443;
guest.port = 443;
}
{
from = "host";
host.port = 10022;
guest.port = 22;
}
{
from = "host";
host.port = 16443;
guest.port = 6443;
}
# Boot Service Ports
{
from = "host";
host.port = 18442;
guest.port = 8442;
}
{
from = "host";
host.port = 18443;
guest.port = 8443;
}
];
};
boot.growPartition = true;
fileSystems."/".autoResize = true;
};
networking.hosts = {
"127.0.0.1" = ["myhost.local test-vw.jmoore53.dev test-kb.jmoore53.dev test-f3.jmoore53.dev"];
};
}
];
};
};
packages.${system} = {
qemu-image = nixos-generators.nixosGenerate {
inherit system;
format = "qcow";
modules = [
./configuration.nix
{
networking.useDHCP = true;
services.openssh.enable = true;
system.stateVersion = "25.05";
virtualisation.diskSize = 8192;
boot.growPartition = true;
fileSystems."/".autoResize = true;
}
];
};
amazon-image = nixos-generators.nixosGenerate {
inherit system;
format = "amazon";
modules = [
./configuration.nix
{
networking.useDHCP = true;
services.openssh.enable = true;
system.stateVersion = "25.05";
virtualisation.diskSize = 8192;
boot.growPartition = true;
fileSystems."/".autoResize = true;
ec2.hvm = true;
}
];
};
};
};
}Running a nix flake show gives the following:
$ nix flake show
git+file:///home/jack/projects/nik3xs?ref=refs/heads/task-885&rev=222a506e09dbd3fdcff9815f2a4b0d9769ee3b5d
├───nixosConfigurations
│ └───qemu: NixOS configuration
└───packages
└───x86_64-linux
├───amazon-image: package 'nixos-image-amazon-25.05.20250112.2f9e2f8-x86_64-linux'
└───qemu-image: package 'nixos-disk-image'To test out the image I find myself running nix build .#nixosConfigurations.qemu.config.system.build.vm
Configuration.nix#
Below you will see a couple different things to note.
- I have imported modules, most of which can be ignored for now. The one we will look at in depth will be
./modules/k3s.nix - Under services I have k3s enabled, but I have disabled traefik. This is so we can customize it with our own Traefik configuration
- I am allowing all users to SSH (maybe not as secure, but we need to ssh for testing)
- Password for user “jack” is Password123. Wow
- The firewall is disabled… for testing and for now.
{pkgs, ...}: {
imports = [
./modules/boot-unlock-service.nix
./modules/k3s-secret.nix
./modules/k3s.nix
./modules/start-restore.nix
];
networking.hostName = "l-nodet";
time.timeZone = "UTC";
nix.settings.experimental-features = ["nix-command" "flakes"];
##################
# SERVICES
##################
services = {
k3s = {
enable = true;
role = "server";
extraFlags = toString [
"--debug"
"--disable=traefik"
];
};
openssh = {
enable = true;
settings = {
Port = 22;
#PermitRootLogin = "no";
PermitRootLogin = "prohibit-password";
PasswordAuthentication = true;
#AlowUsers = ["jack"];
AlowUsers = null; #using null allows all users
};
};
};
##################
# Users
##################
users.users.jack = {
isNormalUser = true;
description = "jack";
initialPassword = "Password123"; # An idiot's luggage password, Password123
extraGroups = ["wheel"]; # rootless podman doesn't need "docker"
openssh.authorizedKeys.keys = [
"ssh-ed25519 jack@pow"
"ssh-ed25519 jack@nixos"
];
};
##################
# Firewall
##################
networking.firewall = {
enable = false;
#enable = true;
#allowedTCPPorts = [80 443 22];
};
##################
# Useful packages
##################
environment.systemPackages = with pkgs; [
vim
curl
wget
jq
openssl
nettools
restic
];
system.stateVersion = "25.05";
}With this setup k3s is running on our system. We are able to SSH to the server and the systemd service for k3s is running.