Skip to content

Commit

Permalink
[DualStack] Support NSG and clean LBs
Browse files Browse the repository at this point in the history
* Support NSG and clean LBs for dualstack
* Support related UTs for dualstack
* Refactor

Signed-off-by: Zhecheng Li <zhechengli@microsoft.com>
  • Loading branch information
lzhecheng committed Jun 19, 2023
1 parent 5631b4a commit 813fd2f
Show file tree
Hide file tree
Showing 17 changed files with 1,362 additions and 1,275 deletions.
6 changes: 6 additions & 0 deletions pkg/consts/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ const (
BackoffJitterDefault = 1.0
)

// IP family variables
const (
IPVersionIPv6 bool = true
IPVersionIPv4 bool = false
)

// LB variables for dual-stack
var (
// Service.Spec.LoadBalancerIP has been deprecated and may be removed in a future release. Those two annotations are introduced as alternatives to set IPv4/IPv6 LoadBalancer IPs.
Expand Down
5 changes: 0 additions & 5 deletions pkg/consts/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"strings"

v1 "k8s.io/api/core/v1"
"k8s.io/utils/net"
)

// IsK8sServiceHasHAModeEnabled return if HA Mode is enabled in kubernetes service annotations
Expand All @@ -36,10 +35,6 @@ func IsK8sServiceUsingInternalLoadBalancer(service *v1.Service) bool {
return expectAttributeInSvcAnnotationBeEqualTo(service.Annotations, ServiceAnnotationLoadBalancerInternal, TrueAnnotationValue)
}

func IsK8sServiceInternalIPv6(service *v1.Service) bool {
return IsK8sServiceUsingInternalLoadBalancer(service) && net.IsIPv6String(service.Spec.ClusterIP)
}

// IsK8sServiceDisableLoadBalancerFloatingIP return if floating IP in load balancer is disabled in kubernetes service annotations
func IsK8sServiceDisableLoadBalancerFloatingIP(service *v1.Service) bool {
return expectAttributeInSvcAnnotationBeEqualTo(service.Annotations, ServiceAnnotationDisableLoadBalancerFloatingIP, TrueAnnotationValue)
Expand Down
439 changes: 246 additions & 193 deletions pkg/provider/azure_loadbalancer.go

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions pkg/provider/azure_loadbalancer_backendpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"k8s.io/utils/pointer"

"sigs.k8s.io/cloud-provider-azure/pkg/cache"
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
)

Expand Down Expand Up @@ -70,11 +71,11 @@ func (bc *backendPoolTypeNodeIPConfig) EnsureHostsInPool(service *v1.Service, no
}

func isLBBackendPoolsExisting(lbBackendPoolNames map[bool]string, bpName *string) (found, isIPv6 bool) {
if strings.EqualFold(pointer.StringDeref(bpName, ""), lbBackendPoolNames[IsIPv4]) {
if strings.EqualFold(pointer.StringDeref(bpName, ""), lbBackendPoolNames[consts.IPVersionIPv4]) {
isIPv6 = false
found = true
}
if strings.EqualFold(pointer.StringDeref(bpName, ""), lbBackendPoolNames[IsIPv6]) {
if strings.EqualFold(pointer.StringDeref(bpName, ""), lbBackendPoolNames[consts.IPVersionIPv6]) {
isIPv6 = true
found = true
}
Expand Down Expand Up @@ -135,10 +136,10 @@ func (bc *backendPoolTypeNodeIPConfig) CleanupVMSetFromBackendPoolByCondition(sl
})
}
if v4Enabled {
findBackendpoolToBeDeleted(IsIPv4)
findBackendpoolToBeDeleted(consts.IPVersionIPv4)
}
if v6Enabled {
findBackendpoolToBeDeleted(IsIPv6)
findBackendpoolToBeDeleted(consts.IPVersionIPv6)
}
// decouple the backendPool from the node
shouldRefreshLB, err := bc.VMSet.EnsureBackendPoolDeleted(service, lbBackendPoolIDsSlice, vmSetName, &backendpoolToBeDeleted, true)
Expand Down Expand Up @@ -723,6 +724,7 @@ func newBackendPool(lb *network.LoadBalancer, isBackendPoolPreConfigured bool, p
BackendAddressPoolPropertiesFormat: &network.BackendAddressPoolPropertiesFormat{},
})

// Always returns false
return isBackendPoolPreConfigured
}

Expand Down
486 changes: 290 additions & 196 deletions pkg/provider/azure_loadbalancer_test.go

Large diffs are not rendered by default.

