mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 01:06:27 +00:00
Merge pull request #80003 from wongma7/cloudprovider-authoritative-hostname
Fix cloud reported hostname being overridden if nodeIP set
This commit is contained in:
commit
ebf15029da
@ -90,40 +90,52 @@ func NodeAddress(nodeIP net.IP, // typically Kubelet.nodeIP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if cloud != nil {
|
if cloud != nil {
|
||||||
nodeAddresses, err := nodeAddressesFunc()
|
cloudNodeAddresses, err := nodeAddressesFunc()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nodeAddresses []v1.NodeAddress
|
||||||
|
|
||||||
|
// For every address supplied by the cloud provider that matches nodeIP, nodeIP is the enforced node address for
|
||||||
|
// that address Type (like InternalIP and ExternalIP), meaning other addresses of the same Type are discarded.
|
||||||
|
// See #61921 for more information: some cloud providers may supply secondary IPs, so nodeIP serves as a way to
|
||||||
|
// ensure that the correct IPs show up on a Node object.
|
||||||
if nodeIP != nil {
|
if nodeIP != nil {
|
||||||
enforcedNodeAddresses := []v1.NodeAddress{}
|
enforcedNodeAddresses := []v1.NodeAddress{}
|
||||||
|
|
||||||
nodeIPTypes := make(map[v1.NodeAddressType]bool)
|
nodeIPTypes := make(map[v1.NodeAddressType]bool)
|
||||||
for _, nodeAddress := range nodeAddresses {
|
for _, nodeAddress := range cloudNodeAddresses {
|
||||||
if nodeAddress.Address == nodeIP.String() {
|
if nodeAddress.Address == nodeIP.String() {
|
||||||
enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: nodeAddress.Type, Address: nodeAddress.Address})
|
enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: nodeAddress.Type, Address: nodeAddress.Address})
|
||||||
nodeIPTypes[nodeAddress.Type] = true
|
nodeIPTypes[nodeAddress.Type] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(enforcedNodeAddresses) > 0 {
|
|
||||||
for _, nodeAddress := range nodeAddresses {
|
|
||||||
if !nodeIPTypes[nodeAddress.Type] && nodeAddress.Type != v1.NodeHostName {
|
|
||||||
enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: nodeAddress.Type, Address: nodeAddress.Address})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: v1.NodeHostName, Address: hostname})
|
// nodeIP must be among the addresses supplied by the cloud provider
|
||||||
node.Status.Addresses = enforcedNodeAddresses
|
if len(enforcedNodeAddresses) == 0 {
|
||||||
return nil
|
return fmt.Errorf("failed to get node address from cloud provider that matches ip: %v", nodeIP)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("failed to get node address from cloud provider that matches ip: %v", nodeIP)
|
|
||||||
|
// nodeIP was found, now use all other addresses supplied by the cloud provider NOT of the same Type as nodeIP.
|
||||||
|
for _, nodeAddress := range cloudNodeAddresses {
|
||||||
|
if !nodeIPTypes[nodeAddress.Type] {
|
||||||
|
enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: nodeAddress.Type, Address: nodeAddress.Address})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeAddresses = enforcedNodeAddresses
|
||||||
|
} else {
|
||||||
|
// If nodeIP is unset, just use the addresses provided by the cloud provider as-is
|
||||||
|
nodeAddresses = cloudNodeAddresses
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case len(nodeAddresses) == 0:
|
case len(cloudNodeAddresses) == 0:
|
||||||
// the cloud provider didn't specify any addresses
|
// the cloud provider didn't specify any addresses
|
||||||
nodeAddresses = append(nodeAddresses, v1.NodeAddress{Type: v1.NodeHostName, Address: hostname})
|
nodeAddresses = append(nodeAddresses, v1.NodeAddress{Type: v1.NodeHostName, Address: hostname})
|
||||||
|
|
||||||
case !hasAddressType(nodeAddresses, v1.NodeHostName) && hasAddressValue(nodeAddresses, hostname):
|
case !hasAddressType(cloudNodeAddresses, v1.NodeHostName) && hasAddressValue(cloudNodeAddresses, hostname):
|
||||||
// the cloud provider didn't specify an address of type Hostname,
|
// the cloud provider didn't specify an address of type Hostname,
|
||||||
// but the auto-detected hostname matched an address reported by the cloud provider,
|
// but the auto-detected hostname matched an address reported by the cloud provider,
|
||||||
// so we can add it and count on the value being verifiable via cloud provider metadata
|
// so we can add it and count on the value being verifiable via cloud provider metadata
|
||||||
|
@ -179,6 +179,21 @@ func TestNodeAddress(t *testing.T) {
|
|||||||
},
|
},
|
||||||
shouldError: false,
|
shouldError: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "cloud reports hostname, nodeIP is set, no override",
|
||||||
|
nodeIP: net.ParseIP("10.1.1.1"),
|
||||||
|
nodeAddresses: []v1.NodeAddress{
|
||||||
|
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
|
||||||
|
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
|
||||||
|
{Type: v1.NodeHostName, Address: "cloud-host"},
|
||||||
|
},
|
||||||
|
expectedAddresses: []v1.NodeAddress{
|
||||||
|
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
|
||||||
|
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
|
||||||
|
{Type: v1.NodeHostName, Address: "cloud-host"}, // cloud-reported hostname wins over detected hostname
|
||||||
|
},
|
||||||
|
shouldError: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "cloud reports hostname, overridden",
|
name: "cloud reports hostname, overridden",
|
||||||
nodeAddresses: []v1.NodeAddress{
|
nodeAddresses: []v1.NodeAddress{
|
||||||
@ -233,6 +248,37 @@ func TestNodeAddress(t *testing.T) {
|
|||||||
},
|
},
|
||||||
shouldError: false,
|
shouldError: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "cloud doesn't report hostname, nodeIP is set, no override, detected hostname match",
|
||||||
|
nodeIP: net.ParseIP("10.1.1.1"),
|
||||||
|
nodeAddresses: []v1.NodeAddress{
|
||||||
|
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
|
||||||
|
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
|
||||||
|
{Type: v1.NodeExternalDNS, Address: testKubeletHostname}, // cloud-reported address value matches detected hostname
|
||||||
|
},
|
||||||
|
expectedAddresses: []v1.NodeAddress{
|
||||||
|
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
|
||||||
|
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
|
||||||
|
{Type: v1.NodeExternalDNS, Address: testKubeletHostname},
|
||||||
|
{Type: v1.NodeHostName, Address: testKubeletHostname}, // detected hostname gets auto-added
|
||||||
|
},
|
||||||
|
shouldError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cloud doesn't report hostname, nodeIP is set, no override, detected hostname match with same type as nodeIP",
|
||||||
|
nodeIP: net.ParseIP("10.1.1.1"),
|
||||||
|
nodeAddresses: []v1.NodeAddress{
|
||||||
|
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
|
||||||
|
{Type: v1.NodeInternalIP, Address: testKubeletHostname}, // cloud-reported address value matches detected hostname
|
||||||
|
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
|
||||||
|
},
|
||||||
|
expectedAddresses: []v1.NodeAddress{
|
||||||
|
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
|
||||||
|
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
|
||||||
|
{Type: v1.NodeHostName, Address: testKubeletHostname}, // detected hostname gets auto-added
|
||||||
|
},
|
||||||
|
shouldError: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "cloud doesn't report hostname, hostname override, hostname mismatch",
|
name: "cloud doesn't report hostname, hostname override, hostname mismatch",
|
||||||
nodeAddresses: []v1.NodeAddress{
|
nodeAddresses: []v1.NodeAddress{
|
||||||
|
Loading…
Reference in New Issue
Block a user