Skip to main content

More Info:

Verifies pods are owned by a controller (Deployment, StatefulSet, DaemonSet, Job). A naked pod is not rescheduled if its node dies.

Risk Level

Low

Address

Security

Compliance Standards

  • Cloudanix Best Practice

Triage and Remediation

Remediation

Manual Steps

  1. Identify all naked pods (run on any machine with kubectl access):
  2. For each naked pod, export its manifest so you can base a controller on it (replace NAMESPACE and PODNAME; run on any machine with kubectl access):
  3. Create an appropriate controller manifest from the pod spec (run on any machine with kubectl access; edit locally with your editor):
    • For stateless workloads, convert to a Deployment:
      Then create PODNAME-deploy.yaml with content like:
      Now paste the contents of PODNAME-pod-spec.yaml under the spec: line above (indented two spaces) and adjust labels, selectors, and any fields that must be unique (for example, remove nodeName if you don’t want pinning).
    • For workloads that must run on every node, build a DaemonSet instead by changing kind: Deployment to kind: DaemonSet and removing the replicas: field.
    • For stateful or single-instance workloads that need stable identities, use kind: StatefulSet and add a serviceName and volumeClaimTemplates as appropriate.
  4. Apply the new controller to the cluster (run on any machine with kubectl access):
    Wait for the new managed pod(s) to be ready:
  5. Once the controller-managed pod is running and serving traffic, delete the original naked pod (run on any machine with kubectl access):
    If the pod was fronted by a Service, confirm the Service’s selector matches the labels used by the controller (for example, app=PODNAME):
  6. Verify no remaining naked pods exist (run on any machine with kubectl access):
    Confirm that either the output is is_compliant=true or that no lines contain is_compliant=false.
On any machine with kubectl access:
  1. Identify “naked” pods (no controller ownerReference) outside system namespaces:
  1. For each listed pod, export its spec to base a controller on (example for namespace app-namespace, pod my-app-pod):
  1. Create a matching controller manifest. For a typical stateless app, prefer a Deployment. Strip pod fields that must not be templated (status, metadata.uid, resourceVersion, etc.) and wrap spec under template. Example deployment-my-app.yaml:
Apply it:
  1. If the naked pod is a singleton system-style agent that should run on all nodes, instead create a DaemonSet. Example daemonset-my-agent.yaml:
Apply it:
  1. After the new controller-created pods are running and traffic is confirmed, delete the original naked pod(s), one at a time, by name:
  1. Repeat steps 2–5 for each naked pod, choosing Deployment/StatefulSet/DaemonSet/Job as appropriate to the workload semantics (stateful storage, one-shot jobs, per-node agents).
  2. Verification (same audit as the check, run after all conversions):