Skip to content

Commit ebf1502

Browse files
authored
Merge pull request kubernetes#80003 from wongma7/cloudprovider-authoritative-hostname
Fix cloud reported hostname being overridden if nodeIP set
2 parents ff1e112 + fc28045 commit ebf1502

File tree

2 files changed

+72
-14
lines changed

2 files changed

+72
-14
lines changed

pkg/kubelet/nodestatus/setters.go

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -90,40 +90,52 @@ func NodeAddress(nodeIP net.IP, // typically Kubelet.nodeIP
9090
}
9191
}
9292
if cloud != nil {
93-
nodeAddresses, err := nodeAddressesFunc()
93+
cloudNodeAddresses, err := nodeAddressesFunc()
9494
if err != nil {
9595
return err
9696
}
97+
98+
var nodeAddresses []v1.NodeAddress
99+
100+
// For every address supplied by the cloud provider that matches nodeIP, nodeIP is the enforced node address for
101+
// that address Type (like InternalIP and ExternalIP), meaning other addresses of the same Type are discarded.
102+
// See #61921 for more information: some cloud providers may supply secondary IPs, so nodeIP serves as a way to
103+
// ensure that the correct IPs show up on a Node object.
97104
if nodeIP != nil {
98105
enforcedNodeAddresses := []v1.NodeAddress{}
99106

100107
nodeIPTypes := make(map[v1.NodeAddressType]bool)
101-
for _, nodeAddress := range nodeAddresses {
108+
for _, nodeAddress := range cloudNodeAddresses {
102109
if nodeAddress.Address == nodeIP.String() {
103110
enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: nodeAddress.Type, Address: nodeAddress.Address})
104111
nodeIPTypes[nodeAddress.Type] = true
105112
}
106113
}
107-
if len(enforcedNodeAddresses) > 0 {
108-
for _, nodeAddress := range nodeAddresses {
109-
if !nodeIPTypes[nodeAddress.Type] && nodeAddress.Type != v1.NodeHostName {
110-
enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: nodeAddress.Type, Address: nodeAddress.Address})
111-
}
112-
}
113114

114-
enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: v1.NodeHostName, Address: hostname})
115-
node.Status.Addresses = enforcedNodeAddresses
116-
return nil
115+
// nodeIP must be among the addresses supplied by the cloud provider
116+
if len(enforcedNodeAddresses) == 0 {
117+
return fmt.Errorf("failed to get node address from cloud provider that matches ip: %v", nodeIP)
118+
}
119+
120+
// nodeIP was found, now use all other addresses supplied by the cloud provider NOT of the same Type as nodeIP.
121+
for _, nodeAddress := range cloudNodeAddresses {
122+
if !nodeIPTypes[nodeAddress.Type] {
123+
enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: nodeAddress.Type, Address: nodeAddress.Address})
124+
}
117125
}
118-
return fmt.Errorf("failed to get node address from cloud provider that matches ip: %v", nodeIP)
126+
127+
nodeAddresses = enforcedNodeAddresses
128+
} else {
129+
// If nodeIP is unset, just use the addresses provided by the cloud provider as-is
130+
nodeAddresses = cloudNodeAddresses
119131
}
120132

121133
switch {
122-
case len(nodeAddresses) == 0:
134+
case len(cloudNodeAddresses) == 0:
123135
// the cloud provider didn't specify any addresses
124136
nodeAddresses = append(nodeAddresses, v1.NodeAddress{Type: v1.NodeHostName, Address: hostname})
125137

126-
case !hasAddressType(nodeAddresses, v1.NodeHostName) && hasAddressValue(nodeAddresses, hostname):
138+
case !hasAddressType(cloudNodeAddresses, v1.NodeHostName) && hasAddressValue(cloudNodeAddresses, hostname):
127139
// the cloud provider didn't specify an address of type Hostname,
128140
// but the auto-detected hostname matched an address reported by the cloud provider,
129141
// so we can add it and count on the value being verifiable via cloud provider metadata

pkg/kubelet/nodestatus/setters_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,21 @@ func TestNodeAddress(t *testing.T) {
179179
},
180180
shouldError: false,
181181
},
182+
{
183+
name: "cloud reports hostname, nodeIP is set, no override",
184+
nodeIP: net.ParseIP("10.1.1.1"),
185+
nodeAddresses: []v1.NodeAddress{
186+
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
187+
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
188+
{Type: v1.NodeHostName, Address: "cloud-host"},
189+
},
190+
expectedAddresses: []v1.NodeAddress{
191+
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
192+
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
193+
{Type: v1.NodeHostName, Address: "cloud-host"}, // cloud-reported hostname wins over detected hostname
194+
},
195+
shouldError: false,
196+
},
182197
{
183198
name: "cloud reports hostname, overridden",
184199
nodeAddresses: []v1.NodeAddress{
@@ -233,6 +248,37 @@ func TestNodeAddress(t *testing.T) {
233248
},
234249
shouldError: false,
235250
},
251+
{
252+
name: "cloud doesn't report hostname, nodeIP is set, no override, detected hostname match",
253+
nodeIP: net.ParseIP("10.1.1.1"),
254+
nodeAddresses: []v1.NodeAddress{
255+
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
256+
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
257+
{Type: v1.NodeExternalDNS, Address: testKubeletHostname}, // cloud-reported address value matches detected hostname
258+
},
259+
expectedAddresses: []v1.NodeAddress{
260+
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
261+
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
262+
{Type: v1.NodeExternalDNS, Address: testKubeletHostname},
263+
{Type: v1.NodeHostName, Address: testKubeletHostname}, // detected hostname gets auto-added
264+
},
265+
shouldError: false,
266+
},
267+
{
268+
name: "cloud doesn't report hostname, nodeIP is set, no override, detected hostname match with same type as nodeIP",
269+
nodeIP: net.ParseIP("10.1.1.1"),
270+
nodeAddresses: []v1.NodeAddress{
271+
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
272+
{Type: v1.NodeInternalIP, Address: testKubeletHostname}, // cloud-reported address value matches detected hostname
273+
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
274+
},
275+
expectedAddresses: []v1.NodeAddress{
276+
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
277+
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
278+
{Type: v1.NodeHostName, Address: testKubeletHostname}, // detected hostname gets auto-added
279+
},
280+
shouldError: false,
281+
},
236282
{
237283
name: "cloud doesn't report hostname, hostname override, hostname mismatch",
238284
nodeAddresses: []v1.NodeAddress{

0 commit comments

Comments
 (0)