func()

in azure/azure_loadbalancer.go [1614:1747]


func (az *Cloud) reconcileLoadBalancerRule(
	service *v1.Service,
	wantLb bool,
	lbFrontendIPConfigID string,
	lbBackendPoolID string,
	lbName string,
	lbIdleTimeout *int32) ([]network.Probe, []network.LoadBalancingRule, error) {

	var ports []v1.ServicePort
	if wantLb {
		ports = service.Spec.Ports
	} else {
		ports = []v1.ServicePort{}
	}

	var enableTCPReset *bool
	if az.useStandardLoadBalancer() {
		enableTCPReset = to.BoolPtr(true)
	}

	var expectedProbes []network.Probe
	var expectedRules []network.LoadBalancingRule
	highAvailabilityPortsEnabled := false
	for _, port := range ports {
		if highAvailabilityPortsEnabled {
			// Since the port is always 0 when enabling HA, only one rule should be configured.
			break
		}

		lbRuleName := az.getLoadBalancerRuleName(service, port.Protocol, port.Port)
		klog.V(2).Infof("reconcileLoadBalancerRule lb name (%s) rule name (%s)", lbName, lbRuleName)

		transportProto, _, probeProto, err := getProtocolsFromKubernetesProtocol(port.Protocol)
		if err != nil {
			return expectedProbes, expectedRules, err
		}

		probeProtocol, requestPath := parseHealthProbeProtocolAndPath(service)
		if servicehelpers.NeedsHealthCheck(service) {
			podPresencePath, podPresencePort := servicehelpers.GetServiceHealthCheckPathPort(service)
			if probeProtocol == "" {
				probeProtocol = string(network.ProbeProtocolHTTP)
			}

			needRequestPath := strings.EqualFold(probeProtocol, string(network.ProbeProtocolHTTP)) || strings.EqualFold(probeProtocol, string(network.ProbeProtocolHTTPS))
			if requestPath == "" && needRequestPath {
				requestPath = podPresencePath
			}

			expectedProbes = append(expectedProbes, network.Probe{
				Name: &lbRuleName,
				ProbePropertiesFormat: &network.ProbePropertiesFormat{
					RequestPath:       to.StringPtr(requestPath),
					Protocol:          network.ProbeProtocol(probeProtocol),
					Port:              to.Int32Ptr(podPresencePort),
					IntervalInSeconds: to.Int32Ptr(5),
					NumberOfProbes:    to.Int32Ptr(2),
				},
			})
		} else if port.Protocol != v1.ProtocolUDP && port.Protocol != v1.ProtocolSCTP {
			// we only add the expected probe if we're doing TCP
			if probeProtocol == "" {
				probeProtocol = string(*probeProto)
			}
			var actualPath *string
			if !strings.EqualFold(probeProtocol, string(network.ProbeProtocolTCP)) {
				if requestPath != "" {
					actualPath = to.StringPtr(requestPath)
				} else {
					actualPath = to.StringPtr("/healthz")
				}
			}
			expectedProbes = append(expectedProbes, network.Probe{
				Name: &lbRuleName,
				ProbePropertiesFormat: &network.ProbePropertiesFormat{
					Protocol:          network.ProbeProtocol(probeProtocol),
					RequestPath:       actualPath,
					Port:              to.Int32Ptr(port.NodePort),
					IntervalInSeconds: to.Int32Ptr(5),
					NumberOfProbes:    to.Int32Ptr(2),
				},
			})
		}

		loadDistribution := network.LoadDistributionDefault
		if service.Spec.SessionAffinity == v1.ServiceAffinityClientIP {
			loadDistribution = network.LoadDistributionSourceIP
		}

		expectedRule := network.LoadBalancingRule{
			Name: &lbRuleName,
			LoadBalancingRulePropertiesFormat: &network.LoadBalancingRulePropertiesFormat{
				Protocol: *transportProto,
				FrontendIPConfiguration: &network.SubResource{
					ID: to.StringPtr(lbFrontendIPConfigID),
				},
				BackendAddressPool: &network.SubResource{
					ID: to.StringPtr(lbBackendPoolID),
				},
				LoadDistribution:    loadDistribution,
				FrontendPort:        to.Int32Ptr(port.Port),
				BackendPort:         to.Int32Ptr(port.Port),
				DisableOutboundSnat: to.BoolPtr(az.disableLoadBalancerOutboundSNAT()),
				EnableTCPReset:      enableTCPReset,
				EnableFloatingIP:    to.BoolPtr(true),
			},
		}

		if port.Protocol == v1.ProtocolTCP {
			expectedRule.LoadBalancingRulePropertiesFormat.IdleTimeoutInMinutes = lbIdleTimeout
		}

		if requiresInternalLoadBalancer(service) &&
			strings.EqualFold(az.LoadBalancerSku, loadBalancerSkuStandard) &&
			strings.EqualFold(service.Annotations[ServiceAnnotationLoadBalancerEnableHighAvailabilityPorts], "true") {
			expectedRule.FrontendPort = to.Int32Ptr(0)
			expectedRule.BackendPort = to.Int32Ptr(0)
			expectedRule.Protocol = network.TransportProtocolAll
			highAvailabilityPortsEnabled = true
		}

		// we didn't construct the probe objects for UDP or SCTP because they're not allowed on Azure.
		// However, when externalTrafficPolicy is Local, Kubernetes HTTP health check would be used for probing.
		if servicehelpers.NeedsHealthCheck(service) || (port.Protocol != v1.ProtocolUDP && port.Protocol != v1.ProtocolSCTP) {
			expectedRule.Probe = &network.SubResource{
				ID: to.StringPtr(az.getLoadBalancerProbeID(lbName, az.getLoadBalancerResourceGroup(), lbRuleName)),
			}
		}

		expectedRules = append(expectedRules, expectedRule)
	}

	return expectedProbes, expectedRules, nil
}