User guide
Keel maintains files and installed packages on Kubernetes nodes. You describe
one task per NodeConfig; the Keel agent on each matching node applies it and
checks it again periodically. Services can be restarted after a change.
NodeConfig authors administer the host OS. A namespace does not restrict which nodes a configuration can affect. Agree ownership and target nodes with your cluster administrator before applying changes.
Before you start
An administrator must install Keel and its CRD using the
deployment guide. You need kubectl connected to that cluster
and permission to manage NodeConfigs in your chosen namespace. These commands
use tak-os; replace it consistently when using another namespace.
kubectl config current-context
kubectl auth can-i create nodeconfigs.keel.tlspu.io -n tak-os
kubectl get nodes --show-labels
kubectl -n tak-os get nodeconfigs
Choose labels that already identify your intended nodes. If you cannot list nodes, ask the administrator for the approved selector. Keel reads NodeConfigs across all namespaces, and an omitted or empty selector matches every node running an agent, including control-plane nodes in the supplied deployment.
Apply your first file configuration
Save this as keel-node-info.yaml. Replace replace-with-approved-node-name
with the value of kubernetes.io/hostname on one approved node. The example
writes a separate informational file and requests no service restarts.
apiVersion: keel.tlspu.io/v1
kind: NodeConfig
metadata:
name: keel-node-info
namespace: tak-os
spec:
type: file
interval: 10m
nodeSelector:
matchLabels:
kubernetes.io/hostname: replace-with-approved-node-name
params:
filename: /etc/keel-node-info
mode: "0644"
contents: |
Managed by Keel
Node: {{ .Node.Name }}
OS: {{ .Node.OSName }} {{ .Node.OSVersion }}
Kubernetes: {{ .Cluster.KubernetesVersion }}
All parameter values are strings. Quote octal file modes and package versions.
Paths are host paths such as /etc/keel-node-info; do not prepend /host.
kubectl apply --dry-run=server -f keel-node-info.yaml
kubectl apply -f keel-node-info.yaml
kubectl -n tak-os get nodeconfig keel-node-info -o yaml
kubectl -n tak-os describe nodeconfig keel-node-info
Server-side dry-run checks the CRD and, when installed, the admission webhook.
It does not execute templates against node facts or test host writes. A successful
kubectl apply means the API accepted the object; check per-node status for the
host result. If the selector matches no node, the object can be accepted without
any node status entries.
Read the result
For every intended node, inspect status.nodes[<node-name>]:
| Field | What to check |
|---|---|
lastResult |
success means that run completed; error needs investigation |
observedGeneration |
Compare with metadata.generation to check the node processed the current spec |
changed |
Whether that recorded run modified host state |
restartPending |
true means services still require a successful restart |
message |
Application, no-change or error details |
lastRunTime |
Time of the recorded outcome, not a continuously updated heartbeat |
Steady no-change runs do not keep rewriting status. The top-level
status.observedGeneration is not proof that every node processed the spec.
Excluded or removed nodes can retain old entries. Check the current target node
list and each node's entry. See troubleshooting for missing
status or failed runs; operations explains Events and metrics.
Change and expand a configuration
Edit the saved manifest, repeat dry-run, apply it, and check the canary node's status and host behavior. A spec change runs without waiting for the normal interval. Once verified, replace the single-node selector with an approved pool label and apply again. NodeConfigs have no cluster-wide rolling-update or disruption-budget mechanism: matching nodes can all apply the change at once.
Use one owner for each host file or package. Different NodeConfigs have no dependency ordering; serialization on one node does not resolve conflicting desired states or coordinate different nodes. A package configuration followed by a file configuration is not an ordered installation workflow.
Normal successful runs repeat on spec.interval (default 10m). Failures retry
with controller backoff. A node label update reevaluates selection, but does not
guarantee an immediate rerun of a previously successful configuration whose
interval has not elapsed. Node facts refresh independently from application.
Restart services after changes
For a configuration that needs a service restart, add its exact host systemd unit name:
services:
- example-agent.service
This is a fragment of spec, not a complete resource. Replace the example unit
with one installed on your nodes. Keel runs systemctl daemon-reload and then
restarts the listed units when the handler reports a change. Unchanged runs do
not restart services unless an earlier restart is pending. Adding a service to
an otherwise unchanged file configuration does not by itself force a restart.
A restart failure leaves the file/package change in place and records
restartPending: true. Keel retries restarts on subsequent runs. There is no
automatic rollback. Service names can be templated, but must render to literal
unit names, without paths, options, whitespace or glob patterns.
Install a package
Use a separate NodeConfig with the same approved selector:
apiVersion: keel.tlspu.io/v1
kind: NodeConfig
metadata:
name: keel-htop
namespace: tak-os
spec:
type: package
interval: 6h
nodeSelector:
matchLabels:
kubernetes.io/hostname: replace-with-approved-node-name
params:
package_name: htop
Package installation uses the host's repositories and package manager. Omitting
version ensures presence; it does not continually upgrade an installed package.
Review the handler reference before pinning versions or using
different node distributions.
Request a run using a ConfigMap
Add a same-namespace trigger reference under spec:
watchConfigMaps:
- name: keel-refresh
After applying that spec, a trusted operator can create or update the trigger:
kubectl -n tak-os create configmap keel-refresh --from-literal=request=initial
kubectl -n tak-os annotate configmap keel-refresh keel.tlspu.io/request=manual-1 --overwrite
Use a new annotation value for a subsequent request. Creation, update, deletion and recreation trigger a run without waiting for the interval. The ConfigMap contains no template inputs: Keel does not copy its data into file contents or facts. Metadata-only edits to the NodeConfig itself do not force a run.
Stop managing or undo a change
kubectl -n tak-os delete nodeconfig keel-node-info
Deletion stops future reconciliation once agents observe it. It does not undo an operation already in progress, delete the host file, uninstall a package or restore service state. Removing a node from selection has the same persistence of host state. There is no suspend field.
To restore earlier file contents, apply the previous manifest while Keel still manages it, verify results, and then remove the NodeConfig if desired. Deleting a file or removing a package requires a separate administrator action; the built-in handlers do not support an absent state. Keep manifests and previous desired values in version control. For one-off filesystem work, see the local CLI guide.
