From 1896906334a3cf7dab06690bf35fa77e1449e0b4 Mon Sep 17 00:00:00 2001 From: ChrisLiu Date: Tue, 9 Apr 2024 15:25:11 +0800 Subject: [PATCH] feat: add AlibabaCloud-NLB network plugin Signed-off-by: ChrisLiu --- Makefile | 2 +- cloudprovider/alibabacloud/nlb.go | 392 ++++++++++++++++++ cloudprovider/alibabacloud/nlb_sp.go | 8 +- cloudprovider/alibabacloud/nlb_sp_test.go | 8 +- cloudprovider/alibabacloud/nlb_test.go | 236 +++++++++++ cloudprovider/alibabacloud/slb.go | 2 +- cloudprovider/options/alibabacloud_options.go | 14 + config/manager/config.toml | 3 + 8 files changed, 655 insertions(+), 10 deletions(-) create mode 100644 cloudprovider/alibabacloud/nlb.go create mode 100644 cloudprovider/alibabacloud/nlb_test.go diff --git a/Makefile b/Makefile index 78fef824..692afe8a 100644 --- a/Makefile +++ b/Makefile @@ -130,7 +130,7 @@ $(CONTROLLER_GEN): $(LOCALBIN) .PHONY: envtest envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. $(ENVTEST): $(LOCALBIN) - GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest + GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@c7e1dc9b5302d649d5531e19168dd7ea0013736d HELM = $(shell pwd)/bin/helm helm: ## Download helm locally if necessary. diff --git a/cloudprovider/alibabacloud/nlb.go b/cloudprovider/alibabacloud/nlb.go new file mode 100644 index 00000000..c3d6db89 --- /dev/null +++ b/cloudprovider/alibabacloud/nlb.go @@ -0,0 +1,392 @@ +/* +Copyright 2024 The Kruise Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package alibabacloud + +import ( + "context" + gamekruiseiov1alpha1 "github.com/openkruise/kruise-game/apis/v1alpha1" + "github.com/openkruise/kruise-game/cloudprovider" + cperrors "github.com/openkruise/kruise-game/cloudprovider/errors" + provideroptions "github.com/openkruise/kruise-game/cloudprovider/options" + "github.com/openkruise/kruise-game/cloudprovider/utils" + "github.com/openkruise/kruise-game/pkg/util" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/intstr" + log "k8s.io/klog/v2" + "sigs.k8s.io/controller-runtime/pkg/client" + "strconv" + "strings" + "sync" +) + +const ( + NlbNetwork = "AlibabaCloud-NLB" + AliasNLB = "NLB-Network" +) + +type NlbPlugin struct { + maxPort int32 + minPort int32 + cache map[string]portAllocated + podAllocate map[string]string + mutex sync.RWMutex +} + +type nlbConfig struct { + lbIds []string + targetPorts []int + protocols []corev1.Protocol + isFixed bool +} + +func (n *NlbPlugin) Name() string { + return NlbNetwork +} + +func (n *NlbPlugin) Alias() string { + return AliasNLB +} + +func (n *NlbPlugin) Init(c client.Client, options cloudprovider.CloudProviderOptions, ctx context.Context) error { + n.mutex.Lock() + defer n.mutex.Unlock() + slbOptions := options.(provideroptions.AlibabaCloudOptions).NLBOptions + n.minPort = slbOptions.MinPort + n.maxPort = slbOptions.MaxPort + + svcList := &corev1.ServiceList{} + err := c.List(ctx, svcList) + if err != nil { + return err + } + + n.cache, n.podAllocate = initLbCache(svcList.Items, n.minPort, n.maxPort) + log.Infof("[%s] podAllocate cache complete initialization: %v", NlbNetwork, n.podAllocate) + return nil +} + +func (n *NlbPlugin) OnPodAdded(client client.Client, pod *corev1.Pod, ctx context.Context) (*corev1.Pod, cperrors.PluginError) { + return pod, nil +} + +func (n *NlbPlugin) OnPodUpdated(c client.Client, pod *corev1.Pod, ctx context.Context) (*corev1.Pod, cperrors.PluginError) { + networkManager := utils.NewNetworkManager(pod, c) + + networkStatus, _ := networkManager.GetNetworkStatus() + networkConfig := networkManager.GetNetworkConfig() + sc := parseNlbConfig(networkConfig) + if networkStatus == nil { + pod, err := networkManager.UpdateNetworkStatus(gamekruiseiov1alpha1.NetworkStatus{ + CurrentNetworkState: gamekruiseiov1alpha1.NetworkNotReady, + }, pod) + return pod, cperrors.ToPluginError(err, cperrors.InternalError) + } + + // get svc + svc := &corev1.Service{} + err := c.Get(ctx, types.NamespacedName{ + Name: pod.GetName(), + Namespace: pod.GetNamespace(), + }, svc) + if err != nil { + if errors.IsNotFound(err) { + return pod, cperrors.ToPluginError(c.Create(ctx, n.consSvc(sc, pod, c, ctx)), cperrors.ApiCallError) + } + return pod, cperrors.NewPluginError(cperrors.ApiCallError, err.Error()) + } + + // update svc + if util.GetHash(sc) != svc.GetAnnotations()[SlbConfigHashKey] { + networkStatus.CurrentNetworkState = gamekruiseiov1alpha1.NetworkNotReady + pod, err = networkManager.UpdateNetworkStatus(*networkStatus, pod) + if err != nil { + return pod, cperrors.NewPluginError(cperrors.InternalError, err.Error()) + } + return pod, cperrors.ToPluginError(c.Update(ctx, n.consSvc(sc, pod, c, ctx)), cperrors.ApiCallError) + } + + // disable network + if networkManager.GetNetworkDisabled() && svc.Spec.Type == corev1.ServiceTypeLoadBalancer { + svc.Spec.Type = corev1.ServiceTypeClusterIP + return pod, cperrors.ToPluginError(c.Update(ctx, svc), cperrors.ApiCallError) + } + + // enable network + if !networkManager.GetNetworkDisabled() && svc.Spec.Type == corev1.ServiceTypeClusterIP { + svc.Spec.Type = corev1.ServiceTypeLoadBalancer + return pod, cperrors.ToPluginError(c.Update(ctx, svc), cperrors.ApiCallError) + } + + // network not ready + if svc.Status.LoadBalancer.Ingress == nil { + networkStatus.CurrentNetworkState = gamekruiseiov1alpha1.NetworkNotReady + pod, err = networkManager.UpdateNetworkStatus(*networkStatus, pod) + return pod, cperrors.ToPluginError(err, cperrors.InternalError) + } + + // allow not ready containers + if util.IsAllowNotReadyContainers(networkManager.GetNetworkConfig()) { + toUpDateSvc, err := utils.AllowNotReadyContainers(c, ctx, pod, svc, false) + if err != nil { + return pod, err + } + + if toUpDateSvc { + err := c.Update(ctx, svc) + if err != nil { + return pod, cperrors.ToPluginError(err, cperrors.ApiCallError) + } + } + } + + // network ready + internalAddresses := make([]gamekruiseiov1alpha1.NetworkAddress, 0) + externalAddresses := make([]gamekruiseiov1alpha1.NetworkAddress, 0) + for _, port := range svc.Spec.Ports { + instrIPort := port.TargetPort + instrEPort := intstr.FromInt(int(port.Port)) + internalAddress := gamekruiseiov1alpha1.NetworkAddress{ + IP: pod.Status.PodIP, + Ports: []gamekruiseiov1alpha1.NetworkPort{ + { + Name: instrIPort.String(), + Port: &instrIPort, + Protocol: port.Protocol, + }, + }, + } + externalAddress := gamekruiseiov1alpha1.NetworkAddress{ + EndPoint: svc.Status.LoadBalancer.Ingress[0].Hostname, + IP: svc.Status.LoadBalancer.Ingress[0].IP, + Ports: []gamekruiseiov1alpha1.NetworkPort{ + { + Name: instrIPort.String(), + Port: &instrEPort, + Protocol: port.Protocol, + }, + }, + } + internalAddresses = append(internalAddresses, internalAddress) + externalAddresses = append(externalAddresses, externalAddress) + } + networkStatus.InternalAddresses = internalAddresses + networkStatus.ExternalAddresses = externalAddresses + networkStatus.CurrentNetworkState = gamekruiseiov1alpha1.NetworkReady + pod, err = networkManager.UpdateNetworkStatus(*networkStatus, pod) + return pod, cperrors.ToPluginError(err, cperrors.InternalError) +} + +func (n *NlbPlugin) OnPodDeleted(c client.Client, pod *corev1.Pod, ctx context.Context) cperrors.PluginError { + networkManager := utils.NewNetworkManager(pod, c) + networkConfig := networkManager.GetNetworkConfig() + sc := parseLbConfig(networkConfig) + + var podKeys []string + if sc.isFixed { + gss, err := util.GetGameServerSetOfPod(pod, c, ctx) + if err != nil && !errors.IsNotFound(err) { + return cperrors.ToPluginError(err, cperrors.ApiCallError) + } + // gss exists in cluster, do not deAllocate. + if err == nil && gss.GetDeletionTimestamp() == nil { + return nil + } + // gss not exists in cluster, deAllocate all the ports related to it. + for key := range n.podAllocate { + gssName := pod.GetLabels()[gamekruiseiov1alpha1.GameServerOwnerGssKey] + if strings.Contains(key, pod.GetNamespace()+"/"+gssName) { + podKeys = append(podKeys, key) + } + } + } else { + podKeys = append(podKeys, pod.GetNamespace()+"/"+pod.GetName()) + } + + for _, podKey := range podKeys { + n.deAllocate(podKey) + } + + return nil +} + +func init() { + nlbPlugin := NlbPlugin{ + mutex: sync.RWMutex{}, + } + alibabaCloudProvider.registerPlugin(&nlbPlugin) +} + +func (n *NlbPlugin) consSvc(nc *nlbConfig, pod *corev1.Pod, c client.Client, ctx context.Context) *corev1.Service { + var ports []int32 + var lbId string + podKey := pod.GetNamespace() + "/" + pod.GetName() + allocatedPorts, exist := n.podAllocate[podKey] + if exist { + slbPorts := strings.Split(allocatedPorts, ":") + lbId = slbPorts[0] + ports = util.StringToInt32Slice(slbPorts[1], ",") + } else { + lbId, ports = n.allocate(nc.lbIds, len(nc.targetPorts), podKey) + } + + svcPorts := make([]corev1.ServicePort, 0) + for i := 0; i < len(nc.targetPorts); i++ { + svcPorts = append(svcPorts, corev1.ServicePort{ + Name: strconv.Itoa(nc.targetPorts[i]), + Port: ports[i], + Protocol: nc.protocols[i], + TargetPort: intstr.FromInt(nc.targetPorts[i]), + }) + } + + loadBalancerClass := "alibabacloud.com/nlb" + + svc := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: pod.GetName(), + Namespace: pod.GetNamespace(), + Annotations: map[string]string{ + SlbListenerOverrideKey: "true", + SlbIdAnnotationKey: lbId, + SlbConfigHashKey: util.GetHash(nc), + }, + OwnerReferences: getSvcOwnerReference(c, ctx, pod, nc.isFixed), + }, + Spec: corev1.ServiceSpec{ + ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyTypeLocal, + Type: corev1.ServiceTypeLoadBalancer, + Selector: map[string]string{ + SvcSelectorKey: pod.GetName(), + }, + Ports: svcPorts, + LoadBalancerClass: &loadBalancerClass, + }, + } + return svc +} + +func (n *NlbPlugin) allocate(lbIds []string, num int, nsName string) (string, []int32) { + n.mutex.Lock() + defer n.mutex.Unlock() + + var ports []int32 + var lbId string + + // find lb with adequate ports + for _, slbId := range lbIds { + sum := 0 + for i := n.minPort; i < n.maxPort; i++ { + if !n.cache[slbId][i] { + sum++ + } + if sum >= num { + lbId = slbId + break + } + } + } + + // select ports + for i := 0; i < num; i++ { + var port int32 + if n.cache[lbId] == nil { + n.cache[lbId] = make(portAllocated, n.maxPort-n.minPort) + for i := n.minPort; i < n.maxPort; i++ { + n.cache[lbId][i] = false + } + } + + for p, allocated := range n.cache[lbId] { + if !allocated { + port = p + break + } + } + n.cache[lbId][port] = true + ports = append(ports, port) + } + + n.podAllocate[nsName] = lbId + ":" + util.Int32SliceToString(ports, ",") + log.Infof("pod %s allocate nlb %s ports %v", nsName, lbId, ports) + return lbId, ports +} + +func (n *NlbPlugin) deAllocate(nsName string) { + n.mutex.Lock() + defer n.mutex.Unlock() + + allocatedPorts, exist := n.podAllocate[nsName] + if !exist { + return + } + + slbPorts := strings.Split(allocatedPorts, ":") + lbId := slbPorts[0] + ports := util.StringToInt32Slice(slbPorts[1], ",") + for _, port := range ports { + n.cache[lbId][port] = false + } + + delete(n.podAllocate, nsName) + log.Infof("pod %s deallocate nlb %s ports %v", nsName, lbId, ports) +} + +func parseNlbConfig(conf []gamekruiseiov1alpha1.NetworkConfParams) *nlbConfig { + var lbIds []string + ports := make([]int, 0) + protocols := make([]corev1.Protocol, 0) + isFixed := false + for _, c := range conf { + switch c.Name { + case NlbIdsConfigName: + for _, slbId := range strings.Split(c.Value, ",") { + if slbId != "" { + lbIds = append(lbIds, slbId) + } + } + case PortProtocolsConfigName: + for _, pp := range strings.Split(c.Value, ",") { + ppSlice := strings.Split(pp, "/") + port, err := strconv.Atoi(ppSlice[0]) + if err != nil { + continue + } + ports = append(ports, port) + if len(ppSlice) != 2 { + protocols = append(protocols, corev1.ProtocolTCP) + } else { + protocols = append(protocols, corev1.Protocol(ppSlice[1])) + } + } + case FixedConfigName: + v, err := strconv.ParseBool(c.Value) + if err != nil { + continue + } + isFixed = v + } + } + return &nlbConfig{ + lbIds: lbIds, + protocols: protocols, + targetPorts: ports, + isFixed: isFixed, + } +} diff --git a/cloudprovider/alibabacloud/nlb_sp.go b/cloudprovider/alibabacloud/nlb_sp.go index d49b4ffb..c9b6f08b 100644 --- a/cloudprovider/alibabacloud/nlb_sp.go +++ b/cloudprovider/alibabacloud/nlb_sp.go @@ -178,13 +178,13 @@ func (N *NlbSpPlugin) OnPodDeleted(client client.Client, pod *corev1.Pod, ctx co return nil } -type nlbConfig struct { +type nlbSpConfig struct { lbId string ports []int protocols []corev1.Protocol } -func parseNLbSpConfig(conf []gamekruiseiov1alpha1.NetworkConfParams) *nlbConfig { +func parseNLbSpConfig(conf []gamekruiseiov1alpha1.NetworkConfParams) *nlbSpConfig { var lbIds string var ports []int var protocols []corev1.Protocol @@ -196,14 +196,14 @@ func parseNLbSpConfig(conf []gamekruiseiov1alpha1.NetworkConfParams) *nlbConfig ports, protocols = parsePortProtocols(c.Value) } } - return &nlbConfig{ + return &nlbSpConfig{ lbId: lbIds, ports: ports, protocols: protocols, } } -func consNlbSvc(nc *nlbConfig, pod *corev1.Pod, c client.Client, ctx context.Context) *corev1.Service { +func consNlbSvc(nc *nlbSpConfig, pod *corev1.Pod, c client.Client, ctx context.Context) *corev1.Service { svcPorts := make([]corev1.ServicePort, 0) for i := 0; i < len(nc.ports); i++ { svcPorts = append(svcPorts, corev1.ServicePort{ diff --git a/cloudprovider/alibabacloud/nlb_sp_test.go b/cloudprovider/alibabacloud/nlb_sp_test.go index 214e1278..63f09db1 100644 --- a/cloudprovider/alibabacloud/nlb_sp_test.go +++ b/cloudprovider/alibabacloud/nlb_sp_test.go @@ -10,7 +10,7 @@ import ( func TestParseNLbSpConfig(t *testing.T) { tests := []struct { conf []gamekruiseiov1alpha1.NetworkConfParams - nc *nlbConfig + nc *nlbSpConfig }{ { conf: []gamekruiseiov1alpha1.NetworkConfParams{ @@ -23,7 +23,7 @@ func TestParseNLbSpConfig(t *testing.T) { Value: "80/UDP", }, }, - nc: &nlbConfig{ + nc: &nlbSpConfig{ protocols: []corev1.Protocol{corev1.ProtocolUDP}, ports: []int{80}, lbId: "nlb-xxx", @@ -40,7 +40,7 @@ func TestParseNLbSpConfig(t *testing.T) { Value: "80", }, }, - nc: &nlbConfig{ + nc: &nlbSpConfig{ protocols: []corev1.Protocol{corev1.ProtocolTCP}, ports: []int{80}, lbId: "nlb-xxx", @@ -52,7 +52,7 @@ func TestParseNLbSpConfig(t *testing.T) { expect := test.nc actual := parseNLbSpConfig(test.conf) if !reflect.DeepEqual(expect, actual) { - t.Errorf("case %d: expect nlbConfig is %v, but actually is %v", i, expect, actual) + t.Errorf("case %d: expect nlbSpConfig is %v, but actually is %v", i, expect, actual) } } } diff --git a/cloudprovider/alibabacloud/nlb_test.go b/cloudprovider/alibabacloud/nlb_test.go new file mode 100644 index 00000000..0337133b --- /dev/null +++ b/cloudprovider/alibabacloud/nlb_test.go @@ -0,0 +1,236 @@ +package alibabacloud + +import ( + "context" + gamekruiseiov1alpha1 "github.com/openkruise/kruise-game/apis/v1alpha1" + "github.com/openkruise/kruise-game/pkg/util" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/utils/pointer" + "reflect" + "sigs.k8s.io/controller-runtime/pkg/client" + "sync" + "testing" +) + +func TestNLBAllocateDeAllocate(t *testing.T) { + test := struct { + lbIds []string + nlb *NlbPlugin + num int + podKey string + }{ + lbIds: []string{"xxx-A"}, + nlb: &NlbPlugin{ + maxPort: int32(712), + minPort: int32(512), + cache: make(map[string]portAllocated), + podAllocate: make(map[string]string), + mutex: sync.RWMutex{}, + }, + podKey: "xxx/xxx", + num: 3, + } + + lbId, ports := test.nlb.allocate(test.lbIds, test.num, test.podKey) + if _, exist := test.nlb.podAllocate[test.podKey]; !exist { + t.Errorf("podAllocate[%s] is empty after allocated", test.podKey) + } + for _, port := range ports { + if port > test.nlb.maxPort || port < test.nlb.minPort { + t.Errorf("allocate port %d, unexpected", port) + } + if test.nlb.cache[lbId][port] == false { + t.Errorf("Allocate port %d failed", port) + } + } + test.nlb.deAllocate(test.podKey) + for _, port := range ports { + if test.nlb.cache[lbId][port] == true { + t.Errorf("deAllocate port %d failed", port) + } + } + if _, exist := test.nlb.podAllocate[test.podKey]; exist { + t.Errorf("podAllocate[%s] is not empty after deallocated", test.podKey) + } +} + +func TestParseNlbConfig(t *testing.T) { + tests := []struct { + conf []gamekruiseiov1alpha1.NetworkConfParams + lbIds []string + ports []int + protocols []corev1.Protocol + isFixed bool + }{ + { + conf: []gamekruiseiov1alpha1.NetworkConfParams{ + { + Name: NlbIdsConfigName, + Value: "xxx-A", + }, + { + Name: PortProtocolsConfigName, + Value: "80", + }, + }, + lbIds: []string{"xxx-A"}, + ports: []int{80}, + protocols: []corev1.Protocol{corev1.ProtocolTCP}, + isFixed: false, + }, + { + conf: []gamekruiseiov1alpha1.NetworkConfParams{ + { + Name: NlbIdsConfigName, + Value: "xxx-A,xxx-B,", + }, + { + Name: PortProtocolsConfigName, + Value: "81/UDP,82,83/TCP", + }, + { + Name: FixedConfigName, + Value: "true", + }, + }, + lbIds: []string{"xxx-A", "xxx-B"}, + ports: []int{81, 82, 83}, + protocols: []corev1.Protocol{corev1.ProtocolUDP, corev1.ProtocolTCP, corev1.ProtocolTCP}, + isFixed: true, + }, + } + + for _, test := range tests { + sc := parseNlbConfig(test.conf) + if !reflect.DeepEqual(test.lbIds, sc.lbIds) { + t.Errorf("lbId expect: %v, actual: %v", test.lbIds, sc.lbIds) + } + if !util.IsSliceEqual(test.ports, sc.targetPorts) { + t.Errorf("ports expect: %v, actual: %v", test.ports, sc.targetPorts) + } + if !reflect.DeepEqual(test.protocols, sc.protocols) { + t.Errorf("protocols expect: %v, actual: %v", test.protocols, sc.protocols) + } + if test.isFixed != sc.isFixed { + t.Errorf("isFixed expect: %v, actual: %v", test.isFixed, sc.isFixed) + } + } +} + +func TestNlbPlugin_consSvc(t *testing.T) { + loadBalancerClass := "alibabacloud.com/nlb" + type fields struct { + maxPort int32 + minPort int32 + cache map[string]portAllocated + podAllocate map[string]string + } + type args struct { + config *nlbConfig + pod *corev1.Pod + client client.Client + ctx context.Context + } + tests := []struct { + name string + fields fields + args args + want *corev1.Service + }{ + { + name: "convert svc cache exist", + fields: fields{ + maxPort: 3000, + minPort: 1, + cache: map[string]portAllocated{ + "default/test-pod": map[int32]bool{}, + }, + podAllocate: map[string]string{ + "default/test-pod": "clb-xxx:80,81", + }, + }, + args: args{ + config: &nlbConfig{ + lbIds: []string{"clb-xxx"}, + targetPorts: []int{82}, + protocols: []corev1.Protocol{ + corev1.ProtocolTCP, + }, + isFixed: false, + }, + pod: &corev1.Pod{ + TypeMeta: metav1.TypeMeta{ + Kind: "pod", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod", + Namespace: "default", + UID: "32fqwfqfew", + }, + }, + client: nil, + ctx: context.Background(), + }, + want: &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod", + Namespace: "default", + Annotations: map[string]string{ + SlbListenerOverrideKey: "true", + SlbIdAnnotationKey: "clb-xxx", + SlbConfigHashKey: util.GetHash(&nlbConfig{ + lbIds: []string{"clb-xxx"}, + targetPorts: []int{82}, + protocols: []corev1.Protocol{ + corev1.ProtocolTCP, + }, + isFixed: false, + }), + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "pod", + Name: "test-pod", + UID: "32fqwfqfew", + Controller: pointer.BoolPtr(true), + BlockOwnerDeletion: pointer.BoolPtr(true), + }, + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyTypeLocal, + LoadBalancerClass: &loadBalancerClass, + Selector: map[string]string{ + SvcSelectorKey: "test-pod", + }, + Ports: []corev1.ServicePort{{ + Name: "82", + Port: 80, + Protocol: "TCP", + TargetPort: intstr.IntOrString{ + Type: 0, + IntVal: 82, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + c := &NlbPlugin{ + maxPort: tt.fields.maxPort, + minPort: tt.fields.minPort, + cache: tt.fields.cache, + podAllocate: tt.fields.podAllocate, + } + if got := c.consSvc(tt.args.config, tt.args.pod, tt.args.client, tt.args.ctx); !reflect.DeepEqual(got, tt.want) { + t.Errorf("consSvc() = %v, want %v", got, tt.want) + } + } +} diff --git a/cloudprovider/alibabacloud/slb.go b/cloudprovider/alibabacloud/slb.go index 3c3aa72b..0da2e42a 100644 --- a/cloudprovider/alibabacloud/slb.go +++ b/cloudprovider/alibabacloud/slb.go @@ -88,6 +88,7 @@ func (s *SlbPlugin) Init(c client.Client, options cloudprovider.CloudProviderOpt } s.cache, s.podAllocate = initLbCache(svcList.Items, s.minPort, s.maxPort) + log.Infof("[%s] podAllocate cache complete initialization: %v", SlbNetwork, s.podAllocate) return nil } @@ -115,7 +116,6 @@ func initLbCache(svcList []corev1.Service, minPort, maxPort int32) (map[string]p } } } - log.Infof("[%s] podAllocate cache complete initialization: %v", SlbNetwork, newPodAllocate) return newCache, newPodAllocate } diff --git a/cloudprovider/options/alibabacloud_options.go b/cloudprovider/options/alibabacloud_options.go index d8cace25..61dbfcf1 100644 --- a/cloudprovider/options/alibabacloud_options.go +++ b/cloudprovider/options/alibabacloud_options.go @@ -3,6 +3,7 @@ package options type AlibabaCloudOptions struct { Enable bool `toml:"enable"` SLBOptions SLBOptions `toml:"slb"` + NLBOptions NLBOptions `toml:"nlb"` } type SLBOptions struct { @@ -10,6 +11,11 @@ type SLBOptions struct { MinPort int32 `toml:"min_port"` } +type NLBOptions struct { + MaxPort int32 `toml:"max_port"` + MinPort int32 `toml:"min_port"` +} + func (o AlibabaCloudOptions) Valid() bool { // SLB valid slbOptions := o.SLBOptions @@ -19,6 +25,14 @@ func (o AlibabaCloudOptions) Valid() bool { if slbOptions.MinPort <= 0 { return false } + // NLB valid + nlbOptions := o.NLBOptions + if nlbOptions.MaxPort-nlbOptions.MinPort != 500 { + return false + } + if nlbOptions.MinPort <= 0 { + return false + } return true } diff --git a/config/manager/config.toml b/config/manager/config.toml index c6c43e1a..2fc62cb7 100644 --- a/config/manager/config.toml +++ b/config/manager/config.toml @@ -9,6 +9,9 @@ enable = true [alibabacloud.slb] max_port = 700 min_port = 500 +[alibabacloud.nlb] +max_port = 1500 +min_port = 1000 [volcengine] enable = true