@@ -146,20 +146,14 @@ func (cnc *CloudNodeController) Run(stopCh <-chan struct{}) {
146
146
147
147
// UpdateNodeStatus updates the node status, such as node addresses
148
148
func (cnc * CloudNodeController ) UpdateNodeStatus (ctx context.Context ) {
149
- instances , ok := cnc .cloud .Instances ()
150
- if ! ok {
151
- utilruntime .HandleError (fmt .Errorf ("failed to get instances from cloud provider" ))
152
- return
153
- }
154
-
155
149
nodes , err := cnc .kubeClient .CoreV1 ().Nodes ().List (context .TODO (), metav1.ListOptions {ResourceVersion : "0" })
156
150
if err != nil {
157
151
klog .Errorf ("Error monitoring node status: %v" , err )
158
152
return
159
153
}
160
154
161
155
for i := range nodes .Items {
162
- cnc .updateNodeAddress (ctx , & nodes .Items [i ], instances )
156
+ cnc .updateNodeAddress (ctx , & nodes .Items [i ])
163
157
}
164
158
165
159
for _ , node := range nodes .Items {
@@ -221,29 +215,42 @@ func (cnc *CloudNodeController) reconcileNodeLabels(nodeName string) error {
221
215
}
222
216
223
217
// UpdateNodeAddress updates the nodeAddress of a single node
224
- func (cnc * CloudNodeController ) updateNodeAddress (ctx context.Context , node * v1.Node , instances cloudprovider. Instances ) {
218
+ func (cnc * CloudNodeController ) updateNodeAddress (ctx context.Context , node * v1.Node ) {
225
219
// Do not process nodes that are still tainted
226
220
cloudTaint := getCloudTaint (node .Spec .Taints )
227
221
if cloudTaint != nil {
228
222
klog .V (5 ).Infof ("This node %s is still tainted. Will not process." , node .Name )
229
223
return
230
224
}
231
- // Node that isn't present according to the cloud provider shouldn't have its address updated
232
- exists , err := ensureNodeExistsByProviderID (ctx , instances , node )
233
- if err != nil {
234
- // Continue to update node address when not sure the node is not exists
235
- klog .Errorf ("%v" , err )
236
- } else if ! exists {
237
- klog .V (4 ).Infof ("The node %s is no longer present according to the cloud provider, do not process." , node .Name )
238
- return
225
+
226
+ instanceMetadataGetter := func (providerID string , node * v1.Node ) (* cloudprovider.InstanceMetadata , error ) {
227
+ if instancesV2 , ok := cnc .cloud .InstancesV2 (); instancesV2 != nil && ok {
228
+ return instancesV2 .InstanceMetadataByProviderID (ctx , providerID )
229
+ }
230
+
231
+ // If InstancesV2 not implement, use Instances.
232
+ instances , ok := cnc .cloud .Instances ()
233
+ if ! ok {
234
+ return nil , fmt .Errorf ("failed to get instances from cloud provider" )
235
+ }
236
+
237
+ nodeAddresses , err := getNodeAddressesByProviderIDOrName (ctx , instances , node .Spec .ProviderID , node .Name )
238
+ if err != nil {
239
+ klog .Errorf ("Error getting node addresses for node %q: %v" , node .Name , err )
240
+ return nil , err
241
+ }
242
+ return & cloudprovider.InstanceMetadata {
243
+ NodeAddresses : nodeAddresses ,
244
+ }, nil
239
245
}
240
246
241
- nodeAddresses , err := getNodeAddressesByProviderIDOrName ( ctx , instances , node .Spec .ProviderID , node . Name )
247
+ instanceMeta , err := instanceMetadataGetter ( node .Spec .ProviderID , node )
242
248
if err != nil {
243
- klog . Errorf ( "Error getting node addresses for node %q: %v" , node . Name , err )
249
+ utilruntime . HandleError ( err )
244
250
return
245
251
}
246
252
253
+ nodeAddresses := instanceMeta .NodeAddresses
247
254
if len (nodeAddresses ) == 0 {
248
255
klog .V (5 ).Infof ("Skipping node address update for node %q since cloud provider did not return any" , node .Name )
249
256
return
@@ -268,19 +275,16 @@ func (cnc *CloudNodeController) updateNodeAddress(ctx context.Context, node *v1.
268
275
}
269
276
// If nodeIP was suggested by user, ensure that
270
277
// it can be found in the cloud as well (consistent with the behaviour in kubelet)
271
- if nodeIP , ok := ensureNodeProvidedIPExists (node , nodeAddresses ); ok {
272
- if nodeIP == nil {
273
- klog .Errorf ("Specified Node IP not found in cloudprovider for node %q" , node .Name )
274
- return
275
- }
278
+ if nodeIP , ok := ensureNodeProvidedIPExists (node , nodeAddresses ); ok && nodeIP == nil {
279
+ klog .Errorf ("Specified Node IP not found in cloudprovider for node %q" , node .Name )
280
+ return
276
281
}
277
282
if ! nodeAddressesChangeDetected (node .Status .Addresses , nodeAddresses ) {
278
283
return
279
284
}
280
285
newNode := node .DeepCopy ()
281
286
newNode .Status .Addresses = nodeAddresses
282
- _ , _ , err = cloudnodeutil .PatchNodeStatus (cnc .kubeClient .CoreV1 (), types .NodeName (node .Name ), node , newNode )
283
- if err != nil {
287
+ if _ , _ , err := cloudnodeutil .PatchNodeStatus (cnc .kubeClient .CoreV1 (), types .NodeName (node .Name ), node , newNode ); err != nil {
284
288
klog .Errorf ("Error patching node with cloud ip addresses = [%v]" , err )
285
289
}
286
290
}
@@ -322,12 +326,6 @@ func (cnc *CloudNodeController) AddCloudNode(ctx context.Context, obj interface{
322
326
func (cnc * CloudNodeController ) initializeNode (ctx context.Context , node * v1.Node ) {
323
327
klog .Infof ("Initializing node %s with cloud provider" , node .Name )
324
328
325
- instances , ok := cnc .cloud .Instances ()
326
- if ! ok {
327
- utilruntime .HandleError (fmt .Errorf ("failed to get instances from cloud provider" ))
328
- return
329
- }
330
-
331
329
err := clientretry .RetryOnConflict (UpdateNodeSpecBackoff , func () error {
332
330
// TODO(wlan0): Move this logic to the route controller using the node taint instead of condition
333
331
// Since there are node taints, do we still need this?
@@ -363,7 +361,9 @@ func (cnc *CloudNodeController) initializeNode(ctx context.Context, node *v1.Nod
363
361
return
364
362
}
365
363
366
- nodeModifiers , err := cnc .getNodeModifiersFromCloudProvider (ctx , curNode , instances )
364
+ // TODO: getNodeModifiersFromCloudProvider and updateNodeAddress both call cloud api to get instanceMetadata,
365
+ // get instanceMetadata and pass it to getNodeModifiersFromCloudProvider and updateNodeAddress which reduces api calls.
366
+ nodeModifiers , err := cnc .getNodeModifiersFromCloudProvider (ctx , curNode )
367
367
if err != nil {
368
368
utilruntime .HandleError (fmt .Errorf ("failed to initialize node %s at cloudprovider: %v" , node .Name , err ))
369
369
return
@@ -390,7 +390,7 @@ func (cnc *CloudNodeController) initializeNode(ctx context.Context, node *v1.Nod
390
390
391
391
// After adding, call UpdateNodeAddress to set the CloudProvider provided IPAddresses
392
392
// So that users do not see any significant delay in IP addresses being filled into the node
393
- cnc .updateNodeAddress (ctx , curNode , instances )
393
+ cnc .updateNodeAddress (ctx , curNode )
394
394
395
395
klog .Infof ("Successfully initialized node %s with cloud provider" , node .Name )
396
396
return nil
@@ -405,7 +405,7 @@ func (cnc *CloudNodeController) initializeNode(ctx context.Context, node *v1.Nod
405
405
// a node object with provider-specific information.
406
406
// All of the returned functions are idempotent, because they are used in a retry-if-conflict
407
407
// loop, meaning they could get called multiple times.
408
- func (cnc * CloudNodeController ) getNodeModifiersFromCloudProvider (ctx context.Context , node * v1.Node , instances cloudprovider. Instances ) ([]nodeModifier , error ) {
408
+ func (cnc * CloudNodeController ) getNodeModifiersFromCloudProvider (ctx context.Context , node * v1.Node ) ([]nodeModifier , error ) {
409
409
var (
410
410
nodeModifiers []nodeModifier
411
411
providerID string
@@ -435,30 +435,50 @@ func (cnc *CloudNodeController) getNodeModifiersFromCloudProvider(ctx context.Co
435
435
providerID = node .Spec .ProviderID
436
436
}
437
437
438
- nodeAddresses , err := getNodeAddressesByProviderIDOrName (ctx , instances , providerID , node .Name )
438
+ instanceMetadataGetter := func (providerID string , nodeName string ) (* cloudprovider.InstanceMetadata , error ) {
439
+ if instancesV2 , ok := cnc .cloud .InstancesV2 (); instancesV2 != nil && ok {
440
+ return instancesV2 .InstanceMetadataByProviderID (ctx , providerID )
441
+ }
442
+
443
+ // If InstancesV2 not implement, use Instances.
444
+ instances , ok := cnc .cloud .Instances ()
445
+ if ! ok {
446
+ return nil , fmt .Errorf ("failed to get instances from cloud provider" )
447
+ }
448
+ nodeAddresses , err := getNodeAddressesByProviderIDOrName (ctx , instances , providerID , nodeName )
449
+ if err != nil {
450
+ return nil , err
451
+ }
452
+ instanceType , err := getInstanceTypeByProviderIDOrName (ctx , instances , providerID , nodeName )
453
+ if err != nil {
454
+ return nil , err
455
+ }
456
+ return & cloudprovider.InstanceMetadata {
457
+ Type : instanceType ,
458
+ NodeAddresses : nodeAddresses ,
459
+ }, nil
460
+ }
461
+
462
+ instanceMeta , err := instanceMetadataGetter (providerID , node .Name )
439
463
if err != nil {
440
464
return nil , err
441
465
}
442
466
443
467
// If user provided an IP address, ensure that IP address is found
444
468
// in the cloud provider before removing the taint on the node
445
- if nodeIP , ok := ensureNodeProvidedIPExists (node , nodeAddresses ); ok {
446
- if nodeIP == nil {
447
- return nil , errors .New ("failed to find kubelet node IP from cloud provider" )
448
- }
469
+ if nodeIP , ok := ensureNodeProvidedIPExists (node , instanceMeta .NodeAddresses ); ok && nodeIP == nil {
470
+ return nil , errors .New ("failed to find kubelet node IP from cloud provider" )
449
471
}
450
472
451
- if instanceType , err := getInstanceTypeByProviderIDOrName (ctx , instances , providerID , node .Name ); err != nil {
452
- return nil , err
453
- } else if instanceType != "" {
454
- klog .V (2 ).Infof ("Adding node label from cloud provider: %s=%s" , v1 .LabelInstanceType , instanceType )
455
- klog .V (2 ).Infof ("Adding node label from cloud provider: %s=%s" , v1 .LabelInstanceTypeStable , instanceType )
473
+ if instanceMeta .Type != "" {
474
+ klog .V (2 ).Infof ("Adding node label from cloud provider: %s=%s" , v1 .LabelInstanceType , instanceMeta .Type )
475
+ klog .V (2 ).Infof ("Adding node label from cloud provider: %s=%s" , v1 .LabelInstanceTypeStable , instanceMeta .Type )
456
476
nodeModifiers = append (nodeModifiers , func (n * v1.Node ) {
457
477
if n .Labels == nil {
458
478
n .Labels = map [string ]string {}
459
479
}
460
- n .Labels [v1 .LabelInstanceType ] = instanceType
461
- n .Labels [v1 .LabelInstanceTypeStable ] = instanceType
480
+ n .Labels [v1 .LabelInstanceType ] = instanceMeta . Type
481
+ n .Labels [v1 .LabelInstanceTypeStable ] = instanceMeta . Type
462
482
})
463
483
}
464
484
0 commit comments