in azure/azure_vmss.go [1102:1240]
func (ss *scaleSet) ensureVMSSInPool(service *v1.Service, nodes []*v1.Node, backendPoolID string, vmSetName string) error {
klog.V(2).Infof("ensureVMSSInPool: ensuring VMSS with backendPoolID %s", backendPoolID)
vmssNamesMap := make(map[string]bool)
// the single standard load balancer supports multiple vmss in its backend while
// multiple standard load balancers and the basic load balancer doesn't
if ss.useStandardLoadBalancer() && !ss.EnableMultipleStandardLoadBalancers {
for _, node := range nodes {
if ss.excludeMasterNodesFromStandardLB() && isMasterNode(node) {
continue
}
shouldExcludeLoadBalancer, err := ss.ShouldNodeExcludedFromLoadBalancer(node.Name)
if err != nil {
klog.Errorf("ShouldNodeExcludedFromLoadBalancer(%s) failed with error: %v", node.Name, err)
return err
}
if shouldExcludeLoadBalancer {
klog.V(4).Infof("Excluding unmanaged/external-resource-group node %q", node.Name)
continue
}
// in this scenario the vmSetName is an empty string and the name of vmss should be obtained from the provider IDs of nodes
resourceGroupName, vmssName, err := getVmssAndResourceGroupNameByVMProviderID(node.Spec.ProviderID)
if err != nil {
klog.V(4).Infof("ensureVMSSInPool: found VMAS node %s, will skip checking and continue", node.Name)
continue
}
// only vmsses in the resource group same as it's in azure config are included
if strings.EqualFold(resourceGroupName, ss.ResourceGroup) {
vmssNamesMap[vmssName] = true
}
}
} else {
vmssNamesMap[vmSetName] = true
}
klog.V(2).Infof("ensureVMSSInPool begins to update VMSS %v with backendPoolID %s", vmssNamesMap, backendPoolID)
for vmssName := range vmssNamesMap {
vmss, err := ss.getVMSS(vmssName, azcache.CacheReadTypeDefault)
if err != nil {
return err
}
// When vmss is being deleted, CreateOrUpdate API would report "the vmss is being deleted" error.
// Since it is being deleted, we shouldn't send more CreateOrUpdate requests for it.
if vmss.ProvisioningState != nil && strings.EqualFold(*vmss.ProvisioningState, virtualMachineScaleSetsDeallocating) {
klog.V(3).Infof("ensureVMSSInPool: found vmss %s being deleted, skipping", vmssName)
continue
}
if vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations == nil {
klog.V(4).Infof("EnsureHostInPool: cannot obtain the primary network interface configuration of vmss %s", vmssName)
continue
}
vmssNIC := *vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations
primaryNIC, err := ss.getPrimaryNetworkInterfaceConfigurationForScaleSet(vmssNIC, vmssName)
if err != nil {
return err
}
var primaryIPConfig *compute.VirtualMachineScaleSetIPConfiguration
ipv6 := utilnet.IsIPv6String(service.Spec.ClusterIP)
// Find primary network interface configuration.
if !ss.Cloud.ipv6DualStackEnabled && !ipv6 {
// Find primary IP configuration.
primaryIPConfig, err = getPrimaryIPConfigFromVMSSNetworkConfig(primaryNIC)
if err != nil {
return err
}
} else {
primaryIPConfig, err = ss.getConfigForScaleSetByIPFamily(primaryNIC, "", ipv6)
if err != nil {
return err
}
}
loadBalancerBackendAddressPools := []compute.SubResource{}
if primaryIPConfig.LoadBalancerBackendAddressPools != nil {
loadBalancerBackendAddressPools = *primaryIPConfig.LoadBalancerBackendAddressPools
}
var found bool
for _, loadBalancerBackendAddressPool := range loadBalancerBackendAddressPools {
if strings.EqualFold(*loadBalancerBackendAddressPool.ID, backendPoolID) {
found = true
break
}
}
if found {
continue
}
if ss.useStandardLoadBalancer() && len(loadBalancerBackendAddressPools) > 0 {
// Although standard load balancer supports backends from multiple scale
// sets, the same network interface couldn't be added to more than one load balancer of
// the same type. Omit those nodes (e.g. masters) so Azure ARM won't complain
// about this.
newBackendPoolsIDs := make([]string, 0, len(loadBalancerBackendAddressPools))
for _, pool := range loadBalancerBackendAddressPools {
if pool.ID != nil {
newBackendPoolsIDs = append(newBackendPoolsIDs, *pool.ID)
}
}
isSameLB, oldLBName, err := isBackendPoolOnSameLB(backendPoolID, newBackendPoolsIDs)
if err != nil {
return err
}
if !isSameLB {
klog.V(4).Infof("VMSS %q has already been added to LB %q, omit adding it to a new one", vmssName, oldLBName)
return nil
}
}
// Compose a new vmss with added backendPoolID.
loadBalancerBackendAddressPools = append(loadBalancerBackendAddressPools,
compute.SubResource{
ID: to.StringPtr(backendPoolID),
})
primaryIPConfig.LoadBalancerBackendAddressPools = &loadBalancerBackendAddressPools
newVMSS := compute.VirtualMachineScaleSet{
Location: vmss.Location,
VirtualMachineScaleSetProperties: &compute.VirtualMachineScaleSetProperties{
VirtualMachineProfile: &compute.VirtualMachineScaleSetVMProfile{
NetworkProfile: &compute.VirtualMachineScaleSetNetworkProfile{
NetworkInterfaceConfigurations: &vmssNIC,
},
},
},
}
klog.V(2).Infof("ensureVMSSInPool begins to update vmss(%s) with new backendPoolID %s", vmssName, backendPoolID)
rerr := ss.CreateOrUpdateVMSS(ss.ResourceGroup, vmssName, newVMSS)
if rerr != nil {
klog.Errorf("ensureVMSSInPool CreateOrUpdateVMSS(%s) with new backendPoolID %s, err: %v", vmssName, backendPoolID, err)
return rerr.Error()
}
}
return nil
}