A Kubernetes node goes NotReady
The kubelet has stopped reporting, or is reporting a condition that makes the node unschedulable.
What you see
kubectl get nodes shows NotReady. Pods are evicted and rescheduled elsewhere, or stay Terminating indefinitely.
What is actually wrong
The kubelet has stopped or cannot reach the API server, the container runtime is unresponsive, or the node is under disk or memory pressure.
Codes and articles
Fixes (3)
Relieve the pressure the node is reporting
DiskPressure or MemoryPressure.
Read the exact condition and its message.
kubectl describe node node01 | sed -n '/Conditions:/,/Addresses:/p'For DiskPressure, find what filled up — it is usually images or logs.
df -h /var/lib/containerd /var/log /sudo du -sh /var/log/pods /var/lib/containerd 2>/dev/null
Let the kubelet's own garbage collection do the work, then prune what remains.
sudo crictl imagessudo crictl rmi --prune
crictl rmi --prune removes images not used by any container, which is what the kubelet would eventually do itself. Deleting files under /var/lib/containerd by hand corrupts the runtime's metadata.
Check the eviction thresholds are sensible for the disk size — the defaults are percentage-based and can be far too aggressive on a large disk.
sudo grep -E 'evictionHard|imageGC' /var/lib/kubelet/config.yamlCap the log sizes so this does not recur.
sudo grep -E 'containerLogMaxSize|containerLogMaxFiles' /var/lib/kubelet/config.yaml
kubectl get nodes; kubectl describe node node01 | grep -A6 ConditionsGet the kubelet talking to the API server again
The kubelet has stopped posting status.
Check the service and read its log.
systemctl status kubelet --no-pager -lsudo journalctl -u kubelet -n 80 --no-pager
Check the client certificate has not expired — this is the most common cause on a cluster that has been running for about a year.
sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -dates -subjectKubelet certificates are typically valid for a year and rotate automatically only if rotation is enabled. A cluster built without it goes NotReady, one node at a time, exactly twelve months later.
Check connectivity to the API server.
sudo grep server /etc/kubernetes/kubelet.confcurl -sk https://10.0.0.1:6443/healthz
Check the clock, which breaks certificate validation in both directions.
timedatectl statusIf the certificate has expired, approve a new signing request or rotate it.
kubectl get csrkubectl certificate approve <csr-name>
kubectl get nodes -o wideDeal with an unresponsive container runtime
PLEG is not healthy, or container operations time out.
PLEG is the kubelet's pod lifecycle event generator. It reports unhealthy when the runtime takes too long to list containers, which usually means the runtime is overloaded or wedged.
sudo crictl info | head -20sudo crictl ps 2>&1 | head
Check how many containers the node is holding — an accumulation of exited containers slows every list operation.
sudo crictl ps -a | wc -lsudo crictl pods | wc -l
PLEG lists every container on every cycle. A node holding thousands of dead containers cannot complete that within the timeout, and the node flaps between Ready and NotReady.
Remove exited containers.
sudo crictl rm --all --force 2>/dev/null || trueCheck I/O wait, which is the other common cause.
iostat -x 2 5vmstat 2 5
Cordon and drain before restarting the runtime, so workloads move rather than being killed.
kubectl cordon node01kubectl drain node01 --ignore-daemonsets --delete-emptydir-datasudo systemctl restart containerd kubeletkubectl uncordon node01
sudo journalctl -u kubelet --since '10 min ago' | grep -ci plegWhere this stops. This write-up was written and checked by hand. It says what each step changes, how to confirm it worked and how to reverse it, and anything destructive is flagged before you reach it. If it does not match what your machine is doing, search the Support Centre for the exact code or message — and when something needs a person, get in touch.