KubeEdge Edge Node Failure Response Guide

KubeEdge Edge Node Failure Response Guide

1. Background

In a recent project, we encountered various issues while operating the program, such as nodes being in a 'NotReady' state in 'kubectl get nodes', 'kubectl exec' becoming unresponsive, and Pods suddenly changing to 'Evicted' status. Therefore, based on the four types of failures encountered during actual operations, we will draft an issue response guide for the KubeEdge environment as follows.

2. Introduction

Unlike a typical cluster based on Kubernetes, KubeEdge is between the cloud and edge nodes CloudCore ↔ EdgeCoreThere are additional tunnels. Thanks to that, edge nodes can operate even in unstable network environments, but at the same time, the causes of failures become more complicated.

3. Type of Disability

Disability Type 1

kubectl exec failed — "unexpected EOF"

(1) Symptoms

$ kubectl exec -it my-app-6jf2m -n iot-edge -- /bin/bash
error: Internal error occurred: error sending request:
Post "https://192.168.1.3:10351/exec/...": unexpected EOF

I ran ‘kubectl exec’ and the connection itself dropped, leaving it unresponsive. Other Pods on the same node appear to be in a Running state, but there are cases where only exec is not working.

(2) Cause Analysis

To make 'kubectl exec' work in KubeEdgeEdgeStreamYou must have this feature enabled. If this feature is turned off, the exec tunnel leading from API Server → CloudCore → EdgeCore will not be established.

In a standard Kubernetes environment, the API Server accesses the kubelet's port 10250 directly to handle exec, but KubeEdge does not have this path. Without EdgeStream, exec, logs, and port-forward will not work.

[kubectl exec flow in KubeEdge]
API Server
    ↓
CloudCore (streamPort: 10003)
    ↓ ← without this tunnel, unexpected EOF occurs
EdgeCore (edgeStream.server)
    ↓
컨테이너

(3) Solutions

Check and activate CloudCore settings:

# cloudcore.yaml
cloudStream:
  enable: true
  streamPort: 10003
  tlsTunnelCAFile: /etc/kubeedge/ca/rootCA.crt
  tlsTunnelCertFile: /etc/kubeedge/certs/server.crt
  tlsTunnelPrivateKeyFile: /etc/kubeedge/certs/server.key

Check and activate EdgeCore settings:

# edgecore.yaml
edgeStream:
  enable: true
  handshakeTimeout: 30
  readDeadline: 15
  server: <CloudCore_IP>:10004
  tlsTunnelCAFile: /etc/kubeedge/ca/rootCA.crt
  tlsTunnelCertFile: /etc/kubeedge/certs/server.crt
  tlsTunnelPrivateKeyFile: /etc/kubeedge/certs/server.key
  writeDeadline: 15

Both sides need to be restarted after configuration changes:

# On the master node where CloudCore is running
systemctl restart cloudcore.

# On the edge node
systemctl restart edgecore

Failure type 2

Pod Eviction due to DiskPressure

(1) Symptoms

$ kubectl get po -A -o wide | grep <NodeName>
iot-edge chronograf-xxxxx 0/1 Evicted 0 2m
iot-edge influxdb-xxxxx 0/1 Evicted 0 9m
iot-edge my-app-xxxxx 0/1 Evicted 0 14m

Pods on a specific node will be uniformly in an Evicted state. If not just one or two but all Pods on that node are evicted, it indicates a node-level resource issue.

(2) Cause analysis

Eviction is a mechanism where the kubelet (in KubeEdge, edgecore) forcefully terminates Pods when it detects insufficient node resources. The cause can be directly verified using ‘kubectl describe node’:

kubectl describe node <NodeName> | grep -A5 "Conditions"

In actual cases, messages like the following were observed:

DiskPressure True ...
Message: The node was low on resource: ephemeral-storage.
  Threshold: 37556267476 (~35GB)
  Available: 36674584Ki (~34.9GB)

As soon as the available disk falls below a threshold, the kubelet forcefully evicts the Pods on that node

Check disk usage
SSH into the edge node to check where the disk is being consumed:

df -h
du -sh /* 2>/dev/null | sort -rh | head -15

In actual cases, one log directory of a specific application occupied 89% of the entire disk.

$ du -sh /var/app/logs/*/
166G /var/app/logs/device-001.ASSET/

(3) Solutions

Cleanup of old logs(Make sure to check if preservation is necessary before deletion!)

# Delete files older than N days
find /var/app/logs -mtime +7 -type f -delete

Cleanup of unused container images

crictl rmi --prune

Reassessment of DiskPressure by restarting edgecore

systemctl restart edgecore

Cleanup and redistribution of Evicted Pods

# On the master node
kubectl get pods -A | grep Evicted | awk '{print "kubectl delete pod " $2 " -n " $1}' | sh

Type of fault 3

Init Container ImagePullBackOff — DNS failure

(1) Symptoms

$ kubectl describe pod my-app-qn6r8 -n iot-edge
Init Containers:
  init-snapshot:
    State: Waiting
      Reason: ImagePullBackOff
    Image: registry.company.internal:5000/infra/busybox:latest

This occurs when the image pull fails in the Init Container, not the main container. If the Init Container fails, the main container does not even start.

In this case, the previous termination state of the main container is shown as follows:

Last State: Terminated
  Reason: Unknown
  Exit Code: 255

Exit Code 255 indicates that the container runtime forcibly terminated the process, which is mostly a result of node-level issues (previous DiskPressure, network disconnection, etc.).

(2) Cause analysis — Private registry DNS failure

The causes of ImagePullBackOff are varied, but in IoT environments using the company's private registry,DNS failureis particularly frequent.

Verification method:

# On the edge node
nslookup registry.company.internal

If DNS SERVFAIL appears, it indicates that the domain itself cannot be resolved.

server can't find registry.company.internal: SERVFAIL

(3) Solutions

Quick temporary fix — register in /etc/hosts
Check the IP from another normal node and directly register in '/etc/hosts':

# Resolve IP from a healthy node
nslookup registry.company.internal
# Add entry to /etc/hosts on the affected node
echo "<IP> registry.company.internal" >> /etc/hosts
# Test image pull
crictl pull registry.company.internal:5000/infra/busybox:latest

Determine the root cause of DNS issues

After temporary measures, check the status of 'systemd-resolved' and restart it:

systemctl status systemd-resolved
systemctl restart systemd-resolved

# Verify DNS resolution is restored
nslookup registry.company.internal

Restart Pod after DNS recovery

# Force delete and recreate the Pod from the master node
kubectl delete pod my-app-qn6r8 -n iot-edge --force --grace-period=0

# Watch Pod status
kubectl get pod -n iot-edge -w | grep my-app

4. Summary

- If 'kubectl exec' doesn't work, it may not be a kubelet issue but rather a problem with EdgeStream configuration.

- If Pods are being evicted in large numbers, first check the disk usage on the nodes.

- ImagePullBackOff may not be an image issue but rather a DNS failure.

The edge environment presents complex challenges such as unstable onsite networks, limited disk capacity, and management of numerous distributed nodes, unlike data centers. Sharing the above checklist within the team can reduce response time regardless of who is on call.

Jsia

Site footer