Security review
Keel is a root administration agent. A principal who can create or change a NodeConfig can write host files, install packages and restart system services on matching nodes. Labels and namespace separation are selection tools, not a security boundary. Keep NodeConfig authors, referenced ConfigMap writers, DaemonSet editors and Keel image publishers within the node-administrator trust boundary. Admission checks catch invalid input; they do not authorize safe host changes or make arbitrary package scripts safe.
Privileges and runtime isolation
The supplied DaemonSet retains privileged: true, UID 0, host PID visibility and a
writable host / mount. The command runner uses chroot /host for package and
systemctl commands; it does not perform a startup mount operation or call
nsenter. Kubernetes prepares the mount. Consequently there is no meaningful
"drop capabilities after mount" phase in the current process. Host commands and
package lifecycle scripts run throughout the agent's lifetime and can require
additional capabilities. A permanent drop would also apply to those children.
A reduced-capability profile needs an explicit supported package/service matrix
and testing on each supported node distribution. File writing needs ownership
and permission privileges; chroot requires CAP_SYS_CHROOT; arbitrary package
scripts may need considerably more. A general privileged profile cannot honestly
promise a small capability set. Adding capabilities.drop: [ALL] while retaining
privileged mode does not establish that restriction.
The manifest explicitly declares seccompProfile: Unconfined because Kubernetes
runs privileged containers unconfined and ignores a specified seccomp restriction.
RuntimeDefault or a custom profile becomes useful after privileged mode is
removed and package/service behavior is constrained and tested. See the
Kubernetes seccomp reference
and Linux kernel security constraints.
The container image filesystem is read-only, with a bounded writable /tmp
emptyDir. This prevents accidental writes to the image filesystem; the writable
host root still gives the process host administration privileges. Restrict
admission of similarly privileged pods to dedicated trusted namespaces and node
administrators. Keel cannot satisfy Kubernetes Baseline or Restricted Pod
Security profiles.
Kubernetes access and network exposure
The service account reads NodeConfigs, Nodes, Namespaces and ConfigMaps, patches NodeConfig status, and creates/patches Events. It cannot update NodeConfig specs, Nodes, ConfigMaps or Secrets using the supplied role. Cluster-wide watch access is necessary for the current all-namespace controller and referenced objects; ConfigMap data is visible to the agent, so keep unrelated secrets out of it. NodeConfig write access must be granted separately and sparingly.
The agent requires outbound Kubernetes API access; package handlers also require access to the host's configured package repositories. Health and metrics listeners are unauthenticated and bind to the pod network by default. Do not expose them with a public Service or ingress. Apply network policy appropriate to the CNI and monitoring system. Pin release images by digest in production and scan/rebuild the runtime image regularly. The Dockerfile uses Alpine 3.24; the previous 3.20 branch ended ordinary support on 1 April 2026, according to the Alpine release lifecycle.
Resource budget and measurement
The sample requests 50m CPU and 64Mi memory, limits memory to 256Mi and ephemeral
storage to 128Mi, and bounds /tmp to 64Mi. It deliberately leaves CPU unlimited
so occasional configuration runs are not throttled. These are starting budgets,
not measurements of production workloads. Cached Nodes, ConfigMaps and
NodeConfigs consume memory according to cluster object counts and content sizes;
package subprocesses can exceed the sample limit. Chrooted package caches and
written host files use host storage outside the pod's ephemeral-storage budget.
Before rollout, exercise representative numbers and sizes of objects, file changes, package operations and concurrent node rollouts. Observe container working set, CPU usage, OOM events, restart counts, CR duration/error metrics and host free space. Size memory above observed peak including package subprocesses; set requests from sustained use and scheduling needs. Increase temporary storage only when the workload needs it. Test in a canary node pool before broad rollout. The kind E2E validates file and systemd behavior; it does not benchmark package managers or justify a universal resource limit.
