Skip to content

Commit 68e4c1e

Browse files
authored
Merge pull request kubernetes#91319 from gongguan/instance-meta
cloud/node-controller use InstanceMetadataByProviderID
2 parents 7942871 + 153745c commit 68e4c1e

File tree

2 files changed

+839
-62
lines changed

2 files changed

+839
-62
lines changed

staging/src/k8s.io/cloud-provider/controllers/node/node_controller.go

Lines changed: 66 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -146,20 +146,14 @@ func (cnc *CloudNodeController) Run(stopCh <-chan struct{}) {
146146

147147
// UpdateNodeStatus updates the node status, such as node addresses
148148
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-
155149
nodes, err := cnc.kubeClient.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{ResourceVersion: "0"})
156150
if err != nil {
157151
klog.Errorf("Error monitoring node status: %v", err)
158152
return
159153
}
160154

161155
for i := range nodes.Items {
162-
cnc.updateNodeAddress(ctx, &nodes.Items[i], instances)
156+
cnc.updateNodeAddress(ctx, &nodes.Items[i])
163157
}
164158

165159
for _, node := range nodes.Items {
@@ -221,29 +215,42 @@ func (cnc *CloudNodeController) reconcileNodeLabels(nodeName string) error {
221215
}
222216

223217
// 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) {
225219
// Do not process nodes that are still tainted
226220
cloudTaint := getCloudTaint(node.Spec.Taints)
227221
if cloudTaint != nil {
228222
klog.V(5).Infof("This node %s is still tainted. Will not process.", node.Name)
229223
return
230224
}
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
239245
}
240246

241-
nodeAddresses, err := getNodeAddressesByProviderIDOrName(ctx, instances, node.Spec.ProviderID, node.Name)
247+
instanceMeta, err := instanceMetadataGetter(node.Spec.ProviderID, node)
242248
if err != nil {
243-
klog.Errorf("Error getting node addresses for node %q: %v", node.Name, err)
249+
utilruntime.HandleError(err)
244250
return
245251
}
246252

253+
nodeAddresses := instanceMeta.NodeAddresses
247254
if len(nodeAddresses) == 0 {
248255
klog.V(5).Infof("Skipping node address update for node %q since cloud provider did not return any", node.Name)
249256
return
@@ -268,19 +275,16 @@ func (cnc *CloudNodeController) updateNodeAddress(ctx context.Context, node *v1.
268275
}
269276
// If nodeIP was suggested by user, ensure that
270277
// 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
276281
}
277282
if !nodeAddressesChangeDetected(node.Status.Addresses, nodeAddresses) {
278283
return
279284
}
280285
newNode := node.DeepCopy()
281286
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 {
284288
klog.Errorf("Error patching node with cloud ip addresses = [%v]", err)
285289
}
286290
}
@@ -322,12 +326,6 @@ func (cnc *CloudNodeController) AddCloudNode(ctx context.Context, obj interface{
322326
func (cnc *CloudNodeController) initializeNode(ctx context.Context, node *v1.Node) {
323327
klog.Infof("Initializing node %s with cloud provider", node.Name)
324328

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-
331329
err := clientretry.RetryOnConflict(UpdateNodeSpecBackoff, func() error {
332330
// TODO(wlan0): Move this logic to the route controller using the node taint instead of condition
333331
// Since there are node taints, do we still need this?
@@ -363,7 +361,9 @@ func (cnc *CloudNodeController) initializeNode(ctx context.Context, node *v1.Nod
363361
return
364362
}
365363

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)
367367
if err != nil {
368368
utilruntime.HandleError(fmt.Errorf("failed to initialize node %s at cloudprovider: %v", node.Name, err))
369369
return
@@ -390,7 +390,7 @@ func (cnc *CloudNodeController) initializeNode(ctx context.Context, node *v1.Nod
390390

391391
// After adding, call UpdateNodeAddress to set the CloudProvider provided IPAddresses
392392
// 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)
394394

395395
klog.Infof("Successfully initialized node %s with cloud provider", node.Name)
396396
return nil
@@ -405,7 +405,7 @@ func (cnc *CloudNodeController) initializeNode(ctx context.Context, node *v1.Nod
405405
// a node object with provider-specific information.
406406
// All of the returned functions are idempotent, because they are used in a retry-if-conflict
407407
// 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) {
409409
var (
410410
nodeModifiers []nodeModifier
411411
providerID string
@@ -435,30 +435,50 @@ func (cnc *CloudNodeController) getNodeModifiersFromCloudProvider(ctx context.Co
435435
providerID = node.Spec.ProviderID
436436
}
437437

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)
439463
if err != nil {
440464
return nil, err
441465
}
442466

443467
// If user provided an IP address, ensure that IP address is found
444468
// 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")
449471
}
450472

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)
456476
nodeModifiers = append(nodeModifiers, func(n *v1.Node) {
457477
if n.Labels == nil {
458478
n.Labels = map[string]string{}
459479
}
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
462482
})
463483
}
464484

0 commit comments

Comments
 (0)