kubernetes: Apiserver to kubelet communication should not use NodeName as address.

In pkg/registry/pod/strategy.go the host address for kubelets seem to be derived from pod.Spec.nodeName. It should however use the Node.Status.Addresses field to find an IP (the docs seem to indicate InternalIP should be used: https://github.com/kubernetes/kubernetes/blob/master/docs/admin/node.md#node-addresses

When a NodeName is resolved to an address/IP which is not open to the apiserver for various reasons (in our case eth0 is blocked for all ingress traffic by security groups) several operations fail. This affects apiserver -> kubelet communication like exec, attach, port-forward.

I’ll try addressing this with a PR, when it’s acknowledged that this is a valid problem.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 6
  • Comments: 54 (47 by maintainers)

Commits related to this issue

Most upvoted comments

I think the ideal scenario would do something like this:

  1. The kubelet records the following addresses, if available:
    • internal IP
    • external IP
    • internal DNS
    • external DNS
    • hostname? (as detected or specified by --override-hostname?)
  2. The apiserver allows prioritizing the address order when resolving a nodeName to an address.

That enables topologies with the apiserver/nodes in the same internal network, or in different networks, with and without DNS.

I’m confused. This is definitely not what we want. Node name should not be used for any kind of resolution. In many clouds node names are not resolvable.

sorry… was unclear. resolve node name to address by looking up the node object and inspecting the reported addresses in its status. That’s what #33718 is doing, defaulting to a reported IP, and what #25532 is doing, defaulting to a reported hostname.

I looked a bit more into the problem, it’s definitely not a low hanging fruit. Changing this behavior (from using Pod.Spec.NodeName to Node.Status.Addresses of the respective node) will require changes in a lot of places. It would mean that we have to defer the TLS cert generation in kubelet until the Addresses list is populated (so we can use those as alt subject in cert).

This list in turn is populated by cloud-providers, which somewhat arbitrarily put addresses there, not necessarily the one to which we bound the kubelet server.

I’d suggest to use the kubelet’s --address parameter in the self-signed cert generation as an alternative subject ( the params we have available at this point). Then the kubelet logic for populating Node.Status.Addresses needs to be extended to add this address with a special type KubeletIP. The apiserver would then connect to the kubelet using this field and Pod.Spec.NodeName as fallback.

Makes some sense? I think it does not break anything. OTOH it’s pretty immersive for something which you could consider as a merely cosmetic issue (nodename == kubelet’s bound ip) or an issue in the realm of the cloud providers (should not rely on nodename for instance discovery).

This has come up many times (see #2462).

Yes, we shouldn’t try to resolve nodeName. Addresses are intended to be used. We’ve talked about adding more information to that array, to better indicate which address should be used by apiserver.