2020-04-17 07:39:54 -07:00
|
|
|
{
|
|
|
|
config,
|
|
|
|
lib,
|
|
|
|
pkgs,
|
|
|
|
...
|
|
|
|
}:
|
|
|
|
let
|
|
|
|
cfg = config.services.k3s;
|
2022-06-15 16:06:35 -03:00
|
|
|
removeOption =
|
|
|
|
config: instruction:
|
|
|
|
lib.mkRemovedOptionModule (
|
|
|
|
[
|
|
|
|
"services"
|
|
|
|
"k3s"
|
|
|
|
]
|
|
|
|
++ config
|
|
|
|
) instruction;
|
2023-12-15 10:43:22 +01:00
|
|
|
|
|
|
|
manifestDir = "/var/lib/rancher/k3s/server/manifests";
|
|
|
|
chartDir = "/var/lib/rancher/k3s/server/static/charts";
|
|
|
|
imageDir = "/var/lib/rancher/k3s/agent/images";
|
2024-08-03 23:15:52 -07:00
|
|
|
containerdConfigTemplateFile = "/var/lib/rancher/k3s/agent/etc/containerd/config.toml.tmpl";
|
2025-01-15 08:28:08 +01:00
|
|
|
yamlFormat = pkgs.formats.yaml { };
|
|
|
|
yamlDocSeparator = builtins.toFile "yaml-doc-separator" "\n---\n";
|
|
|
|
# Manifests need a valid YAML suffix to be respected by k3s
|
|
|
|
mkManifestTarget =
|
|
|
|
name: if (lib.hasSuffix ".yaml" name || lib.hasSuffix ".yml" name) then name else name + ".yaml";
|
|
|
|
# Produces a list containing all duplicate manifest names
|
|
|
|
duplicateManifests =
|
|
|
|
with builtins;
|
|
|
|
lib.intersectLists (attrNames cfg.autoDeployCharts) (attrNames cfg.manifests);
|
|
|
|
# Produces a list containing all duplicate chart names
|
|
|
|
duplicateCharts =
|
|
|
|
with builtins;
|
|
|
|
lib.intersectLists (attrNames cfg.autoDeployCharts) (attrNames cfg.charts);
|
|
|
|
|
|
|
|
# Converts YAML -> JSON -> Nix
|
|
|
|
fromYaml =
|
|
|
|
path:
|
|
|
|
with builtins;
|
|
|
|
fromJSON (
|
|
|
|
readFile (
|
|
|
|
pkgs.runCommand "${path}-converted.json" { nativeBuildInputs = [ yq-go ]; } ''
|
|
|
|
yq --no-colors --output-format json ${path} > $out
|
|
|
|
''
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2025-05-05 11:58:39 +02:00
|
|
|
# Replace prefixes and characters that are problematic in file names
|
2025-01-15 08:28:08 +01:00
|
|
|
cleanHelmChartName =
|
2025-05-05 11:58:39 +02:00
|
|
|
name:
|
|
|
|
let
|
|
|
|
woPrefix = lib.removePrefix "https://" (lib.removePrefix "oci://" name);
|
|
|
|
in
|
2025-01-15 08:28:08 +01:00
|
|
|
lib.replaceStrings
|
|
|
|
[
|
|
|
|
"/"
|
|
|
|
":"
|
|
|
|
]
|
|
|
|
[
|
|
|
|
"-"
|
|
|
|
"-"
|
2025-05-05 11:58:39 +02:00
|
|
|
]
|
|
|
|
woPrefix;
|
2023-12-15 10:43:22 +01:00
|
|
|
|
2025-01-15 08:28:08 +01:00
|
|
|
# Fetch a Helm chart from a public registry. This only supports a basic Helm pull.
|
|
|
|
fetchHelm =
|
|
|
|
{
|
|
|
|
name,
|
|
|
|
repo,
|
|
|
|
version,
|
|
|
|
hash ? lib.fakeHash,
|
|
|
|
}:
|
2025-05-05 11:58:39 +02:00
|
|
|
let
|
|
|
|
isOci = lib.hasPrefix "oci://" repo;
|
|
|
|
pullCmd = if isOci then repo else "--repo ${repo} ${name}";
|
|
|
|
name' = if isOci then "${repo}-${version}" else "${repo}-${name}-${version}";
|
|
|
|
in
|
|
|
|
pkgs.runCommand (cleanHelmChartName "${name'}.tgz")
|
2025-01-15 08:28:08 +01:00
|
|
|
{
|
|
|
|
inherit (lib.fetchers.normalizeHash { } { inherit hash; }) outputHash outputHashAlgo;
|
|
|
|
impureEnvVars = lib.fetchers.proxyImpureEnvVars;
|
|
|
|
nativeBuildInputs = with pkgs; [
|
|
|
|
kubernetes-helm
|
|
|
|
cacert
|
|
|
|
];
|
|
|
|
}
|
|
|
|
''
|
2025-05-05 11:58:39 +02:00
|
|
|
helm pull ${pullCmd} --version ${version}
|
2025-01-15 08:28:08 +01:00
|
|
|
mv ./*.tgz $out
|
|
|
|
'';
|
|
|
|
|
|
|
|
# Returns the path to a YAML manifest file
|
|
|
|
mkExtraDeployManifest =
|
|
|
|
x:
|
|
|
|
# x is a derivation that provides a YAML file
|
|
|
|
if lib.isDerivation x then
|
|
|
|
x.outPath
|
|
|
|
# x is an attribute set that needs to be converted to a YAML file
|
|
|
|
else if builtins.isAttrs x then
|
|
|
|
(yamlFormat.generate "extra-deploy-chart-manifest" x)
|
|
|
|
# assume x is a path to a YAML file
|
|
|
|
else
|
|
|
|
x;
|
|
|
|
|
|
|
|
# Generate a HelmChart custom resource.
|
|
|
|
mkHelmChartCR =
|
|
|
|
name: value:
|
2023-12-15 10:43:22 +01:00
|
|
|
let
|
2025-01-15 08:28:08 +01:00
|
|
|
chartValues = if (lib.isPath value.values) then fromYaml value.values else value.values;
|
|
|
|
# use JSON for values as it's a subset of YAML and understood by the k3s Helm controller
|
|
|
|
valuesContent = builtins.toJSON chartValues;
|
2023-12-15 10:43:22 +01:00
|
|
|
in
|
2025-01-15 08:28:08 +01:00
|
|
|
# merge with extraFieldDefinitions to allow setting advanced values and overwrite generated
|
|
|
|
# values
|
|
|
|
lib.recursiveUpdate {
|
|
|
|
apiVersion = "helm.cattle.io/v1";
|
|
|
|
kind = "HelmChart";
|
|
|
|
metadata = {
|
|
|
|
inherit name;
|
|
|
|
namespace = "kube-system";
|
|
|
|
};
|
|
|
|
spec = {
|
|
|
|
inherit valuesContent;
|
|
|
|
inherit (value) targetNamespace createNamespace;
|
|
|
|
chart = "https://%{KUBERNETES_API}%/static/charts/${name}.tgz";
|
|
|
|
};
|
|
|
|
} value.extraFieldDefinitions;
|
|
|
|
|
|
|
|
# Generate a HelmChart custom resource together with extraDeploy manifests. This
|
|
|
|
# generates possibly a multi document YAML file that the auto deploy mechanism of k3s
|
|
|
|
# deploys.
|
|
|
|
mkAutoDeployChartManifest = name: value: {
|
|
|
|
# target is the final name of the link created for the manifest file
|
|
|
|
target = mkManifestTarget name;
|
|
|
|
inherit (value) enable package;
|
|
|
|
# source is a store path containing the complete manifest file
|
|
|
|
source = pkgs.concatText "auto-deploy-chart-${name}.yaml" (
|
|
|
|
[
|
|
|
|
(yamlFormat.generate "helm-chart-manifest-${name}.yaml" (mkHelmChartCR name value))
|
|
|
|
]
|
2025-06-02 15:54:57 +02:00
|
|
|
# alternate the YAML doc separator (---) and extraDeploy manifests to create
|
2025-01-15 08:28:08 +01:00
|
|
|
# multi document YAMLs
|
|
|
|
++ (lib.concatMap (x: [
|
|
|
|
yamlDocSeparator
|
|
|
|
(mkExtraDeployManifest x)
|
|
|
|
]) value.extraDeploy)
|
|
|
|
);
|
|
|
|
};
|
2023-12-15 10:43:22 +01:00
|
|
|
|
2025-01-15 08:28:08 +01:00
|
|
|
autoDeployChartsModule = lib.types.submodule (
|
|
|
|
{ config, ... }:
|
|
|
|
{
|
|
|
|
options = {
|
|
|
|
enable = lib.mkOption {
|
|
|
|
type = lib.types.bool;
|
|
|
|
default = true;
|
|
|
|
example = false;
|
|
|
|
description = ''
|
|
|
|
Whether to enable the installation of this Helm chart. Note that setting
|
|
|
|
this option to `false` will not uninstall the chart from the cluster, if
|
|
|
|
it was previously installed. Please use the the `--disable` flag or `.skip`
|
|
|
|
files to delete/disable Helm charts, as mentioned in the
|
|
|
|
[docs](https://docs.k3s.io/installation/packaged-components#disabling-manifests).
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
repo = lib.mkOption {
|
|
|
|
type = lib.types.nonEmptyStr;
|
|
|
|
example = "https://kubernetes.github.io/ingress-nginx";
|
|
|
|
description = ''
|
|
|
|
The repo of the Helm chart. Only has an effect if `package` is not set.
|
|
|
|
The Helm chart is fetched during build time and placed as a `.tgz` archive on the
|
|
|
|
filesystem.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
name = lib.mkOption {
|
|
|
|
type = lib.types.nonEmptyStr;
|
|
|
|
example = "ingress-nginx";
|
|
|
|
description = ''
|
|
|
|
The name of the Helm chart. Only has an effect if `package` is not set.
|
|
|
|
The Helm chart is fetched during build time and placed as a `.tgz` archive on the
|
|
|
|
filesystem.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
version = lib.mkOption {
|
|
|
|
type = lib.types.nonEmptyStr;
|
|
|
|
example = "4.7.0";
|
|
|
|
description = ''
|
|
|
|
The version of the Helm chart. Only has an effect if `package` is not set.
|
|
|
|
The Helm chart is fetched during build time and placed as a `.tgz` archive on the
|
|
|
|
filesystem.
|
|
|
|
'';
|
|
|
|
};
|
2023-12-15 10:43:22 +01:00
|
|
|
|
2025-01-15 08:28:08 +01:00
|
|
|
hash = lib.mkOption {
|
|
|
|
type = lib.types.str;
|
|
|
|
example = "sha256-ej+vpPNdiOoXsaj1jyRpWLisJgWo8EqX+Z5VbpSjsPA=";
|
2025-04-26 13:32:40 +02:00
|
|
|
default = "";
|
2025-01-15 08:28:08 +01:00
|
|
|
description = ''
|
|
|
|
The hash of the packaged Helm chart. Only has an effect if `package` is not set.
|
|
|
|
The Helm chart is fetched during build time and placed as a `.tgz` archive on the
|
|
|
|
filesystem.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
package = lib.mkOption {
|
|
|
|
type = with lib.types; either path package;
|
|
|
|
example = lib.literalExpression "../my-helm-chart.tgz";
|
|
|
|
description = ''
|
|
|
|
The packaged Helm chart. Overwrites the options `repo`, `name`, `version`
|
|
|
|
and `hash` in case of conflicts.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
targetNamespace = lib.mkOption {
|
|
|
|
type = lib.types.nonEmptyStr;
|
|
|
|
default = "default";
|
|
|
|
example = "kube-system";
|
|
|
|
description = "The namespace in which the Helm chart gets installed.";
|
|
|
|
};
|
|
|
|
|
|
|
|
createNamespace = lib.mkOption {
|
|
|
|
type = lib.types.bool;
|
|
|
|
default = false;
|
|
|
|
example = true;
|
|
|
|
description = "Whether to create the target namespace if not present.";
|
|
|
|
};
|
2023-12-15 10:43:22 +01:00
|
|
|
|
2025-01-15 08:28:08 +01:00
|
|
|
values = lib.mkOption {
|
|
|
|
type = with lib.types; either path attrs;
|
|
|
|
default = { };
|
|
|
|
example = {
|
|
|
|
replicaCount = 3;
|
|
|
|
hostName = "my-host";
|
|
|
|
server = {
|
|
|
|
name = "nginx";
|
|
|
|
port = 80;
|
|
|
|
};
|
2023-12-15 10:43:22 +01:00
|
|
|
};
|
2025-01-15 08:28:08 +01:00
|
|
|
description = ''
|
|
|
|
Override default chart values via Nix expressions. This is equivalent to setting
|
|
|
|
values in a `values.yaml` file.
|
|
|
|
|
|
|
|
WARNING: The values (including secrets!) specified here are exposed unencrypted
|
|
|
|
in the world-readable nix store.
|
|
|
|
'';
|
|
|
|
};
|
2023-12-15 10:43:22 +01:00
|
|
|
|
2025-01-15 08:28:08 +01:00
|
|
|
extraDeploy = lib.mkOption {
|
|
|
|
type = with lib.types; listOf (either path attrs);
|
|
|
|
default = [ ];
|
|
|
|
example = lib.literalExpression ''
|
|
|
|
[
|
|
|
|
../manifests/my-extra-deployment.yaml
|
|
|
|
{
|
|
|
|
apiVersion = "v1";
|
|
|
|
kind = "Service";
|
|
|
|
metadata = {
|
|
|
|
name = "app-service";
|
|
|
|
};
|
|
|
|
spec = {
|
|
|
|
selector = {
|
|
|
|
"app.kubernetes.io/name" = "MyApp";
|
|
|
|
};
|
|
|
|
ports = [
|
|
|
|
{
|
|
|
|
name = "name-of-service-port";
|
|
|
|
protocol = "TCP";
|
|
|
|
port = 80;
|
|
|
|
targetPort = "http-web-svc";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
};
|
|
|
|
}
|
|
|
|
];
|
|
|
|
'';
|
|
|
|
description = "List of extra Kubernetes manifests to deploy with this Helm chart.";
|
|
|
|
};
|
2023-12-15 10:43:22 +01:00
|
|
|
|
2025-01-15 08:28:08 +01:00
|
|
|
extraFieldDefinitions = lib.mkOption {
|
|
|
|
inherit (yamlFormat) type;
|
|
|
|
default = { };
|
|
|
|
example = {
|
|
|
|
spec = {
|
|
|
|
bootstrap = true;
|
|
|
|
helmVersion = "v2";
|
|
|
|
backOffLimit = 3;
|
|
|
|
jobImage = "custom-helm-controller:v0.0.1";
|
|
|
|
};
|
2023-12-15 10:43:22 +01:00
|
|
|
};
|
2025-01-15 08:28:08 +01:00
|
|
|
description = ''
|
|
|
|
Extra HelmChart field definitions that are merged with the rest of the HelmChart
|
|
|
|
custom resource. This can be used to set advanced fields or to overwrite
|
|
|
|
generated fields. See https://docs.k3s.io/helm#helmchart-field-definitions
|
|
|
|
for possible fields.
|
|
|
|
'';
|
2023-12-15 10:43:22 +01:00
|
|
|
};
|
2025-01-15 08:28:08 +01:00
|
|
|
};
|
2023-12-15 10:43:22 +01:00
|
|
|
|
2025-01-15 08:28:08 +01:00
|
|
|
config.package = lib.mkDefault (fetchHelm {
|
|
|
|
inherit (config)
|
|
|
|
repo
|
|
|
|
name
|
|
|
|
version
|
|
|
|
hash
|
|
|
|
;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
manifestModule = lib.types.submodule (
|
|
|
|
{
|
|
|
|
name,
|
|
|
|
config,
|
|
|
|
options,
|
|
|
|
...
|
|
|
|
}:
|
|
|
|
{
|
|
|
|
options = {
|
|
|
|
enable = lib.mkOption {
|
|
|
|
type = lib.types.bool;
|
|
|
|
default = true;
|
|
|
|
description = "Whether this manifest file should be generated.";
|
2023-12-15 10:43:22 +01:00
|
|
|
};
|
|
|
|
|
2025-01-15 08:28:08 +01:00
|
|
|
target = lib.mkOption {
|
|
|
|
type = lib.types.nonEmptyStr;
|
|
|
|
example = "manifest.yaml";
|
|
|
|
description = ''
|
|
|
|
Name of the symlink (relative to {file}`${manifestDir}`).
|
|
|
|
Defaults to the attribute name.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
content = lib.mkOption {
|
|
|
|
type = with lib.types; nullOr (either attrs (listOf attrs));
|
|
|
|
default = null;
|
|
|
|
description = ''
|
|
|
|
Content of the manifest file. A single attribute set will
|
|
|
|
generate a single document YAML file. A list of attribute sets
|
|
|
|
will generate multiple documents separated by `---` in a single
|
|
|
|
YAML file.
|
|
|
|
'';
|
2023-12-15 10:43:22 +01:00
|
|
|
};
|
|
|
|
|
2025-01-15 08:28:08 +01:00
|
|
|
source = lib.mkOption {
|
|
|
|
type = lib.types.path;
|
|
|
|
example = lib.literalExpression "./manifests/app.yaml";
|
|
|
|
description = ''
|
|
|
|
Path of the source `.yaml` file.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = {
|
|
|
|
target = lib.mkDefault (mkManifestTarget name);
|
|
|
|
source = lib.mkIf (config.content != null) (
|
|
|
|
let
|
|
|
|
name' = "k3s-manifest-" + builtins.baseNameOf name;
|
|
|
|
docName = "k3s-manifest-doc-" + builtins.baseNameOf name;
|
|
|
|
mkSource =
|
|
|
|
value:
|
|
|
|
if builtins.isList value then
|
|
|
|
pkgs.concatText name' (
|
|
|
|
lib.concatMap (x: [
|
|
|
|
yamlDocSeparator
|
|
|
|
(yamlFormat.generate docName x)
|
|
|
|
]) value
|
|
|
|
)
|
|
|
|
else
|
|
|
|
yamlFormat.generate name' value;
|
|
|
|
in
|
|
|
|
lib.mkDerivedConfig options.content mkSource
|
|
|
|
);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
);
|
2020-04-17 07:39:54 -07:00
|
|
|
in
|
|
|
|
{
|
2022-06-15 16:06:35 -03:00
|
|
|
imports = [ (removeOption [ "docker" ] "k3s docker option is no longer supported.") ];
|
|
|
|
|
2020-04-17 07:39:54 -07:00
|
|
|
# interface
|
|
|
|
options.services.k3s = {
|
2024-08-28 21:18:55 +02:00
|
|
|
enable = lib.mkEnableOption "k3s";
|
2020-04-17 07:39:54 -07:00
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
package = lib.mkPackageOption pkgs "k3s" { };
|
2020-04-17 07:39:54 -07:00
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
role = lib.mkOption {
|
2020-04-17 07:39:54 -07:00
|
|
|
description = ''
|
|
|
|
Whether k3s should run as a server or agent.
|
2022-08-30 09:27:29 +01:00
|
|
|
|
|
|
|
If it's a server:
|
|
|
|
|
|
|
|
- By default it also runs workloads as an agent.
|
|
|
|
- Starts by default as a standalone server using an embedded sqlite datastore.
|
|
|
|
- Configure `clusterInit = true` to switch over to embedded etcd datastore and enable HA mode.
|
|
|
|
- Configure `serverAddr` to join an already-initialized HA cluster.
|
|
|
|
|
|
|
|
If it's an agent:
|
|
|
|
|
|
|
|
- `serverAddr` is required.
|
2020-04-17 07:39:54 -07:00
|
|
|
'';
|
|
|
|
default = "server";
|
2024-08-28 21:18:55 +02:00
|
|
|
type = lib.types.enum [
|
2020-04-17 07:39:54 -07:00
|
|
|
"server"
|
|
|
|
"agent"
|
|
|
|
];
|
|
|
|
};
|
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
serverAddr = lib.mkOption {
|
|
|
|
type = lib.types.str;
|
2022-08-30 09:27:29 +01:00
|
|
|
description = ''
|
|
|
|
The k3s server to connect to.
|
|
|
|
|
|
|
|
Servers and agents need to communicate each other. Read
|
|
|
|
[the networking docs](https://rancher.com/docs/k3s/latest/en/installation/installation-requirements/#networking)
|
|
|
|
to know how to configure the firewall.
|
|
|
|
'';
|
2020-04-17 07:39:54 -07:00
|
|
|
example = "https://10.0.0.10:6443";
|
|
|
|
default = "";
|
|
|
|
};
|
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
clusterInit = lib.mkOption {
|
|
|
|
type = lib.types.bool;
|
2022-08-30 09:27:29 +01:00
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Initialize HA cluster using an embedded etcd datastore.
|
|
|
|
|
|
|
|
If this option is `false` and `role` is `server`
|
|
|
|
|
|
|
|
On a server that was using the default embedded sqlite backend,
|
|
|
|
enabling this option will migrate to an embedded etcd DB.
|
|
|
|
|
|
|
|
If an HA cluster using the embedded etcd datastore was already initialized,
|
|
|
|
this option has no effect.
|
|
|
|
|
|
|
|
This option only makes sense in a server that is not connecting to another server.
|
|
|
|
|
|
|
|
If you are configuring an HA cluster with an embedded etcd,
|
|
|
|
the 1st server must have `clusterInit = true`
|
|
|
|
and other servers must connect to it using `serverAddr`.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
token = lib.mkOption {
|
|
|
|
type = lib.types.str;
|
2021-04-09 11:50:03 +02:00
|
|
|
description = ''
|
2022-08-30 09:27:29 +01:00
|
|
|
The k3s token to use when connecting to a server.
|
|
|
|
|
2021-04-09 11:50:03 +02:00
|
|
|
WARNING: This option will expose store your token unencrypted world-readable in the nix store.
|
|
|
|
If this is undesired use the tokenFile option instead.
|
|
|
|
'';
|
2020-04-17 07:39:54 -07:00
|
|
|
default = "";
|
|
|
|
};
|
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
tokenFile = lib.mkOption {
|
|
|
|
type = lib.types.nullOr lib.types.path;
|
2022-08-30 09:27:29 +01:00
|
|
|
description = "File path containing k3s token to use when connecting to the server.";
|
2021-04-09 11:50:03 +02:00
|
|
|
default = null;
|
|
|
|
};
|
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
extraFlags = lib.mkOption {
|
2020-04-17 07:39:54 -07:00
|
|
|
description = "Extra flags to pass to the k3s command.";
|
2024-08-28 21:18:55 +02:00
|
|
|
type = with lib.types; either str (listOf str);
|
2024-07-15 22:46:52 +02:00
|
|
|
default = [ ];
|
|
|
|
example = [
|
2025-04-03 11:01:47 +02:00
|
|
|
"--disable traefik"
|
2024-07-15 22:46:52 +02:00
|
|
|
"--cluster-cidr 10.24.0.0/16"
|
|
|
|
];
|
2020-04-17 07:39:54 -07:00
|
|
|
};
|
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
disableAgent = lib.mkOption {
|
|
|
|
type = lib.types.bool;
|
2020-04-17 07:39:54 -07:00
|
|
|
default = false;
|
|
|
|
description = "Only run the server. This option only makes sense for a server.";
|
|
|
|
};
|
2021-07-19 13:29:39 +02:00
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
environmentFile = lib.mkOption {
|
|
|
|
type = lib.types.nullOr lib.types.path;
|
2023-02-27 05:15:25 -06:00
|
|
|
description = ''
|
2025-01-27 02:10:23 +01:00
|
|
|
File path containing environment variables for configuring the k3s service in the format of an EnvironmentFile. See {manpage}`systemd.exec(5)`.
|
2023-02-27 05:15:25 -06:00
|
|
|
'';
|
|
|
|
default = null;
|
|
|
|
};
|
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
configPath = lib.mkOption {
|
|
|
|
type = lib.types.nullOr lib.types.path;
|
2021-07-19 13:29:39 +02:00
|
|
|
default = null;
|
|
|
|
description = "File path containing the k3s YAML config. This is useful when the config is generated (for example on boot).";
|
|
|
|
};
|
2023-12-15 10:43:22 +01:00
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
manifests = lib.mkOption {
|
|
|
|
type = lib.types.attrsOf manifestModule;
|
2023-12-15 10:43:22 +01:00
|
|
|
default = { };
|
|
|
|
example = lib.literalExpression ''
|
2025-01-15 08:28:08 +01:00
|
|
|
{
|
|
|
|
deployment.source = ../manifests/deployment.yaml;
|
|
|
|
my-service = {
|
|
|
|
enable = false;
|
|
|
|
target = "app-service.yaml";
|
|
|
|
content = {
|
|
|
|
apiVersion = "v1";
|
|
|
|
kind = "Service";
|
|
|
|
metadata = {
|
|
|
|
name = "app-service";
|
|
|
|
};
|
|
|
|
spec = {
|
|
|
|
selector = {
|
|
|
|
"app.kubernetes.io/name" = "MyApp";
|
|
|
|
};
|
|
|
|
ports = [
|
|
|
|
{
|
|
|
|
name = "name-of-service-port";
|
|
|
|
protocol = "TCP";
|
|
|
|
port = 80;
|
|
|
|
targetPort = "http-web-svc";
|
|
|
|
}
|
|
|
|
];
|
2023-12-15 10:43:22 +01:00
|
|
|
};
|
|
|
|
};
|
2025-01-15 08:28:08 +01:00
|
|
|
};
|
2023-12-15 10:43:22 +01:00
|
|
|
|
2025-01-15 08:28:08 +01:00
|
|
|
nginx.content = [
|
|
|
|
{
|
|
|
|
apiVersion = "v1";
|
|
|
|
kind = "Pod";
|
|
|
|
metadata = {
|
|
|
|
name = "nginx";
|
|
|
|
labels = {
|
|
|
|
"app.kubernetes.io/name" = "MyApp";
|
|
|
|
};
|
2023-12-15 10:43:22 +01:00
|
|
|
};
|
2025-01-15 08:28:08 +01:00
|
|
|
spec = {
|
|
|
|
containers = [
|
|
|
|
{
|
|
|
|
name = "nginx";
|
|
|
|
image = "nginx:1.14.2";
|
|
|
|
ports = [
|
|
|
|
{
|
|
|
|
containerPort = 80;
|
|
|
|
name = "http-web-svc";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
}
|
|
|
|
];
|
2023-12-15 10:43:22 +01:00
|
|
|
};
|
2025-01-15 08:28:08 +01:00
|
|
|
}
|
|
|
|
{
|
|
|
|
apiVersion = "v1";
|
|
|
|
kind = "Service";
|
|
|
|
metadata = {
|
|
|
|
name = "nginx-service";
|
|
|
|
};
|
|
|
|
spec = {
|
|
|
|
selector = {
|
|
|
|
"app.kubernetes.io/name" = "MyApp";
|
|
|
|
};
|
|
|
|
ports = [
|
|
|
|
{
|
|
|
|
name = "name-of-service-port";
|
|
|
|
protocol = "TCP";
|
|
|
|
port = 80;
|
|
|
|
targetPort = "http-web-svc";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
};
|
|
|
|
}
|
|
|
|
];
|
|
|
|
};
|
2023-12-15 10:43:22 +01:00
|
|
|
'';
|
|
|
|
description = ''
|
|
|
|
Auto-deploying manifests that are linked to {file}`${manifestDir}` before k3s starts.
|
|
|
|
Note that deleting manifest files will not remove or otherwise modify the resources
|
|
|
|
it created. Please use the the `--disable` flag or `.skip` files to delete/disable AddOns,
|
|
|
|
as mentioned in the [docs](https://docs.k3s.io/installation/packaged-components#disabling-manifests).
|
|
|
|
This option only makes sense on server nodes (`role = server`).
|
|
|
|
Read the [auto-deploying manifests docs](https://docs.k3s.io/installation/packaged-components#auto-deploying-manifests-addons)
|
|
|
|
for further information.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
charts = lib.mkOption {
|
|
|
|
type = with lib.types; attrsOf (either path package);
|
2023-12-15 10:43:22 +01:00
|
|
|
default = { };
|
|
|
|
example = lib.literalExpression ''
|
|
|
|
nginx = ../charts/my-nginx-chart.tgz;
|
|
|
|
redis = ../charts/my-redis-chart.tgz;
|
|
|
|
'';
|
|
|
|
description = ''
|
|
|
|
Packaged Helm charts that are linked to {file}`${chartDir}` before k3s starts.
|
|
|
|
The attribute name will be used as the link target (relative to {file}`${chartDir}`).
|
|
|
|
The specified charts will only be placed on the file system and made available to the
|
2025-01-15 08:28:08 +01:00
|
|
|
Kubernetes APIServer from within the cluster. See the [](#opt-services.k3s.autoDeployCharts)
|
|
|
|
option and the [k3s Helm controller docs](https://docs.k3s.io/helm#using-the-helm-controller)
|
|
|
|
to deploy Helm charts. This option only makes sense on server nodes (`role = server`).
|
2023-12-15 10:43:22 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
containerdConfigTemplate = lib.mkOption {
|
|
|
|
type = lib.types.nullOr lib.types.str;
|
2024-08-03 23:15:52 -07:00
|
|
|
default = null;
|
|
|
|
example = lib.literalExpression ''
|
|
|
|
# Base K3s config
|
|
|
|
{{ template "base" . }}
|
|
|
|
|
|
|
|
# Add a custom runtime
|
|
|
|
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes."custom"]
|
|
|
|
runtime_type = "io.containerd.runc.v2"
|
|
|
|
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes."custom".options]
|
|
|
|
BinaryName = "/path/to/custom-container-runtime"
|
|
|
|
'';
|
|
|
|
description = ''
|
|
|
|
Config template for containerd, to be placed at
|
|
|
|
`/var/lib/rancher/k3s/agent/etc/containerd/config.toml.tmpl`.
|
|
|
|
See the K3s docs on [configuring containerd](https://docs.k3s.io/advanced#configuring-containerd).
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
images = lib.mkOption {
|
|
|
|
type = with lib.types; listOf package;
|
2023-12-15 10:43:22 +01:00
|
|
|
default = [ ];
|
|
|
|
example = lib.literalExpression ''
|
|
|
|
[
|
|
|
|
(pkgs.dockerTools.pullImage {
|
|
|
|
imageName = "docker.io/bitnami/keycloak";
|
|
|
|
imageDigest = "sha256:714dfadc66a8e3adea6609bda350345bd3711657b7ef3cf2e8015b526bac2d6b";
|
2024-09-16 20:40:34 +00:00
|
|
|
hash = "sha256-IM2BLZ0EdKIZcRWOtuFY9TogZJXCpKtPZnMnPsGlq0Y=";
|
2023-12-15 10:43:22 +01:00
|
|
|
finalImageTag = "21.1.2-debian-11-r0";
|
|
|
|
})
|
2024-07-30 11:37:20 +02:00
|
|
|
|
|
|
|
config.services.k3s.package.airgapImages
|
2023-12-15 10:43:22 +01:00
|
|
|
]
|
|
|
|
'';
|
|
|
|
description = ''
|
|
|
|
List of derivations that provide container images.
|
|
|
|
All images are linked to {file}`${imageDir}` before k3s starts and consequently imported
|
2024-07-30 11:37:20 +02:00
|
|
|
by the k3s agent. Consider importing the k3s airgap images archive of the k3s package in
|
|
|
|
use, if you want to pre-provision this node with all k3s container images. This option
|
|
|
|
only makes sense on nodes with an enabled agent.
|
2023-12-15 10:43:22 +01:00
|
|
|
'';
|
|
|
|
};
|
2024-07-19 11:26:37 +02:00
|
|
|
|
|
|
|
gracefulNodeShutdown = {
|
|
|
|
enable = lib.mkEnableOption ''
|
|
|
|
graceful node shutdowns where the kubelet attempts to detect
|
|
|
|
node system shutdown and terminates pods running on the node. See the
|
|
|
|
[documentation](https://kubernetes.io/docs/concepts/cluster-administration/node-shutdown/#graceful-node-shutdown)
|
|
|
|
for further information.
|
|
|
|
'';
|
|
|
|
|
|
|
|
shutdownGracePeriod = lib.mkOption {
|
|
|
|
type = lib.types.nonEmptyStr;
|
|
|
|
default = "30s";
|
|
|
|
example = "1m30s";
|
|
|
|
description = ''
|
|
|
|
Specifies the total duration that the node should delay the shutdown by. This is the total
|
|
|
|
grace period for pod termination for both regular and critical pods.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
shutdownGracePeriodCriticalPods = lib.mkOption {
|
|
|
|
type = lib.types.nonEmptyStr;
|
|
|
|
default = "10s";
|
|
|
|
example = "15s";
|
|
|
|
description = ''
|
|
|
|
Specifies the duration used to terminate critical pods during a node shutdown. This should be
|
|
|
|
less than `shutdownGracePeriod`.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
extraKubeletConfig = lib.mkOption {
|
|
|
|
type = with lib.types; attrsOf anything;
|
|
|
|
default = { };
|
|
|
|
example = {
|
|
|
|
podsPerCore = 3;
|
|
|
|
memoryThrottlingFactor = 0.69;
|
|
|
|
containerLogMaxSize = "5Mi";
|
|
|
|
};
|
|
|
|
description = ''
|
|
|
|
Extra configuration to add to the kubelet's configuration file. The subset of the kubelet's
|
|
|
|
configuration that can be configured via a file is defined by the
|
|
|
|
[KubeletConfiguration](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/)
|
|
|
|
struct. See the
|
|
|
|
[documentation](https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/)
|
|
|
|
for further information.
|
|
|
|
'';
|
|
|
|
};
|
2024-12-01 23:40:41 +08:00
|
|
|
|
|
|
|
extraKubeProxyConfig = lib.mkOption {
|
|
|
|
type = with lib.types; attrsOf anything;
|
|
|
|
default = { };
|
|
|
|
example = {
|
|
|
|
mode = "nftables";
|
|
|
|
clientConnection.kubeconfig = "/var/lib/rancher/k3s/agent/kubeproxy.kubeconfig";
|
|
|
|
};
|
|
|
|
description = ''
|
|
|
|
Extra configuration to add to the kube-proxy's configuration file. The subset of the kube-proxy's
|
|
|
|
configuration that can be configured via a file is defined by the
|
|
|
|
[KubeProxyConfiguration](https://kubernetes.io/docs/reference/config-api/kube-proxy-config.v1alpha1/)
|
|
|
|
struct. Note that the kubeconfig param will be override by `clientConnection.kubeconfig`, so you must
|
|
|
|
set the `clientConnection.kubeconfig` if you want to use `extraKubeProxyConfig`.
|
|
|
|
'';
|
|
|
|
};
|
2025-01-15 08:28:08 +01:00
|
|
|
|
|
|
|
autoDeployCharts = lib.mkOption {
|
|
|
|
type = lib.types.attrsOf autoDeployChartsModule;
|
|
|
|
apply = lib.mapAttrs mkAutoDeployChartManifest;
|
|
|
|
default = { };
|
|
|
|
example = lib.literalExpression ''
|
|
|
|
{
|
|
|
|
harbor = {
|
|
|
|
name = "harbor";
|
|
|
|
repo = "https://helm.goharbor.io";
|
|
|
|
version = "1.14.0";
|
|
|
|
hash = "sha256-fMP7q1MIbvzPGS9My91vbQ1d3OJMjwc+o8YE/BXZaYU=";
|
|
|
|
values = {
|
|
|
|
existingSecretAdminPassword = "harbor-admin";
|
|
|
|
expose = {
|
|
|
|
tls = {
|
|
|
|
enabled = true;
|
|
|
|
certSource = "secret";
|
|
|
|
secret.secretName = "my-tls-secret";
|
|
|
|
};
|
|
|
|
ingress = {
|
|
|
|
hosts.core = "example.com";
|
|
|
|
className = "nginx";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
2025-05-05 11:58:39 +02:00
|
|
|
nginx = {
|
|
|
|
repo = "oci://registry-1.docker.io/bitnamicharts/nginx";
|
|
|
|
version = "20.0.0";
|
|
|
|
hash = "sha256-sy+tzB+i9jIl/tqOMzzuhVhTU4EZVsoSBtPznxF/36c=";
|
|
|
|
};
|
2025-01-15 08:28:08 +01:00
|
|
|
custom-chart = {
|
|
|
|
package = ../charts/my-chart.tgz;
|
|
|
|
values = ../values/my-values.yaml;
|
|
|
|
extraFieldDefinitions = {
|
|
|
|
spec.timeout = "60s";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
description = ''
|
|
|
|
Auto deploying Helm charts that are installed by the k3s Helm controller. Avoid to use
|
|
|
|
attribute names that are also used in the [](#opt-services.k3s.manifests) and
|
|
|
|
[](#opt-services.k3s.charts) options. Manifests with the same name will override
|
|
|
|
auto deploying charts with the same name. Similiarly, charts with the same name will
|
|
|
|
overwrite the Helm chart contained in auto deploying charts. This option only makes
|
|
|
|
sense on server nodes (`role = server`). See the
|
|
|
|
[k3s Helm documentation](https://docs.k3s.io/helm) for further information.
|
|
|
|
'';
|
|
|
|
};
|
2020-04-17 07:39:54 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
# implementation
|
|
|
|
|
2024-08-28 21:18:55 +02:00
|
|
|
config = lib.mkIf cfg.enable {
|
2023-12-15 10:43:22 +01:00
|
|
|
warnings =
|
|
|
|
(lib.optional (cfg.role != "server" && cfg.manifests != { })
|
|
|
|
"k3s: Auto deploying manifests are only installed on server nodes (role == server), they will be ignored by this node."
|
|
|
|
)
|
|
|
|
++ (lib.optional (cfg.role != "server" && cfg.charts != { })
|
|
|
|
"k3s: Helm charts are only made available to the cluster on server nodes (role == server), they will be ignored by this node."
|
|
|
|
)
|
2025-01-15 08:28:08 +01:00
|
|
|
++ (lib.optional (cfg.role != "server" && cfg.autoDeployCharts != { })
|
|
|
|
"k3s: Auto deploying Helm charts are only installed on server nodes (role == server), they will be ignored by this node."
|
|
|
|
)
|
|
|
|
++ (lib.optional (duplicateManifests != [ ])
|
|
|
|
"k3s: The following auto deploying charts are overriden by manifests of the same name: ${toString duplicateManifests}."
|
|
|
|
)
|
|
|
|
++ (lib.optional (duplicateCharts != [ ])
|
|
|
|
"k3s: The following auto deploying charts are overriden by charts of the same name: ${toString duplicateCharts}."
|
|
|
|
)
|
2024-12-09 16:39:22 +01:00
|
|
|
++ (lib.optional (
|
|
|
|
cfg.disableAgent && cfg.images != [ ]
|
|
|
|
) "k3s: Images are only imported on nodes with an enabled agent, they will be ignored by this node")
|
|
|
|
++ (lib.optional (
|
|
|
|
cfg.role == "agent" && cfg.configPath == null && cfg.serverAddr == ""
|
|
|
|
) "k3s: ServerAddr or configPath (with 'server' key) should be set if role is 'agent'")
|
|
|
|
++ (lib.optional
|
|
|
|
(cfg.role == "agent" && cfg.configPath == null && cfg.tokenFile == null && cfg.token == "")
|
|
|
|
"k3s: Token or tokenFile or configPath (with 'token' or 'token-file' keys) should be set if role is 'agent'"
|
2023-12-15 10:43:22 +01:00
|
|
|
);
|
|
|
|
|
2020-04-17 07:39:54 -07:00
|
|
|
assertions = [
|
2022-08-30 09:27:29 +01:00
|
|
|
{
|
|
|
|
assertion = cfg.role == "agent" -> !cfg.disableAgent;
|
2024-12-09 16:39:22 +01:00
|
|
|
message = "k3s: disableAgent must be false if role is 'agent'";
|
2022-08-30 09:27:29 +01:00
|
|
|
}
|
|
|
|
{
|
|
|
|
assertion = cfg.role == "agent" -> !cfg.clusterInit;
|
2024-12-09 16:39:22 +01:00
|
|
|
message = "k3s: clusterInit must be false if role is 'agent'";
|
2022-08-30 09:27:29 +01:00
|
|
|
}
|
2020-04-17 07:39:54 -07:00
|
|
|
];
|
|
|
|
|
2021-04-07 20:46:10 +02:00
|
|
|
environment.systemPackages = [ config.services.k3s.package ];
|
|
|
|
|
2025-01-15 11:52:06 +01:00
|
|
|
# Use systemd-tmpfiles to activate k3s content
|
|
|
|
systemd.tmpfiles.settings."10-k3s" =
|
|
|
|
let
|
|
|
|
# Merge manifest with manifests generated from auto deploying charts, keep only enabled manifests
|
|
|
|
enabledManifests = lib.filterAttrs (_: v: v.enable) (cfg.autoDeployCharts // cfg.manifests);
|
|
|
|
# Merge charts with charts contained in enabled auto deploying charts
|
|
|
|
helmCharts =
|
|
|
|
(lib.concatMapAttrs (n: v: { ${n} = v.package; }) (
|
|
|
|
lib.filterAttrs (_: v: v.enable) cfg.autoDeployCharts
|
|
|
|
))
|
|
|
|
// cfg.charts;
|
|
|
|
# Make a systemd-tmpfiles rule for a manifest
|
|
|
|
mkManifestRule = manifest: {
|
|
|
|
name = "${manifestDir}/${manifest.target}";
|
|
|
|
value = {
|
|
|
|
"L+".argument = "${manifest.source}";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
# Ensure that all chart targets have a .tgz suffix
|
|
|
|
mkChartTarget = name: if (lib.hasSuffix ".tgz" name) then name else name + ".tgz";
|
|
|
|
# Make a systemd-tmpfiles rule for a chart
|
|
|
|
mkChartRule = target: source: {
|
|
|
|
name = "${chartDir}/${mkChartTarget target}";
|
|
|
|
value = {
|
|
|
|
"L+".argument = "${source}";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
# Make a systemd-tmpfiles rule for a container image
|
|
|
|
mkImageRule = image: {
|
|
|
|
name = "${imageDir}/${image.name}";
|
|
|
|
value = {
|
|
|
|
"L+".argument = "${image}";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
in
|
|
|
|
(lib.mapAttrs' (_: v: mkManifestRule v) enabledManifests)
|
|
|
|
// (lib.mapAttrs' (n: v: mkChartRule n v) helmCharts)
|
|
|
|
// (builtins.listToAttrs (map mkImageRule cfg.images))
|
|
|
|
// (lib.optionalAttrs (cfg.containerdConfigTemplate != null) {
|
|
|
|
${containerdConfigTemplateFile} = {
|
|
|
|
"L+".argument = "${pkgs.writeText "config.toml.tmpl" cfg.containerdConfigTemplate}";
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
2024-07-19 11:26:37 +02:00
|
|
|
systemd.services.k3s =
|
|
|
|
let
|
|
|
|
kubeletParams =
|
|
|
|
(lib.optionalAttrs (cfg.gracefulNodeShutdown.enable) {
|
|
|
|
inherit (cfg.gracefulNodeShutdown) shutdownGracePeriod shutdownGracePeriodCriticalPods;
|
|
|
|
})
|
|
|
|
// cfg.extraKubeletConfig;
|
|
|
|
kubeletConfig = (pkgs.formats.yaml { }).generate "k3s-kubelet-config" (
|
|
|
|
{
|
|
|
|
apiVersion = "kubelet.config.k8s.io/v1beta1";
|
|
|
|
kind = "KubeletConfiguration";
|
|
|
|
}
|
|
|
|
// kubeletParams
|
2020-04-17 07:39:54 -07:00
|
|
|
);
|
2024-12-01 23:40:41 +08:00
|
|
|
|
|
|
|
kubeProxyConfig = (pkgs.formats.yaml { }).generate "k3s-kubeProxy-config" (
|
|
|
|
{
|
|
|
|
apiVersion = "kubeproxy.config.k8s.io/v1alpha1";
|
|
|
|
kind = "KubeProxyConfiguration";
|
|
|
|
}
|
|
|
|
// cfg.extraKubeProxyConfig
|
|
|
|
);
|
2024-07-19 11:26:37 +02:00
|
|
|
in
|
|
|
|
{
|
|
|
|
description = "k3s service";
|
|
|
|
after = [
|
|
|
|
"firewall.service"
|
|
|
|
"network-online.target"
|
|
|
|
];
|
|
|
|
wants = [
|
|
|
|
"firewall.service"
|
|
|
|
"network-online.target"
|
|
|
|
];
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
2024-08-28 21:18:55 +02:00
|
|
|
path = lib.optional config.boot.zfs.enabled config.boot.zfs.package;
|
2024-07-19 11:26:37 +02:00
|
|
|
serviceConfig = {
|
|
|
|
# See: https://github.com/rancher/k3s/blob/dddbd16305284ae4bd14c0aade892412310d7edc/install.sh#L197
|
|
|
|
Type = if cfg.role == "agent" then "exec" else "notify";
|
|
|
|
KillMode = "process";
|
|
|
|
Delegate = "yes";
|
|
|
|
Restart = "always";
|
|
|
|
RestartSec = "5s";
|
|
|
|
LimitNOFILE = 1048576;
|
|
|
|
LimitNPROC = "infinity";
|
|
|
|
LimitCORE = "infinity";
|
|
|
|
TasksMax = "infinity";
|
|
|
|
EnvironmentFile = cfg.environmentFile;
|
2024-08-28 21:18:55 +02:00
|
|
|
ExecStart = lib.concatStringsSep " \\\n " (
|
2024-07-19 11:26:37 +02:00
|
|
|
[ "${cfg.package}/bin/k3s ${cfg.role}" ]
|
2024-08-28 21:18:55 +02:00
|
|
|
++ (lib.optional cfg.clusterInit "--cluster-init")
|
|
|
|
++ (lib.optional cfg.disableAgent "--disable-agent")
|
|
|
|
++ (lib.optional (cfg.serverAddr != "") "--server ${cfg.serverAddr}")
|
|
|
|
++ (lib.optional (cfg.token != "") "--token ${cfg.token}")
|
|
|
|
++ (lib.optional (cfg.tokenFile != null) "--token-file ${cfg.tokenFile}")
|
|
|
|
++ (lib.optional (cfg.configPath != null) "--config ${cfg.configPath}")
|
|
|
|
++ (lib.optional (kubeletParams != { }) "--kubelet-arg=config=${kubeletConfig}")
|
2024-12-01 23:40:41 +08:00
|
|
|
++ (lib.optional (cfg.extraKubeProxyConfig != { }) "--kube-proxy-arg=config=${kubeProxyConfig}")
|
2024-07-19 11:26:37 +02:00
|
|
|
++ (lib.flatten cfg.extraFlags)
|
|
|
|
);
|
|
|
|
};
|
2020-04-17 07:39:54 -07:00
|
|
|
};
|
|
|
|
};
|
2024-07-12 09:01:55 -03:00
|
|
|
|
|
|
|
meta.maintainers = lib.teams.k3s.members;
|
2020-04-17 07:39:54 -07:00
|
|
|
}
|