Search code examples
kuberneteskubernetes-servicekubernetes-nodeport

Does NodePort route traffic only to pods that are hosted under node to which we send request? How to achieve that if it's not the case?


NodePort - Expose the service on each Node’s IP

Does this mean that given:

  • NodePort service called nps
  • Two nodes n1 and n2
  • Four pods: p1, p2 (hosted on n1) and p3, p4 (hosted on n2)

a request which we send to URL associated with n2 will be handled only by one of the pods that are assigned to n2 (p3 or p4) (meaning that it's guaranteed that such request wont be handled by p1 or p2 ?).

I assume that this is not the case taking into considerations diagrams like the one below where there seems to be no 'owning' relationship between vm and pod which suggests that node port to which a request goes does not determine which pod will handle the request (I haven't found any article where it's explicitly stated that it is/it is not the case and I'd be thankful if someone could show me a source which explicitly states that): enter image description here
article with above diagram

If that is not the case then is there any other way (other than creating two separate deployments - one for p1, p2 and other one for p3, p4) to achieve such scenario where p1 and p2 are handled by different URL even though they contain the same app as p3 and p4?


Solution

  • Every Node will behave identically when it's called for a NodePort Service. There's no way to make one Node reach one set of Pods and another Node reach another with the same port number.

    As your diagram indicates:

    1. Every Node in the cluster forwards the same host port to a NodePort-type Service;
    2. Every Service (regardless of type:) forwards requests to an arbitrary Pod.

    Services in general don't have any notion of "locality" or "subsets". If your Pods p1..4 are all behind the same Service s then any request to the Service from anywhere can reach any of the Pods. It doesn't matter if the caller is on the same Node, and Kubernetes doesn't specifically try to avoid crossing Nodes.

    If you want different sets of Pods to serve different URLs, I'd probably set up

    1. A separate Ingress (or gateway HTTPRoute) for each endpoint; which would need to target by name
    2. A separate Service for each endpoint; which would match by labels
    3. A separate Deployment for each endpoint.

    The Services and Deployments can be all-but-identical, and a templating tool like Helm or ytt can help produce these. Nothing stops you from running two Deployments with the same image:.

    Note that this setup doesn't consider Nodes at all. In Kubernetes I would not create a Node just to be an HTTP endpoint, and in most cases I wouldn't try to manually assign Pods to Nodes. The standard model is that Nodes can come and go in the same way Pods do (read about the cluster autoscaler for a common cloud-oriented setup).