120 lines
3.9 KiB
Nix
120 lines
3.9 KiB
Nix
{pkgs, config, ...}:
|
|
|
|
with pkgs.lib;
|
|
|
|
let
|
|
cfg = config.services.k3s-cluster;
|
|
agentTokenFilename = cfg.agentTokenFile;
|
|
agentTokenFileArg = ''--agent-token-file ${escapeShellArg agentTokenFilename}'';
|
|
serverTokenFilename = "/etc/k3s-server-token.txt";
|
|
serverTokenFileArg = "--token-file ${escapeShellArg serverTokenFilename}";
|
|
serverArg = if (cfg.leader != null) then "--server https://${escapeShellArg cfg.leader}:6443" else "";
|
|
in
|
|
{
|
|
|
|
options = with types; {
|
|
services.k3s-cluster.secretNamespace = mkOption {
|
|
type = nullOr str;
|
|
description = ''
|
|
namespace used with deterministic-passwords to isolate the
|
|
secrets for this cluster. this should be the same for all
|
|
members of the cluster, agent or server, and different for all
|
|
other clusters.
|
|
'';
|
|
default = null;
|
|
};
|
|
services.k3s-cluster.enabled = mkEnableOption "k3s cluster";
|
|
|
|
services.k3s-cluster.leader = mkOption {
|
|
default = null;
|
|
type = nullOr str;
|
|
description = ''
|
|
hostname or IP of cluster leader
|
|
|
|
This should be set to null (the default) for a cluster leader.
|
|
|
|
For a member server, this should be set to an address which may
|
|
be used to reach the cluster leader from this host.
|
|
|
|
After completion of cluster formation, this may be set to any
|
|
member server. This is a viable path forward when the original
|
|
leader dies.
|
|
|
|
This string will be wrapped in https://...:6443
|
|
'';
|
|
};
|
|
|
|
services.k3s-cluster.agentTokenFile = mkOption {
|
|
default = "/etc/k3s-agent-token.txt";
|
|
type = str;
|
|
description = "agent token file path for agents and servers";
|
|
};
|
|
services.k3s-cluster.serverTokenFile = mkOption {
|
|
default = "/etc/k3s-server-token.txt";
|
|
type = str;
|
|
description = "server token file path for servers";
|
|
};
|
|
services.k3s-cluster.role = mkOption {
|
|
default = "server";
|
|
type = str;
|
|
description = "server or agent, passed on to k3s";
|
|
};
|
|
};
|
|
|
|
|
|
config = { services.k3s = mkIf cfg.enabled (
|
|
if (cfg.role == "server") then {
|
|
extraFlags = mkForce "--cluster-init ${serverArg} ${agentTokenFileArg} ${serverTokenFileArg}";
|
|
enable = mkForce true;
|
|
role = mkForce "server";
|
|
} else {
|
|
extraFlags = mkForce "${agentTokenFileArg}";
|
|
role = "agent";
|
|
serverAddr = "https://${cfg.leader}:6443";
|
|
enable = mkForce true;
|
|
}
|
|
);
|
|
|
|
systemd = mkIf (cfg.enabled && cfg.leader == null && cfg.role == "server") {
|
|
sockets = {
|
|
tokenCAHash = {
|
|
listenStreams = [ "0.0.0.0:65479" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
socketConfig.Accept = "yes";
|
|
};
|
|
};
|
|
services = {
|
|
"tokenCAHash@" = {
|
|
script = ''
|
|
cat /var/lib/rancher/k3s/server/agent-token|cut -d: -f 1
|
|
'';
|
|
startLimitIntervalSec = 0;
|
|
serviceConfig.Type = "oneshot";
|
|
serviceConfig.StandardInput = "socket";
|
|
};
|
|
};
|
|
};
|
|
|
|
networking.firewall.allowedTCPPorts = mkIf cfg.enabled [ 6443 53 65479 ];
|
|
networking.firewall.allowedUDPPorts = mkIf cfg.enabled [ 53 ];
|
|
|
|
environment.deterministic-passwords.secrets = mkIf (cfg.enabled) {
|
|
"k3s-agent-token" = {
|
|
namespace = cfg.secretNamespace;
|
|
destination = agentTokenFilename;
|
|
before = ["k3s.service"];
|
|
writer = ''
|
|
echo "$(nc ${if cfg.leader == null then "localhost" else cfg.leader} 65479 < /dev/null)::server:$secret" > "$destination"
|
|
'';
|
|
};
|
|
"k3s-server-token" = mkIf (cfg.role == "server") {
|
|
namespace = cfg.secretNamespace;
|
|
destination = serverTokenFilename;
|
|
before = ["k3s.service"];
|
|
writer = ''
|
|
echo "$(nc ${if cfg.leader == null then "localhost" else cfg.leader} 65479 < /dev/null)::server:$secret" > "$destination"
|
|
'';
|
|
};
|
|
};};
|
|
}
|