Kubernetes
NGINX
Raspberry Pi
nodePort
troubleshooting

Unable to access NGINX nodePort service in K8 cluster running on RPI

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A NodePort service should let you reach a pod through http://NODE_IP:NODE_PORT, but on a Raspberry Pi Kubernetes cluster there are a few extra failure points. ARM image compatibility, lightweight distributions such as k3s, home-network firewalls, and incorrect node IP assumptions all show up more often on Pi clusters than on cloud VMs.

The right way to debug this is from the inside out: confirm the pod is healthy, confirm the service has endpoints, then confirm traffic can reach the node and that kube-proxy is publishing the port correctly.

Verify the Pod and Service First

Start by checking whether the NGINX pod is actually running and ready. A NodePort can exist even when there are no healthy endpoints behind it.

bash
kubectl get pods -o wide
kubectl get svc
kubectl get endpoints

If the service shows no endpoints, the selector does not match the pod labels or the pod is not ready yet.

A working example looks like this:

yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: nginx
5spec:
6  replicas: 1
7  selector:
8    matchLabels:
9      app: nginx
10  template:
11    metadata:
12      labels:
13        app: nginx
14    spec:
15      containers:
16        - name: nginx
17          image: nginx:stable-alpine
18          ports:
19            - containerPort: 80
20---
21apiVersion: v1
22kind: Service
23metadata:
24  name: nginx-nodeport
25spec:
26  type: NodePort
27  selector:
28    app: nginx
29  ports:
30    - port: 80
31      targetPort: 80
32      nodePort: 30080

If kubectl get endpoints nginx-nodeport is empty, fix that before looking at networking.

Test Reachability from Inside the Cluster

Before testing from your laptop or phone, test from inside the cluster. That tells you whether the application path works independently of the external network.

bash
kubectl run curl --rm -it --image=curlimages/curl -- sh
curl http://nginx-nodeport.default.svc.cluster.local
curl http://<pod-ip>:80

If those requests fail, the problem is not NodePort exposure. It is the pod, container port, or service selector.

If they succeed, move outward and test the node IP.

Use the Correct Node IP and Port

A common mistake is hitting the wrong address. NodePort listens on the node's network IP, not the cluster service IP. On a Raspberry Pi cluster, nodes may have multiple interfaces such as Ethernet, Wi-Fi, VPN, and internal overlay networking.

Check the node addresses:

bash
kubectl get nodes -o wide

Then test from another machine on the same network:

bash
curl http://192.168.1.50:30080

If you test from the same Raspberry Pi node, remember that some home-router setups or local firewall configurations behave differently for local versus remote traffic.

Check kube-proxy, Firewall, and CNI Behavior

NodePort depends on iptables or IPVS rules installed by kube-proxy. If that component is unhealthy, the service may exist in Kubernetes while the node never forwards packets.

bash
kubectl -n kube-system get pods
kubectl -n kube-system logs daemonset/kube-proxy
sudo iptables -t nat -L -n | grep 30080

Also inspect host firewall rules. On Ubuntu or Debian-based Pi nodes, ufw or raw iptables rules may block high ports.

bash
sudo ufw status
sudo ss -ltnp | grep 30080

On k3s, the networking stack is simplified, but the same core checks apply. If you use nftables or a custom CNI, verify those components are not dropping traffic before it reaches the service.

Make Sure the Image Runs on ARM

Raspberry Pi nodes are ARM devices, so an x86-only container image will fail or crash-loop. NGINX official images are generally multi-architecture, but custom images or sidecars may not be.

Check the pod status and logs:

bash
kubectl describe pod <nginx-pod-name>
kubectl logs <nginx-pod-name>

If the pod is restarting or never becomes ready, the service may technically exist while there is nothing usable behind it.

When to Use LoadBalancer Instead

NodePort is good for debugging and small internal setups. For a cleaner Raspberry Pi homelab, consider MetalLB with a LoadBalancer service. That gives you a stable LAN IP and removes some of the friction of choosing the right node address.

Still, if NodePort does not work, do not skip the diagnosis. The same missing endpoints or broken network path will often affect LoadBalancer too.

Common Pitfalls

  • Testing the service IP instead of the node IP. NodePort is reached through the node address, not the ClusterIP.
  • Ignoring empty endpoints. A service with no matching ready pods cannot forward traffic.
  • Using an image that is not compatible with ARM. On Raspberry Pi, architecture mismatches are a real failure mode.
  • Forgetting host firewall rules on high ports such as 30080. Kubernetes objects do not automatically override OS-level filtering.
  • Assuming external access proves application health. Always test pod and service connectivity from inside the cluster first.

Summary

  • Diagnose NodePort issues from the inside out: pod, endpoints, node IP, then host networking.
  • Confirm the service selector matches a ready NGINX pod.
  • Reach the service through NODE_IP:NODE_PORT, not through the ClusterIP.
  • Check kube-proxy, iptables, and firewall rules on Raspberry Pi nodes.
  • Verify the container image actually runs on ARM before chasing network problems.

Course illustration
Course illustration

All Rights Reserved.