Skip to content
kix /docs
Install the CLI

Reference Cluster module

cluster.roles

How the environment claims each infrastructure role, and which packages and flavours provide it.

cluster.roles.<role> records whether the environment already provides an infrastructure role, such as the CNI or the cluster’s default StorageClass. Flavours set these bindings; a cluster file overrides them when its environment differs. Packages never set a binding: a package claims a role through meta.roles.

FieldTypeDefaultMeaning
bindingnull | absent | shadowable | exclusivenullHow the environment claims the role.
providerstring or nullnullDisplay name of the environment’s implementation. Informational only.
bindingMeaning
nullUnknown. Consumers that rely on the role warn.
absentThe environment does not provide the role. A managed instance fills it. Without one, a consumer that requires the role fails to build, and an optional dependency on it is null.
shadowableThe environment provides a default, usually through a platform import. A managed instance that claims the role replaces it.
exclusiveThe environment owns the role. A managed instance that claims it is an evaluation error.

Keys must be roles from the registry in kix/lib/eval/roles.nix.

The role name is also a dependency alias: a package that declares a dependency with the role’s name gets the instance that provides it, managed or imported.

RoleProvider’s outPackages that claim it
cninonecilium
network-policy-enforcernetpolcilium
dnsfqdncoredns
storageClassesstorageClassName, the class a claim gets when it names nonestorage-classes
loadBalancernone; a provider’s presence allows type: LoadBalancer Servicesnone
metricsApinone; a provider’s presence allows HorizontalPodAutoscalers on resource metrics and the descheduler’s KubernetesMetrics sourcemetrics-server
registryMirrornone; the role exists so that an environment that runs its own mirror (k3s or RKE2 with embedded-registry: true, bound exclusive) refuses a second onespegel
snapshotControllercrds, the VolumeSnapshotClass, VolumeSnapshotContent, and VolumeSnapshot handles for scope.mkCRsnapshot-controller

A CSI driver package such as zfs-localpv does not claim storageClasses. A consumer names the driver instance with deps.storageClasses = ref.<namespace>.<instance>, or the instance sets aliases = [ "storageClasses" "zfsLocalPv" ] to serve every consumer. Keep zfsLocalPv in that list: the package’s one-instance-per-cluster check matches on it.

No package takes loadBalancer or metricsApi as a dependency; evaluation checks the resources that need them. With the binding absent and no provider instance, a type: LoadBalancer Service fails evaluation, and so do a HorizontalPodAutoscaler that reads metrics.k8s.io (autoscaling/v1, an autoscaling/v2 HPA with no metrics, or a Resource or ContainerResource metric) and a descheduler whose policy.metricsProviders lists KubernetesMetrics. With the binding null, they evaluate with a warning.

Each cell is the flavour’s default binding. “import” means the flavour also declares a platform import in kube-system that provides the role.

FlavourcnidnsstorageClassesloadBalancersnapshotControllermetricsApiregistryMirror
aksexclusiveshadowable, importshadowable, importshadowablenullexclusivenull
eksexclusiveshadowable, importabsentshadowablenullabsentnull
gkeexclusiveshadowable, importshadowable, importshadowablenullexclusivenull
gke-autopilotexclusiveshadowable, importshadowable, importexclusivenullexclusivenull
k3sexclusiveshadowable, importshadowable, importexclusivenullexclusivenull
kindexclusiveshadowable, importshadowable, importabsentabsentabsentabsent
kubeadmabsentshadowable, importabsentabsentnullabsentnull
openshiftexclusiveshadowable, importabsentabsentnullnullnull
ovhexclusiveshadowable, importshadowable, importshadowablenullnullnull
rke2follows cluster.flavor.rke2.cni (cilium: shadowable, import)shadowable, importabsentabsentexclusive, importexclusivenull
scalewayexclusiveshadowable, importshadowable, importshadowablenullnullnull
talosexclusiveshadowable, importabsentabsentnullabsentnull

No flavour binds network-policy-enforcer.

A cluster whose environment differs from its flavour’s assumption sets the binding in its own module. An RKE2 cluster that disables RKE2’s snapshot charts runs its own controller:

cluster.roles.snapshotController.binding = "absent";
instances.storage.snapshot-controller.package = packages.snapshot-controller;

A k3s server started with --disable=metrics-server runs its own:

cluster.roles.metricsApi.binding = "absent";
instances.metrics-server.metrics-server.package = packages.metrics-server;