kubectl exec fails because the image has no shell — how do you get a shell to debug it?
You need a shell inside a running Pod to debug it, but kubectl exec fails: the app image is distroless and ships no shell. Get a debugging shell into the Pod without rebuilding the image.
$ kubectl exec -it api-5f6 -- sh
OCI runtime exec failed: exec failed: unable to start container process:
exec: "sh": executable file not found in $PATH: unknown
Diagnose and fix.
The image is distroless, so there is no sh to exec into. Attach an ephemeral debug container that shares the target's namespaces: kubectl debug -it api-5f6 --image=busybox --target=api. --target shares the process namespace, so you see its processes. No rebuild.
- ✗Assuming a distroless Pod cannot be debugged without a rebuild
- ✗Forgetting
--targetso the debug container cannot see the app's processes - ✗Confusing
kubectl debugwith a plainexecinto the same container
- →Why is running a distroless image (no shell) a security benefit in production?
- →What does
--targetchange compared with omitting it onkubectl debug?
Solution
1. Why exec fails
exec: "sh": executable file not found in $PATH
The image is distroless/minimal — it has no sh/bash, so kubectl exec ... -- sh cannot start a shell. That is expected for a hardened prod image, not a fault.
2. Ephemeral debug container
$ kubectl debug -it api-5f6 --image=busybox --target=api
/ # ps -ef # the api container's processes are visible
/ # wget -qO- localhost:8080/health
kubectl debug adds an ephemeral container to the already-running Pod. --target=api shares the process namespace with the app container, so you see its processes, network, and (via /proc/<pid>/root) files. The app image is not changed or rebuilt.
3. Cleanup
The ephemeral container lives only for the session — on exit it is removed and the Pod does not restart.