A NodePort Service allocates a cluster-wide port and arranges forwarding through eligible node addresses. It is useful for external load balancers, development environments and deliberately exposed services. It does not make every address on every machine reachable, nor does it promise an application-level listening socket on each node. Network routing, firewalls, proxy implementation and traffic policy remain part of the path.

NodePort allocates a node-facing entry; targetPort selects the backend port and Service port is the virtual-service entry. Cluster policy can use other-node endpoints and may source-NAT. Local policy needs eligible local endpoints and preserves source along that path, subject to upstream changes. Routing, firewall, address selection, readiness and actual application behavior need separate checks.
NodePort forwards through eligible node addresses to the backend port. Cluster and Local policies change endpoint eligibility; allocation does not prove application reachability. Diagnostics were not rerun.

One allocation, several forwarding paths

The default allocation range is 30000–32767, but administrators can configure another range. Requesting a specific nodePort succeeds only if allocation and validation allow it; a conflict rejects the API transaction. It does not normally create a new Service with a silently unusable port. Inspect the stored object and the command’s exit status separately.

The Service port, targetPort and nodePort have different roles. The Service port is the virtual-service entry, targetPort identifies the backend port, and nodePort is the node-facing entry. A multi-port Service can have several allocations. LoadBalancer Services can also consume NodePorts, unless configured and supported otherwise, so counting only objects whose type is NodePort misses part of the allocation pool.

Forwarding may use iptables, IPVS, nftables or another implementation. Rules can steer packets without an application accepting them on a normal userspace socket. Socket listings therefore cannot establish whether the NodePort datapath works. The configured node-address selection also matters: a reachable primary address does not establish equivalent behavior on secondary or loopback addresses.

Traffic policy changes eligibility

With externalTrafficPolicy Cluster, eligible endpoints can reside on another node. The usual kube-proxy path can perform source NAT, so do not assume that the backend receives the original client address. With Local, external traffic uses local eligible endpoints and preserves the source address along that path. Upstream proxies or load balancers may already have changed it.

A node without suitable local endpoints cannot serve ordinary Local-policy traffic. External load balancing must account for this placement, rather than sending equal traffic to every node indefinitely. Terminating-endpoint handling and proxy versions add further details. Test the installed datapath instead of treating a one-replica example as a complete availability model.

Exposure follows the actual backend

NodePort itself provides transport forwarding, not HTTP authorization or TLS termination. A port selecting application Pods directly may bypass an ingress controller’s authentication, routing or WAF. A port selecting the ingress controller itself does not inherently bypass that controller. Draw the actual chain before deciding which controls a request traverses.

Restrict node-address reachability to the intended callers and record the exposure’s purpose. NodePort can be a supported long-term component; an arbitrary expiry date is not a substitute for ownership, firewall policy and monitoring. A public node IP alone neither proves the port is open nor proves that the application is protected.

When it breaks

Allocation failure, missing endpoints and unreachable nodes are different failures. An empty endpoint set can produce rejection or dropped traffic depending on implementation and policy. A timeout or refusal alone cannot identify a port collision, and HTTP 200 is only an appropriate expectation for an application that intentionally serves that response.

Check selector scope, readiness, targetPort, address selection, firewall rules and traffic policy before changing exposure. Review EndpointSlices for current endpoint conditions; the older Endpoints API is deprecated and can truncate large backend sets. Do not infer that an otherwise healthy Service object certifies the network path.

Check it quickly

These retained diagnostic commands require an explicitly selected disposable cluster, kubectl, jq and Linux networking tools. They were not rerun in this review. The final request assumes the shell is on the intended node and its first reported address is eligible; verify that assumption before running it. They inspect state and attempt one HTTP request, not an exhaustive NodePort test.

kubectl get svc web -o jsonpath='{.spec.type} {.spec.ports[0].nodePort}{"\n"}'
kubectl get endpoints web
kubectl get svc -A -o json | jq -r '.items[] | select(.spec.type=="NodePort") | "\(.spec.ports[0].nodePort) \(.metadata.namespace)/\(.metadata.name)"' | sort -n | uniq -D -w5
ss -lnt | grep -E ':3[0-9]{4}\b'
curl -sS -o /dev/null -w '%{http_code}\n' "http://$(hostname -I | awk '{print $1}'):$(kubectl get svc web -o jsonpath='{.spec.ports[0].nodePort}')/"

The first command shows only the first port. The duplicate search covers first ports on NodePort-type Services only; empty output is expected after normal API allocation and is not a complete capacity audit. The socket filter covers 30000–39999 and cannot identify datapath health or process ownership. Compare EndpointSlices separately. Test Cluster and Local policies on known node addresses in an authorized test network; retain response, endpoint and source-address evidence together.

Sources

  • Kubernetes Service, NodePort type, the 30000-32767 default range and cluster-wide port allocation, checked 2026-10-15.
  • Virtual IPs and Service Proxies, kube-proxy iptables/IPVS rule programming and externalTrafficPolicy, checked 2026-10-15.
  • Using Source IP, SNAT on NodePort and the client-IP consequence, checked 2026-10-15.