15 changes: 9 additions & 6 deletions pkg/provider/azure_privatelinkservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,27 @@ func (az *Cloud) reconcilePrivateLinkService(
isinternal := requiresInternalLoadBalancer(service)
pipRG := az.getPublicIPAddressResourceGroup(service)
_, _, fipIPVersion := az.serviceOwnsFrontendIP(*fipConfig, service)
serviceName := getServiceName(service)
var isIPv6 bool
var err error
if fipIPVersion != "" {
isIPv6 = fipIPVersion == network.IPv6
} else {
if isIPv6, err = az.isFIPIPv6(service, pipRG, fipConfig); err != nil {
klog.Errorf("reconcilePrivateLinkService for service(%s): failed to get FIP IP family: %v", service, err)
klog.Errorf("reconcilePrivateLinkService for service(%s): failed to get FIP IP family: %v", serviceName, err)
return err
}
}

createPLS := wantPLS && serviceRequiresPLS(service)
isDualStack := isServiceDualStack(service)
if isIPv6 {
klog.V(2).Infof("IPv6 is not supported for private link service, skip reconcilePrivateLinkService for service(%s)", service)
return nil
if isDualStack || !createPLS {
klog.V(2).Infof("IPv6 is not supported for private link service, skip reconcilePrivateLinkService for service(%s)", serviceName)
return nil
}
return fmt.Errorf("IPv6 is not supported for private link service")
}

createPLS := wantPLS && serviceRequiresPLS(service)
serviceName := getServiceName(service)
fipConfigID := fipConfig.ID
klog.V(2).Infof("reconcilePrivateLinkService for service(%s) - LB fipConfigID(%s) - wantPLS(%t) - createPLS(%t)", serviceName, pointer.StringDeref(fipConfig.Name, ""), wantPLS, createPLS)

Expand Down
24 changes: 13 additions & 11 deletions pkg/provider/azure_standard.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ func (az *Cloud) getBackendPoolIDWithRG(lbName, rgName, backendPoolName string)

func (az *Cloud) getBackendPoolIDs(clusterName, lbName string) map[bool]string {
return map[bool]string{
IsIPv4: az.getBackendPoolID(lbName, getBackendPoolName(clusterName, false)),
IsIPv6: az.getBackendPoolID(lbName, getBackendPoolName(clusterName, true)),
consts.IPVersionIPv4: az.getBackendPoolID(lbName, getBackendPoolName(clusterName, consts.IPVersionIPv4)),
consts.IPVersionIPv6: az.getBackendPoolID(lbName, getBackendPoolName(clusterName, consts.IPVersionIPv6)),
}
}

Expand Down Expand Up @@ -282,8 +282,8 @@ func getBackendPoolName(clusterName string, isIPv6 bool) string {
// getBackendPoolNames returns the IPv4 and IPv6 backend pool names.
func getBackendPoolNames(clusterName string) map[bool]string {
return map[bool]string{
IsIPv4: getBackendPoolName(clusterName, IsIPv4),
IsIPv6: getBackendPoolName(clusterName, IsIPv6),
consts.IPVersionIPv4: getBackendPoolName(clusterName, consts.IPVersionIPv4),
consts.IPVersionIPv6: getBackendPoolName(clusterName, consts.IPVersionIPv6),
}
}

Expand Down Expand Up @@ -320,15 +320,17 @@ func (az *Cloud) getloadbalancerHAmodeRuleName(service *v1.Service, isIPv6 bool)
}

func (az *Cloud) getSecurityRuleName(service *v1.Service, port v1.ServicePort, sourceAddrPrefix string, isIPv6 bool) string {
isDualStack := isServiceDualStack(service)
safePrefix := strings.Replace(sourceAddrPrefix, "/", "_", -1)
safePrefix = strings.Replace(safePrefix, ":", ".", -1) // Consider IPv6 address
var name string
if useSharedSecurityRule(service) {
return fmt.Sprintf("shared-%s-%d-%s", port.Protocol, port.Port, safePrefix)
name = fmt.Sprintf("shared-%s-%d-%s", port.Protocol, port.Port, safePrefix)
} else {
rulePrefix := az.getRulePrefix(service)
name = fmt.Sprintf("%s-%s-%d-%s", rulePrefix, port.Protocol, port.Port, safePrefix)
}
rulePrefix := az.getRulePrefix(service)
name := fmt.Sprintf("%s-%s-%d-%s", rulePrefix, port.Protocol, port.Port, safePrefix)
// TODO: Use getResourceByIPFamily
return name
return getResourceByIPFamily(name, isDualStack, isIPv6)
}

// This returns a human-readable version of the Service used to tag some resources.
Expand Down Expand Up @@ -432,8 +434,8 @@ func (az *Cloud) getFrontendIPConfigNames(service *v1.Service) map[bool]string {
isDualStack := isServiceDualStack(service)
defaultLBFrontendIPConfigName := az.getDefaultFrontendIPConfigName(service)
return map[bool]string{
IsIPv4: getResourceByIPFamily(defaultLBFrontendIPConfigName, isDualStack, IsIPv4),
IsIPv6: getResourceByIPFamily(defaultLBFrontendIPConfigName, isDualStack, IsIPv6),
consts.IPVersionIPv4: getResourceByIPFamily(defaultLBFrontendIPConfigName, isDualStack, consts.IPVersionIPv4),
consts.IPVersionIPv6: getResourceByIPFamily(defaultLBFrontendIPConfigName, isDualStack, consts.IPVersionIPv6),
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/provider/azure_standard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ func TestGetBackendPoolNames(t *testing.T) {
name: "GetBackendPoolNames should return 2 backend pool names",
service: getTestService("test1", v1.ProtocolTCP, nil, true, 80),
clusterName: "azure",
expectedPoolNames: map[bool]string{IsIPv4: "azure", IsIPv6: "azure-IPv6"},
expectedPoolNames: map[bool]string{consts.IPVersionIPv4: "azure", consts.IPVersionIPv6: "azure-IPv6"},
},
}
for _, test := range testcases {
Expand Down

0 comments on commit 813fd2f

Please sign in to comment.