Back

K10: Outdated and Vulnerable Kubernetes Components - Prevention

Prevention Strategy

K10 is closed by a process, not a one-time fix. Currency is a moving target: a cluster that is fully patched today drifts into "outdated" within weeks as new advisories land and support windows advance. The goal is to make patching routine, boring, and automated—so that being current is the default state rather than a heroic quarterly project.

The strategy has six pillars, applied to every layer of the stack:

Know it      -> inventory every component and its version
Watch it     -> subscribe to CVE feeds + track support/EOL dates
Measure it   -> scan the cluster and images continuously
Upgrade it   -> tested, incremental upgrades within version skew
Patch nodes  -> automate OS/kernel/runtime patching on nodes
Shrink it    -> remove unused add-ons; prefer maintained/managed

1. Inventory the Whole Stack

You cannot patch what you cannot see. Build and maintain a living inventory of every version-bearing component—not just "the Kubernetes version."

# Control plane + node agents (versions and skew):
kubectl version
kubectl get nodes -o wide
# -> KUBELET-VERSION, KERNEL-VERSION, OS-IMAGE, CONTAINER-RUNTIME per node

# Add-ons and their images (ingress, CNI, CSI, dashboard, mesh):
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{range .spec.containers[*]}{.image}{"\n"}{end}{end}' | sort -u

What to record: for each component—current version, upstream latest, support/EOL date, and an owner responsible for upgrading it. Include the Kubernetes minor, kubelet, runtime, runc, node OS/kernel, CNI, CSI, ingress controller, dashboard, metrics, and every mesh/operator you installed. Store it as data (a manifest or SBOM), not tribal knowledge.

2. Track CVEs and Support Windows

Application dependencies usually have an owner watching advisories. The cluster's own components frequently do not—assign that ownership explicitly.

3. Scan the Cluster, Not Just Images

Image scanning is necessary but insufficient for K10—it does not inspect the kubelet, runtime, or add-on versions. Add tools that scan the cluster.

# Trivy can scan the cluster's components (control plane, node,
# workloads) for known vulnerabilities and misconfigurations:
trivy k8s --report summary cluster

# kubescape scans the live cluster against frameworks that
# include outdated/vulnerable-component controls:
kubescape scan --format json --output results.json

# Grype scans images (and SBOMs) for known CVEs in packages:
grype registry.example.com/app:1.4.2 --fail-on high

Wire scanning into CI/CD and into a schedule: gate deployments on image scans (Grype/Trivy) and run cluster scans (Trivy k8s, kubescape) on a cron so newly disclosed CVEs surface against already-running components—not only at deploy time.

4. Upgrade on a Cadence, Within Skew

Regular, small, tested upgrades are how you avoid emergency multi-version jumps.

# Example cadence (adapt to your risk tolerance):
#   - Patch releases: apply within days of a security release.
#   - Minor upgrades: every 1-3 months, staged (canary -> fleet).
#   - Node OS/kernel: continuous auto-patch (see next section).
#   - Add-ons: reviewed monthly against upstream + advisories.

5. Automate Node and OS Patching

Node OS, kernel, and container runtime are the most-neglected layers and the ones behind escape and LPE classes. Automate them so they are never "waiting for a maintenance window."

# kured runs as a DaemonSet and coordinates safe, serialized reboots
# after unattended-upgrades / OS patching flags a reboot is needed:
#   node applies kernel/security updates -> kured cordons+drains -> reboot -> uncordon
# PodDisruptionBudgets keep workloads available during the roll.

6. Reduce and Maintain Add-ons

Every add-on is another component to track and patch. The cheapest way to reduce K10 exposure is to run fewer things.

Hardening Checklist

ControlActionPriority
InventoryMaintain a versioned list of every component + owner + EOL dateCritical
Support windowKeep Kubernetes on a supported minor; never run EOLCritical
Version skewKeep kubelets within the supported gap from the API serverCritical
Runtime/runcPatch container runtime and runc on every nodeCritical
Node OS/kernelAutomate patching (kured / managed node pools); no EOL OSCritical
Ingress controllerTrack advisories; patch promptly (IngressNightmare class)Critical
CVE feedsSubscribe to k8s security-announce + each add-on's channelHigh
Cluster scanningRun Trivy k8s / kubescape on a schedule + Grype in CIHigh
Tested upgradesCanary/staging upgrades, one minor at a timeHigh
Add-on hygieneRemove unused add-ons; pin + track the restMedium
ExposureKeep dashboard/kubelet/metrics off the public internetMedium
Managed optionPrefer managed clusters/node pools where feasibleMedium

Defense-in-Depth Summary

No single control fully addresses K10; layer them so a lapse in one is caught by another:

Layer 1: Inventory      -> you know every component and version
Layer 2: Intelligence   -> CVE feeds + EOL tracking tell you what's at risk
Layer 3: Detection      -> Trivy k8s / kubescape / Grype find it in your cluster
Layer 4: Remediation    -> tested, cadence-based upgrades within skew
Layer 5: Automation     -> kured / managed pools patch nodes continuously
Layer 6: Reduction      -> fewer add-ons, less exposure, managed where possible

Key Takeaways

  1. Make currency the default—automate and schedule so patched is the resting state, not a special event.
  2. Inventory the whole stack—kubelet, runtime, kernel, CNI/CSI, ingress, and add-ons, each with an owner and an EOL date.
  3. Scan the cluster, not only images—Trivy k8s and kubescape see the components image scanners miss.
  4. Upgrade small, upgrade often, within skew—incremental tested upgrades beat emergency jumps every time.
  5. Automate node patching and shrink the surface—kured/managed pools for the OS and runtime; delete add-ons you do not use.

Next Steps