The problem

A Pod is behaving strangely. You checked the logs. You exec’d into the container. But the issue is not inside the Pod — it is on the node itself.

Maybe it is disk pressure. Maybe host-level networking. Maybe you need kubelet logs, the container runtime, or what is happening on the actual Linux host.

Normally you would SSH into the node. In modern environments — managed EKS, GKE, AKS, or hardened on-prem — SSH to nodes is often restricted, disabled, or a multi-hop process.

Enter kubectl node-shell

kubectl node-shell launches a privileged Pod on the target node that gives you a root shell on the host — from kubectl, without SSH.

One command. Full node access. No SSH required.

It still needs RBAC permission to create privileged Pods and to use the plugin. If your role cannot run it, that is policy working as intended.

Installation

Via Krew:

kubectl krew install node-shell

Confirm context first — kubectx and kubens help. For Pod-level work, k9s and stern cover most days; node-shell is for when the problem is under the kubelet.

Basic usage

# List available nodes first
kubectl get nodes

# Get a shell on a specific node
kubectl node-shell k8s-worker-01

That is it. You are dropped into a root shell on the node within seconds.

What you can do from a node shell

Once you have node-level access, you can investigate things not visible from inside a Pod:

Check kubelet status and logs:

systemctl status kubelet
journalctl -u kubelet -n 100

Inspect disk usage at the host level:

df -h
du -sh /var/lib/containerd/*
du -sh /var/lib/kubelet/*

Check node-level networking:

ip addr show
ip route show
iptables -L -n
ss -tulpn

Inspect the container runtime directly:

# For containerd (common on modern clusters)
crictl ps
crictl logs <container-id>
crictl inspect <container-id>

# For Docker (older setups)
docker ps
docker stats

Check system resources:

top
free -h
dmesg | tail -50

Investigate OOM kills:

dmesg | grep -i "oom\|killed"
journalctl -k | grep -i oom

How it works

kubectl node-shell creates a temporary privileged Pod with hostPID: true, hostNetwork: true, and hostIPC: true, mounted to the host filesystem. It exec’s into that Pod with nsenter to enter the node’s namespaces — a shell at host level, not container level.

When you exit, the Pod is cleaned up automatically.

Important: use with care

Node-shell gives you root access to the host. Powerful and dangerous if misused:

  • Prefer read-only investigation on production nodes
  • Be careful with writes — you are on the actual host
  • In regulated environments, access should be logged and audited
  • Never leave a node-shell session open and unattended

The tool is for debugging, not routine operations. Treat it accordingly.

For ownership and YAML without SSH, kubectl tree and kubectl neat stay in the toolkit at the Pod layer.

When pod-level access is not enough

Scenariokubectl execkubectl node-shell
Check app logsYesYes
Check kubelet logsNoYes
Inspect disk at host levelNoYes
Check iptables rulesNoYes
Investigate OOM killsNoYes
Inspect container runtimeNoYes
Check host networkingNoYes

Summary

Installkubectl krew install node-shell
Best forNode-level debugging, kubelet issues, disk/network problems
Killer featureRoot shell on any node without SSH
ImportantUse with care — you have full host access
GitHubgithub.com/kvaps/kubectl-node-shell

When the problem is below the Pod level, kubectl node-shell is the fastest path to the truth.