mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
fix load balancer IP change when updating service
This commit is contained in:
parent
59fdc02b13
commit
006310b78e
@ -117,14 +117,6 @@ func (az *Cloud) EnsureLoadBalancer(ctx context.Context, clusterName string, ser
|
||||
// Here we'll firstly ensure service do not lie in the opposite LB.
|
||||
serviceName := getServiceName(service)
|
||||
glog.V(5).Infof("ensureloadbalancer(%s): START clusterName=%q", serviceName, clusterName)
|
||||
flippedService := flipServiceInternalAnnotation(service)
|
||||
if _, err := az.reconcileLoadBalancer(clusterName, flippedService, nil, false /* wantLb */); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := az.reconcilePublicIP(clusterName, service, true /* wantLb */); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lb, err := az.reconcileLoadBalancer(clusterName, service, nodes, true /* wantLb */)
|
||||
if err != nil {
|
||||
@ -145,6 +137,16 @@ func (az *Cloud) EnsureLoadBalancer(ctx context.Context, clusterName string, ser
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updateService := updateServiceLoadBalancerIP(service, to.String(serviceIP))
|
||||
flippedService := flipServiceInternalAnnotation(updateService)
|
||||
if _, err := az.reconcileLoadBalancer(clusterName, flippedService, nil, false /* wantLb */); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := az.reconcilePublicIP(clusterName, updateService, true /* wantLb */); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return lbStatus, nil
|
||||
}
|
||||
|
||||
@ -223,7 +225,7 @@ func (az *Cloud) getServiceLoadBalancer(service *v1.Service, clusterName string,
|
||||
return nil, nil, false, err
|
||||
}
|
||||
if status == nil {
|
||||
// service is not om this load balancer
|
||||
// service is not on this load balancer
|
||||
continue
|
||||
}
|
||||
|
||||
@ -409,6 +411,14 @@ func flipServiceInternalAnnotation(service *v1.Service) *v1.Service {
|
||||
return copyService
|
||||
}
|
||||
|
||||
func updateServiceLoadBalancerIP(service *v1.Service, serviceIP string) *v1.Service {
|
||||
copyService := service.DeepCopy()
|
||||
if len(serviceIP) > 0 && copyService != nil {
|
||||
copyService.Spec.LoadBalancerIP = serviceIP
|
||||
}
|
||||
return copyService
|
||||
}
|
||||
|
||||
func (az *Cloud) findServiceIPAddress(ctx context.Context, clusterName string, service *v1.Service, isInternalLb bool) (string, error) {
|
||||
if len(service.Spec.LoadBalancerIP) > 0 {
|
||||
return service.Spec.LoadBalancerIP, nil
|
||||
@ -502,6 +512,53 @@ func getIdleTimeout(s *v1.Service) (*int32, error) {
|
||||
return &to32, nil
|
||||
}
|
||||
|
||||
func (az *Cloud) isFrontendIPChanged(clusterName string, config network.FrontendIPConfiguration, service *v1.Service, lbFrontendIPConfigName string) (bool, error) {
|
||||
if az.serviceOwnsFrontendIP(config, service) && !strings.EqualFold(to.String(config.Name), lbFrontendIPConfigName) {
|
||||
return true, nil
|
||||
}
|
||||
if !strings.EqualFold(to.String(config.Name), lbFrontendIPConfigName) {
|
||||
return false, nil
|
||||
}
|
||||
loadBalancerIP := service.Spec.LoadBalancerIP
|
||||
isInternal := requiresInternalLoadBalancer(service)
|
||||
if isInternal {
|
||||
// Judge subnet
|
||||
subnetName := subnet(service)
|
||||
if subnetName != nil {
|
||||
subnet, existsSubnet, err := az.getSubnet(az.VnetName, *subnetName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !existsSubnet {
|
||||
return false, fmt.Errorf("failed to get subnet")
|
||||
}
|
||||
if config.Subnet != nil && !strings.EqualFold(to.String(config.Subnet.Name), to.String(subnet.Name)) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
if loadBalancerIP == "" {
|
||||
return config.PrivateIPAllocationMethod == network.Static, nil
|
||||
}
|
||||
return config.PrivateIPAllocationMethod != network.Static || !strings.EqualFold(loadBalancerIP, to.String(config.PrivateIPAddress)), nil
|
||||
}
|
||||
if loadBalancerIP == "" {
|
||||
return false, nil
|
||||
}
|
||||
pipName, err := az.determinePublicIPName(clusterName, service)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
pipResourceGroup := az.getPublicIPAddressResourceGroup(service)
|
||||
pip, existsPip, err := az.getPublicIPAddress(pipResourceGroup, pipName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !existsPip {
|
||||
return true, nil
|
||||
}
|
||||
return config.PublicIPAddress != nil && !strings.EqualFold(to.String(pip.ID), to.String(config.PublicIPAddress.ID)), nil
|
||||
}
|
||||
|
||||
// This ensures load balancer exists and the frontend ip config is setup.
|
||||
// This also reconciles the Service's Ports with the LoadBalancer config.
|
||||
// This entails adding rules/probes for expected Ports and removing stale rules/ports.
|
||||
@ -574,16 +631,18 @@ func (az *Cloud) reconcileLoadBalancer(clusterName string, service *v1.Service,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if isInternal {
|
||||
for i := len(newConfigs) - 1; i >= 0; i-- {
|
||||
config := newConfigs[i]
|
||||
if az.serviceOwnsFrontendIP(config, service) && !strings.EqualFold(*config.Name, lbFrontendIPConfigName) {
|
||||
isFipChanged, err := az.isFrontendIPChanged(clusterName, config, service, lbFrontendIPConfigName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if isFipChanged {
|
||||
glog.V(2).Infof("reconcileLoadBalancer for service (%s)(%t): lb frontendconfig(%s) - dropping", serviceName, wantLb, *config.Name)
|
||||
newConfigs = append(newConfigs[:i], newConfigs[i+1:]...)
|
||||
dirtyConfigs = true
|
||||
}
|
||||
}
|
||||
}
|
||||
foundConfig := false
|
||||
for _, config := range newConfigs {
|
||||
if strings.EqualFold(*config.Name, lbFrontendIPConfigName) {
|
||||
|
Loading…
Reference in New Issue
Block a user