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. List all non-system “naked” Pods (no controller)
    • Run on: any machine with kubectl access
  2. For each naked Pod, export its manifest
    • Replace <namespace> and <pod-name> for each entry from step 1.
    • Run on: any machine with kubectl access
  3. Convert the Pod manifest into a controller manifest (example: Deployment)
    • Edit the exported file on your workstation and save as a new file, e.g. /tmp/<namespace>-<pod-name>.deploy.yaml.
    • Minimal transformation pattern (keep metadata.labels and spec, remove fields set by the cluster like status, resourceVersion, uid, etc.):
    • Choose StatefulSet/DaemonSet/Job instead of Deployment if that better matches the workload semantics, following the same pattern (controller spec.template contains the old Pod spec).
  4. Delete the original naked Pod and create the controller
    • This will cause a brief disruption for that workload.
    • Run on: any machine with kubectl access
    • Wait for the new Pod to become Ready:
  5. Repeat for all naked Pods
    • Perform steps 2–4 for each Pod listed in step 1, selecting the appropriate controller type (Deployment, StatefulSet, DaemonSet, or Job) based on how the workload should behave on EKS.
  6. Verify no remaining naked Pods
    • Run on: any machine with kubectl access
    • Confirm that all entries show is_compliant=true and no remaining Pods have owner= missing or is_compliant=false.
On any machine with kubectl access:
  1. Identify naked pods (excluding system namespaces):
  1. For each non-system naked pod you want to keep, export its spec (example for namespace default, pod my-pod):
  1. Create a controller manifest from the pod spec, for example a Deployment (most common). Edit a file like /tmp/my-pod-deploy.yaml to look like:
Populate containers and other fields from /tmp/my-pod-raw.yaml’s spec: section.
  1. Apply the controller:
  1. Wait for the new pod(s) to be ready:
  1. Migrate traffic or data if needed (e.g., ensure Services point via labels app: my-pod), then delete the original naked pod:
  1. Repeat steps 2–6 for each naked pod, choosing the appropriate controller type:
  • Long-running stateless: Deployment
  • Long-running stateful with stable identity/storage: StatefulSet
  • One per node: DaemonSet
  • Finite/one-off work: Job (or CronJob for scheduled jobs)
  1. Verification (same command used by the check):