Component customization#
This page explains how to customize Kubernetes resources generated by k0smotron.
Overview#
k0smotron creates the Kubernetes resources (for example StatefulSet, Service, and ConfigMap) documented in Generated Resources through a k0smotron.io/v1beta2 Cluster. You can customize those generated resources by defining patches.
- Standalone: You create the
k0smotron.io/v1beta2Cluster directly. See Create a cluster. - Cluster API integration: When k0smotron acts as a control plane provider (in-cluster),
K0smotronControlPlanecreates ak0smotron.io/v1beta2Cluster, which then produces the same set of generated resources. See k0smotron as Cluster API provider.
In both modes, the resources that can be customized are the same, and you define patches in the same field (.spec.patches); only the resource that has that spec differs (Cluster in standalone, K0smotronControlPlane in Cluster API).
Where to define patches#
Define patches in spec.patches on the resource that owns the generated resources:
| Mode | Resource | Field |
|---|---|---|
| Standalone | k0smotron.io/v1beta2 Cluster |
Cluster.spec.patches |
| Cluster API (control plane provider - in-cluster) | K0smotronControlPlane |
K0smotronControlPlane.spec.patches |
The patch format and targeting rules are identical in both modes.
Examples#
Standalone#
The following example uses a k0smotron.io/v1beta2 Cluster (standalone). It targets the k0s configuration ConfigMap and adds a custom label using a merge patch.
apiVersion: k0smotron.io/v1beta2
kind: Cluster
metadata:
name: docker-test
spec:
version: v1.34.3-k0s.0
patches:
- target:
kind: ConfigMap
component: cluster-config
patch:
type: merge
content: |
metadata:
labels:
custom-label: "my-value"
Cluster API#
The following example builds on the Docker (HCP) example and adds patches. It demonstrates all three patch types (strategic, json, merge) targeting different components. Before starting, ensure that you have met the general prerequisites and initialized the Docker infrastructure provider as described in the Docker (HCP) guide.
Note: The K0smotronControlPlane spec embeds the k0smotron.io/v1beta2 ClusterSpec, so the patches field and all other fields follow the v1beta2 schema.
apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
name: docker-test
namespace: default
spec:
clusterNetwork:
pods:
cidrBlocks:
- 192.168.0.0/16
serviceDomain: cluster.local
services:
cidrBlocks:
- 10.128.0.0/12
controlPlaneRef:
apiGroup: controlplane.cluster.x-k8s.io
kind: K0smotronControlPlane
name: docker-test-cp
infrastructureRef:
apiGroup: infrastructure.cluster.x-k8s.io
kind: DockerCluster
name: docker-test
---
apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: K0smotronControlPlane
metadata:
name: docker-test-cp
namespace: default
spec:
version: v1.34.3-k0s.0
persistence:
type: emptyDir
service:
type: LoadBalancer
patches:
# Set resource requests/limits and probe timing on the control-plane pods
- target:
kind: StatefulSet
component: control-plane
patch:
type: strategic
content: |
spec:
template:
spec:
containers:
- name: controller
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
readinessProbe:
initialDelaySeconds: 10
livenessProbe:
initialDelaySeconds: 10
# Increase the etcd readiness probe initial delay
- target:
kind: StatefulSet
component: etcd
patch:
type: json
content: '[{"op":"add","path":"/spec/template/spec/containers/0/readinessProbe/initialDelaySeconds","value":15}]'
# Add an annotation to the control-plane Service
- target:
kind: Service
component: control-plane
patch:
type: merge
content: |
metadata:
annotations:
example.com/managed-by: "k0smotron-customized"
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: DockerCluster
metadata:
name: docker-test
namespace: default
annotations:
cluster.x-k8s.io/managed-by: k0smotron
spec: {}
---
apiVersion: cluster.x-k8s.io/v1beta2
kind: MachineDeployment
metadata:
name: docker-test-md
namespace: default
spec:
clusterName: docker-test
replicas: 1
selector:
matchLabels:
cluster.x-k8s.io/cluster-name: docker-test
pool: worker-pool-1
template:
metadata:
labels:
cluster.x-k8s.io/cluster-name: docker-test
pool: worker-pool-1
spec:
clusterName: docker-test
version: v1.34.3
bootstrap:
configRef:
apiGroup: bootstrap.cluster.x-k8s.io
kind: K0sWorkerConfigTemplate
name: docker-test-machine-config
infrastructureRef:
apiGroup: infrastructure.cluster.x-k8s.io
kind: DockerMachineTemplate
name: docker-test-mt
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: DockerMachineTemplate
metadata:
name: docker-test-mt
namespace: default
spec:
template:
spec: {}
---
apiVersion: bootstrap.cluster.x-k8s.io/v1beta2
kind: K0sWorkerConfigTemplate
metadata:
name: docker-test-machine-config
spec:
template:
spec:
version: v1.34.3+k0s.0
After the cluster is provisioned, verify that the patches were applied. Resource names follow the conventions described in Generated Resources.
# Verify resource limits on the control-plane StatefulSet
kubectl get statefulset kmc-docker-test -o jsonpath='{.spec.template.spec.containers[0].resources}'
# Verify the control-plane probe timing
kubectl get statefulset kmc-docker-test -o jsonpath='{.spec.template.spec.containers[0].readinessProbe.initialDelaySeconds}'
kubectl get statefulset kmc-docker-test -o jsonpath='{.spec.template.spec.containers[0].livenessProbe.initialDelaySeconds}'
# Verify the etcd readiness probe initial delay
kubectl get statefulset kmc-docker-test-etcd -o jsonpath='{.spec.template.spec.containers[0].readinessProbe.initialDelaySeconds}'
# Verify the annotation on the control-plane Service
kubectl get service kmc-docker-test-lb -o jsonpath='{.metadata.annotations}'
Targeting resources#
To keep targeting predictable and maintainable, each patch entry has a target block that selects resources by:
kind: Kubernetes Kind (for exampleStatefulSet,Service,ConfigMap)component: value of theapp.kubernetes.io/componentlabel on the generated resource
This avoids string-based targeting via names and avoids template-based targeting. See the Examples above.
Patch types#
Each patch entry has a patch block containing type and content. The format of content depends on type:
json: a JSON Patch array, an array of add/remove/replace operationsstrategic: a Kubernetes strategic merge patch object, like merge but with array merge semantics based onpatchStrategytagsmerge: a JSON Merge Patch object, a partial JSON/YAML object that is merged into the target resource
Component values#
k0smotron labels generated resources with app.kubernetes.io/component to describe their purpose. Use these values in the target.component field when targeting patches. For the full list of component values, resource types, and their naming conventions, see Generated Resources.
Note: A (kind, component) combination is not always unique. For example, component: monitoring is shared by two ConfigMaps (Prometheus and Nginx). A patch targeting such a combination will be applied to all matching resources.
Notes and limitations#
- Patches are applied in list order after k0smotron generates each resource and before it is applied to the cluster. Multiple patches that match the same resource (same
kindandcomponent) are applied in sequence. - A patch is applied to all generated resources that match the given
kindandcomponentcombination. - Only resources created and managed by the K0smotron Cluster (documented in Generated Resources) are patch targets. Other resources are not; for example, when using Cluster API, certificate Secrets are created by Cluster API controllers and follow Cluster API naming conventions, so they are not patch targets.