mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 06:27:05 +00:00
Add load balancer cross resource group settings to config.
This commit is contained in:
parent
fcd0c6706f
commit
659e857a1d
@ -163,6 +163,13 @@ type Config struct {
|
|||||||
|
|
||||||
// The cloud configure type for Azure cloud provider. Supported values are file, secret and merge.
|
// The cloud configure type for Azure cloud provider. Supported values are file, secret and merge.
|
||||||
CloudConfigType cloudConfigType `json:"cloudConfigType,omitempty" yaml:"cloudConfigType,omitempty"`
|
CloudConfigType cloudConfigType `json:"cloudConfigType,omitempty" yaml:"cloudConfigType,omitempty"`
|
||||||
|
|
||||||
|
// LoadBalancerName determines the specific name of the load balancer user want to use, working with
|
||||||
|
// LoadBalancerResourceGroup
|
||||||
|
LoadBalancerName string `json:"loadBalancerName,omitempty" yaml:"loadBalancerName,omitempty"`
|
||||||
|
// LoadBalancerResourceGroup determines the specific resource group of the load balancer user want to use, working
|
||||||
|
// with LoadBalancerName
|
||||||
|
LoadBalancerResourceGroup string `json:"loadBalancerResourceGroup,omitempty" yaml:"loadBalancerResourceGroup,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ cloudprovider.Interface = (*Cloud)(nil)
|
var _ cloudprovider.Interface = (*Cloud)(nil)
|
||||||
|
@ -232,7 +232,7 @@ func (az *Cloud) CreateOrUpdateLB(service *v1.Service, lb network.LoadBalancer)
|
|||||||
ctx, cancel := getContextWithCancel()
|
ctx, cancel := getContextWithCancel()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
rgName := az.getLoadBalancerResourceGroup(service)
|
rgName := az.getLoadBalancerResourceGroup()
|
||||||
resp, err := az.LoadBalancerClient.CreateOrUpdate(ctx, rgName, *lb.Name, lb, to.String(lb.Etag))
|
resp, err := az.LoadBalancerClient.CreateOrUpdate(ctx, rgName, *lb.Name, lb, to.String(lb.Etag))
|
||||||
klog.V(10).Infof("LoadBalancerClient.CreateOrUpdate(%s): end", *lb.Name)
|
klog.V(10).Infof("LoadBalancerClient.CreateOrUpdate(%s): end", *lb.Name)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -260,7 +260,7 @@ func (az *Cloud) createOrUpdateLBWithRetry(service *v1.Service, lb network.LoadB
|
|||||||
ctx, cancel := getContextWithCancel()
|
ctx, cancel := getContextWithCancel()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
rgName := az.getLoadBalancerResourceGroup(service)
|
rgName := az.getLoadBalancerResourceGroup()
|
||||||
resp, err := az.LoadBalancerClient.CreateOrUpdate(ctx, rgName, *lb.Name, lb, to.String(lb.Etag))
|
resp, err := az.LoadBalancerClient.CreateOrUpdate(ctx, rgName, *lb.Name, lb, to.String(lb.Etag))
|
||||||
klog.V(10).Infof("LoadBalancerClient.CreateOrUpdate(%s): end", *lb.Name)
|
klog.V(10).Infof("LoadBalancerClient.CreateOrUpdate(%s): end", *lb.Name)
|
||||||
done, retryError := az.processHTTPRetryResponse(service, "CreateOrUpdateLoadBalancer", resp, err)
|
done, retryError := az.processHTTPRetryResponse(service, "CreateOrUpdateLoadBalancer", resp, err)
|
||||||
@ -284,11 +284,11 @@ func (az *Cloud) ListLB(service *v1.Service) ([]network.LoadBalancer, error) {
|
|||||||
ctx, cancel := getContextWithCancel()
|
ctx, cancel := getContextWithCancel()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
rgName := az.getLoadBalancerResourceGroup(service)
|
rgName := az.getLoadBalancerResourceGroup()
|
||||||
allLBs, err := az.LoadBalancerClient.List(ctx, rgName)
|
allLBs, err := az.LoadBalancerClient.List(ctx, rgName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
az.Event(service, v1.EventTypeWarning, "ListLoadBalancers", err.Error())
|
az.Event(service, v1.EventTypeWarning, "ListLoadBalancers", err.Error())
|
||||||
klog.Errorf("LoadBalancerClient.List(%v) failure with err=%v", az.ResourceGroup, err)
|
klog.Errorf("LoadBalancerClient.List(%v) failure with err=%v", rgName, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
klog.V(2).Infof("LoadBalancerClient.List(%v) success", az.ResourceGroup)
|
klog.V(2).Infof("LoadBalancerClient.List(%v) success", az.ResourceGroup)
|
||||||
@ -307,12 +307,12 @@ func (az *Cloud) listLBWithRetry(service *v1.Service) ([]network.LoadBalancer, e
|
|||||||
ctx, cancel := getContextWithCancel()
|
ctx, cancel := getContextWithCancel()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
rgName := az.getLoadBalancerResourceGroup(service)
|
rgName := az.getLoadBalancerResourceGroup()
|
||||||
allLBs, retryErr = az.LoadBalancerClient.List(ctx, rgName)
|
allLBs, retryErr = az.LoadBalancerClient.List(ctx, rgName)
|
||||||
if retryErr != nil {
|
if retryErr != nil {
|
||||||
az.Event(service, v1.EventTypeWarning, "ListLoadBalancers", retryErr.Error())
|
az.Event(service, v1.EventTypeWarning, "ListLoadBalancers", retryErr.Error())
|
||||||
klog.Errorf("LoadBalancerClient.List(%v) - backoff: failure, will retry,err=%v",
|
klog.Errorf("LoadBalancerClient.List(%v) - backoff: failure, will retry,err=%v",
|
||||||
az.ResourceGroup,
|
rgName,
|
||||||
retryErr)
|
retryErr)
|
||||||
return false, retryErr
|
return false, retryErr
|
||||||
}
|
}
|
||||||
@ -454,7 +454,8 @@ func (az *Cloud) DeleteLB(service *v1.Service, lbName string) error {
|
|||||||
ctx, cancel := getContextWithCancel()
|
ctx, cancel := getContextWithCancel()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
resp, err := az.LoadBalancerClient.Delete(ctx, az.ResourceGroup, lbName)
|
rgName := az.getLoadBalancerResourceGroup()
|
||||||
|
resp, err := az.LoadBalancerClient.Delete(ctx, rgName, lbName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if isSuccessHTTPResponse(resp) {
|
if isSuccessHTTPResponse(resp) {
|
||||||
// Invalidate the cache right after updating
|
// Invalidate the cache right after updating
|
||||||
@ -475,7 +476,8 @@ func (az *Cloud) deleteLBWithRetry(service *v1.Service, lbName string) error {
|
|||||||
ctx, cancel := getContextWithCancel()
|
ctx, cancel := getContextWithCancel()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
resp, err := az.LoadBalancerClient.Delete(ctx, az.ResourceGroup, lbName)
|
rgName := az.getLoadBalancerResourceGroup()
|
||||||
|
resp, err := az.LoadBalancerClient.Delete(ctx, rgName, lbName)
|
||||||
done, err := az.processHTTPRetryResponse(service, "DeleteLoadBalancer", resp, err)
|
done, err := az.processHTTPRetryResponse(service, "DeleteLoadBalancer", resp, err)
|
||||||
if done && err == nil {
|
if done && err == nil {
|
||||||
// Invalidate the cache right after deleting
|
// Invalidate the cache right after deleting
|
||||||
|
@ -93,8 +93,6 @@ const (
|
|||||||
serviceTagKey = "service"
|
serviceTagKey = "service"
|
||||||
// clusterNameKey is the cluster name key applied for public IP tags.
|
// clusterNameKey is the cluster name key applied for public IP tags.
|
||||||
clusterNameKey = "kubernetes-cluster-name"
|
clusterNameKey = "kubernetes-cluster-name"
|
||||||
// LoadBalancerName
|
|
||||||
LoadBalancerName = "load-balancer-name"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetLoadBalancer returns whether the specified load balancer exists, and
|
// GetLoadBalancer returns whether the specified load balancer exists, and
|
||||||
@ -221,42 +219,17 @@ func (az *Cloud) EnsureLoadBalancerDeleted(ctx context.Context, clusterName stri
|
|||||||
|
|
||||||
// GetLoadBalancerName returns the LoadBalancer name.
|
// GetLoadBalancerName returns the LoadBalancer name.
|
||||||
func (az *Cloud) GetLoadBalancerName(ctx context.Context, clusterName string, service *v1.Service) string {
|
func (az *Cloud) GetLoadBalancerName(ctx context.Context, clusterName string, service *v1.Service) string {
|
||||||
if lbName, found := service.Annotations[LoadBalancerName]; found && strings.TrimSpace(lbName) != "" {
|
|
||||||
return lbName
|
|
||||||
}
|
|
||||||
return cloudprovider.DefaultLoadBalancerName(service)
|
return cloudprovider.DefaultLoadBalancerName(service)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (az *Cloud) getLoadBalancerResourceGroup(service *v1.Service) string {
|
func (az *Cloud) getLoadBalancerResourceGroup() string {
|
||||||
if rgName, found := service.Annotations[ServiceAnnotationLoadBalancerResourceGroup]; found && strings.TrimSpace(rgName) != "" {
|
if az.LoadBalancerResourceGroup != "" {
|
||||||
return rgName
|
return az.LoadBalancerResourceGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
return az.ResourceGroup
|
return az.ResourceGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
// getLoadBalancerByName get the specific lb with given load balancer name and resource group.
|
|
||||||
// It works with annotation "service.beta.kubernetes.io/azure-load-balancer-resource-group"
|
|
||||||
func (az *Cloud) getLoadBalancerByName(service *v1.Service, lbName string) (lb *network.LoadBalancer, status *v1.LoadBalancerStatus, exists bool, err error) {
|
|
||||||
existingLBs, err := az.ListLB(service)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, false, err
|
|
||||||
}
|
|
||||||
if existingLBs == nil {
|
|
||||||
return nil, nil, false, fmt.Errorf("cannot obtain the load balancer %q", lbName)
|
|
||||||
}
|
|
||||||
for _, existingLB := range existingLBs {
|
|
||||||
if strings.EqualFold(*existingLB.Name, lbName) {
|
|
||||||
status, err = az.getServiceLoadBalancerStatus(service, &existingLB)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, false, err
|
|
||||||
}
|
|
||||||
return &existingLB, status, true, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil, false, fmt.Errorf("cannot obtain the load balancer %q", lbName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// getServiceLoadBalancer gets the loadbalancer for the service if it already exists.
|
// getServiceLoadBalancer gets the loadbalancer for the service if it already exists.
|
||||||
// If wantLb is TRUE then -it selects a new load balancer.
|
// If wantLb is TRUE then -it selects a new load balancer.
|
||||||
// In case the selected load balancer does not exist it returns network.LoadBalancer struct
|
// In case the selected load balancer does not exist it returns network.LoadBalancer struct
|
||||||
@ -629,32 +602,14 @@ func (az *Cloud) isFrontendIPChanged(clusterName string, config network.Frontend
|
|||||||
// This entails adding rules/probes for expected Ports and removing stale rules/ports.
|
// This entails adding rules/probes for expected Ports and removing stale rules/ports.
|
||||||
// nodes only used if wantLb is true
|
// nodes only used if wantLb is true
|
||||||
func (az *Cloud) reconcileLoadBalancer(clusterName string, service *v1.Service, nodes []*v1.Node, wantLb bool) (*network.LoadBalancer, error) {
|
func (az *Cloud) reconcileLoadBalancer(clusterName string, service *v1.Service, nodes []*v1.Node, wantLb bool) (*network.LoadBalancer, error) {
|
||||||
var (
|
|
||||||
lb *network.LoadBalancer
|
|
||||||
exists bool
|
|
||||||
err error
|
|
||||||
rgName string
|
|
||||||
)
|
|
||||||
|
|
||||||
isInternal := requiresInternalLoadBalancer(service)
|
isInternal := requiresInternalLoadBalancer(service)
|
||||||
serviceName := getServiceName(service)
|
serviceName := getServiceName(service)
|
||||||
klog.V(2).Infof("reconcileLoadBalancer for service(%s) - wantLb(%t): started", serviceName, wantLb)
|
klog.V(2).Infof("reconcileLoadBalancer for service(%s) - wantLb(%t): started", serviceName, wantLb)
|
||||||
|
lb, _, _, err := az.getServiceLoadBalancer(service, clusterName, nodes, wantLb)
|
||||||
if rgName = az.getLoadBalancerResourceGroup(service); rgName != az.ResourceGroup {
|
if err != nil {
|
||||||
lbName := az.GetLoadBalancerName(context.Background(), clusterName, service)
|
klog.Errorf("reconcileLoadBalancer: failed to get load balancer for service %q, error: %v", serviceName, err)
|
||||||
lb, _, exists, err = az.getLoadBalancerByName(service, lbName)
|
return nil, err
|
||||||
if err != nil {
|
|
||||||
klog.Errorf("reconcileLoadBalancer: failed to get load balancer for service %q in resource group %q, error: %v, will continue in the default resource group", serviceName, rgName, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if !exists || strings.TrimSpace(rgName) == "" || strings.TrimSpace(rgName) == az.ResourceGroup {
|
|
||||||
lb, _, _, err = az.getServiceLoadBalancer(service, clusterName, nodes, wantLb)
|
|
||||||
if err != nil {
|
|
||||||
klog.Errorf("reconcileLoadBalancer: failed to get load balancer for service %q, error: %v", serviceName, err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lbName := *lb.Name
|
lbName := *lb.Name
|
||||||
klog.V(2).Infof("reconcileLoadBalancer for service(%s): lb(%s) wantLb(%t) resolved load balancer name", serviceName, lbName, wantLb)
|
klog.V(2).Infof("reconcileLoadBalancer for service(%s): lb(%s) wantLb(%t) resolved load balancer name", serviceName, lbName, wantLb)
|
||||||
lbFrontendIPConfigName := az.getFrontendIPConfigName(service, subnet(service))
|
lbFrontendIPConfigName := az.getFrontendIPConfigName(service, subnet(service))
|
||||||
|
@ -676,83 +676,6 @@ func TestGetServiceLoadBalancer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetLoadBalancerByName(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
desc string
|
|
||||||
existingLBs []network.LoadBalancer
|
|
||||||
expectedLB *network.LoadBalancer
|
|
||||||
expectedStatus *v1.LoadBalancerStatus
|
|
||||||
expectedExists bool
|
|
||||||
expectedError bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
desc: "getLoadBalancerByName shall return the corresponding load balancer in the resource group different from the cluster's",
|
|
||||||
existingLBs: []network.LoadBalancer{
|
|
||||||
{
|
|
||||||
Name: to.StringPtr("me"),
|
|
||||||
LoadBalancerPropertiesFormat: &network.LoadBalancerPropertiesFormat{
|
|
||||||
FrontendIPConfigurations: &[]network.FrontendIPConfiguration{
|
|
||||||
{
|
|
||||||
Name: to.StringPtr("atest1"),
|
|
||||||
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
|
|
||||||
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: to.StringPtr("notMe"),
|
|
||||||
LoadBalancerPropertiesFormat: &network.LoadBalancerPropertiesFormat{
|
|
||||||
FrontendIPConfigurations: &[]network.FrontendIPConfiguration{
|
|
||||||
{
|
|
||||||
Name: to.StringPtr("atest1"),
|
|
||||||
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
|
|
||||||
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedLB: &network.LoadBalancer{
|
|
||||||
Name: to.StringPtr("me"),
|
|
||||||
LoadBalancerPropertiesFormat: &network.LoadBalancerPropertiesFormat{
|
|
||||||
FrontendIPConfigurations: &[]network.FrontendIPConfiguration{
|
|
||||||
{
|
|
||||||
Name: to.StringPtr("atest1"),
|
|
||||||
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
|
|
||||||
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedStatus: &v1.LoadBalancerStatus{Ingress: []v1.LoadBalancerIngress{{IP: "", Hostname: ""}}},
|
|
||||||
expectedExists: true,
|
|
||||||
expectedError: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, test := range testCases {
|
|
||||||
az := getTestCloud()
|
|
||||||
service := getTestService("test1", v1.ProtocolTCP, nil, 80)
|
|
||||||
service.Annotations[ServiceAnnotationLoadBalancerResourceGroup] = "rg1"
|
|
||||||
for _, existingLB := range test.existingLBs {
|
|
||||||
_, err := az.LoadBalancerClient.CreateOrUpdate(context.TODO(), "rg1", *existingLB.Name, existingLB, "")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("TestCase[%d] meets unexpected error: %v", i, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lb, status, exists, err := az.getLoadBalancerByName(&service, "me")
|
|
||||||
assert.Equal(t, test.expectedLB, lb, "TestCase[%d]: %s", i, test.desc)
|
|
||||||
assert.Equal(t, test.expectedStatus, status, "TestCase[%d]: %s", i, test.desc)
|
|
||||||
assert.Equal(t, test.expectedExists, exists, "TestCase[%d]: %s", i, test.desc)
|
|
||||||
assert.Equal(t, test.expectedError, err != nil, "TestCase[%d]: %s", i, test.desc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsFrontendIPChanged(t *testing.T) {
|
func TestIsFrontendIPChanged(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
|
@ -127,6 +127,9 @@ func (az *Cloud) mapLoadBalancerNameToVMSet(lbName string, clusterName string) (
|
|||||||
// So we'd have a separate name for internal load balancer.
|
// So we'd have a separate name for internal load balancer.
|
||||||
// This would be the name for Azure LoadBalancer resource.
|
// This would be the name for Azure LoadBalancer resource.
|
||||||
func (az *Cloud) getAzureLoadBalancerName(clusterName string, vmSetName string, isInternal bool) string {
|
func (az *Cloud) getAzureLoadBalancerName(clusterName string, vmSetName string, isInternal bool) string {
|
||||||
|
if az.LoadBalancerName != "" {
|
||||||
|
clusterName = az.LoadBalancerName
|
||||||
|
}
|
||||||
lbNamePrefix := vmSetName
|
lbNamePrefix := vmSetName
|
||||||
if strings.EqualFold(vmSetName, az.vmSet.GetPrimaryVMSetName()) || az.useStandardLoadBalancer() {
|
if strings.EqualFold(vmSetName, az.vmSet.GetPrimaryVMSetName()) || az.useStandardLoadBalancer() {
|
||||||
lbNamePrefix = clusterName
|
lbNamePrefix = clusterName
|
||||||
|
@ -233,7 +233,7 @@ func (az *Cloud) newLBCache() (*timedCache, error) {
|
|||||||
ctx, cancel := getContextWithCancel()
|
ctx, cancel := getContextWithCancel()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
lb, err := az.LoadBalancerClient.Get(ctx, az.ResourceGroup, key, "")
|
lb, err := az.LoadBalancerClient.Get(ctx, az.getLoadBalancerResourceGroup(), key, "")
|
||||||
exists, message, realErr := checkResourceExistsFromError(err)
|
exists, message, realErr := checkResourceExistsFromError(err)
|
||||||
if realErr != nil {
|
if realErr != nil {
|
||||||
return nil, realErr
|
return nil, realErr
|
||||||
|
Loading…
Reference in New Issue
Block a user