diff --git a/apis/apps/v1/cluster_types.go b/apis/apps/v1/cluster_types.go index a960a562f89..3c2dd1c9f6c 100644 --- a/apis/apps/v1/cluster_types.go +++ b/apis/apps/v1/cluster_types.go @@ -606,15 +606,9 @@ type ShardingSpec struct { type ClusterService struct { Service `json:",inline"` - // Extends the ServiceSpec.Selector by allowing the specification of a sharding name, which is defined in - // `cluster.spec.shardingSpecs[*].name`, to be used as a selector for the service. - // Note that this and the `componentSelector` are mutually exclusive and cannot be set simultaneously. + // Extends the ServiceSpec.Selector by allowing the specification of components, to be used as a selector for the service. // - // +optional - ShardingSelector string `json:"shardingSelector,omitempty"` - - // Extends the ServiceSpec.Selector by allowing the specification of a component, to be used as a selector for the service. - // Note that this and the `shardingSelector` are mutually exclusive and cannot be set simultaneously. + // If the `componentSelector` is set as a name of a sharding, the service will be exposed to all components in the sharding. // // +optional ComponentSelector string `json:"componentSelector,omitempty"` diff --git a/config/crd/bases/apps.kubeblocks.io_clusters.yaml b/config/crd/bases/apps.kubeblocks.io_clusters.yaml index 19f781797f1..081ffee50ff 100644 --- a/config/crd/bases/apps.kubeblocks.io_clusters.yaml +++ b/config/crd/bases/apps.kubeblocks.io_clusters.yaml @@ -8350,8 +8350,10 @@ spec: type: object componentSelector: description: |- - Extends the ServiceSpec.Selector by allowing the specification of a component, to be used as a selector for the service. - Note that this and the `shardingSelector` are mutually exclusive and cannot be set simultaneously. + Extends the ServiceSpec.Selector by allowing the specification of components, to be used as a selector for the service. + + + If the `componentSelector` is set as a name of a sharding, the service will be exposed to all components in the sharding. type: string name: description: |- @@ -8390,12 +8392,6 @@ spec: maxLength: 25 pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ type: string - shardingSelector: - description: |- - Extends the ServiceSpec.Selector by allowing the specification of a sharding name, which is defined in - `cluster.spec.shardingSpecs[*].name`, to be used as a selector for the service. - Note that this and the `componentSelector` are mutually exclusive and cannot be set simultaneously. - type: string spec: description: |- Spec defines the behavior of a service. diff --git a/controllers/apps/cluster_controller_test.go b/controllers/apps/cluster_controller_test.go index a8268666938..4ee54d2ae27 100644 --- a/controllers/apps/cluster_controller_test.go +++ b/controllers/apps/cluster_controller_test.go @@ -528,7 +528,7 @@ var _ = Describe("Cluster Controller", func() { svcType corev1.ServiceType } - validateClusterServiceList := func(g Gomega, expectServices map[string]expectService, compName string, shardCount *int, enableShardOrdinal bool) { + validateClusterServiceList := func(g Gomega, expectServices map[string]expectService, compName string, shardCount *int) { svcList := &corev1.ServiceList{} g.Expect(testCtx.Cli.List(testCtx.Ctx, svcList, client.MatchingLabels{ constant.AppInstanceLabelKey: clusterKey.Name, @@ -553,9 +553,6 @@ var _ = Describe("Cluster Controller", func() { g.Expect(svc.Spec.ClusterIP).ShouldNot(Equal(corev1.ClusterIPNone)) case svc.Spec.Type == corev1.ServiceTypeClusterIP && len(svcSpec.clusterIP) != 0: g.Expect(svc.Spec.ClusterIP).Should(Equal(corev1.ClusterIPNone)) - // for _, port := range getHeadlessSvcPorts(g, compDefName) { - // g.Expect(slices.Index(svc.Spec.Ports, port) >= 0).Should(BeTrue()) - // } } } @@ -571,20 +568,16 @@ var _ = Describe("Cluster Controller", func() { } g.Expect(len(expectServices)).Should(Equal(len(services))) } else { - if enableShardOrdinal { - g.Expect(len(expectServices) * *shardCount).Should(Equal(len(services))) - } else { - for svcName, svcSpec := range expectServices { - idx := slices.IndexFunc(services, func(e *corev1.Service) bool { - return e.Name == constant.GenerateClusterServiceName(clusterObj.Name, svcName) - }) - g.Expect(idx >= 0).To(BeTrue()) - svc := services[idx] - g.Expect(svc.Spec.Selector).Should(HaveKeyWithValue(constant.KBAppShardingNameLabelKey, compName)) - validateSvc(svc, svcSpec) - } - g.Expect(len(expectServices)).Should(Equal(len(services))) + for svcName, svcSpec := range expectServices { + idx := slices.IndexFunc(services, func(e *corev1.Service) bool { + return e.Name == constant.GenerateClusterServiceName(clusterObj.Name, svcName) + }) + g.Expect(idx >= 0).To(BeTrue()) + svc := services[idx] + g.Expect(svc.Spec.Selector).Should(HaveKeyWithValue(constant.KBAppShardingNameLabelKey, compName)) + validateSvc(svc, svcSpec) } + g.Expect(len(expectServices)).Should(Equal(len(services))) } } @@ -635,7 +628,7 @@ var _ = Describe("Cluster Controller", func() { Expect(testCtx.CheckedCreateObj(testCtx.Ctx, svcObj)).Should(Succeed()) By("check all services created") - Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compName, nil, false) }).Should(Succeed()) + Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compName, nil) }).Should(Succeed()) By("delete a cluster service") delete(expectServices, deleteService.Name) @@ -650,14 +643,14 @@ var _ = Describe("Cluster Controller", func() { })()).ShouldNot(HaveOccurred()) By("check the service has been deleted, and the non-managed service has not been deleted") - Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compName, nil, false) }).Should(Succeed()) + Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compName, nil) }).Should(Succeed()) By("add the deleted service back") expectServices[deleteService.Name] = expectService{deleteService.Spec.ClusterIP, deleteService.Spec.Type} Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { cluster.Spec.Services = append(cluster.Spec.Services, deleteService) })()).ShouldNot(HaveOccurred()) - Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compName, nil, false) }).Should(Succeed()) + Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compName, nil) }).Should(Succeed()) } testShardingClusterServiceCreateAndDelete := func(compTplName, compDefName string, createObj func(string, string, func(*testapps.MockClusterFactory))) { @@ -680,7 +673,7 @@ var _ = Describe("Cluster Controller", func() { ClusterIP: svc.clusterIP, }, }, - ShardingSelector: compTplName, + ComponentSelector: compTplName, }) } createObj(compTplName, compDefName, func(f *testapps.MockClusterFactory) { @@ -690,19 +683,10 @@ var _ = Describe("Cluster Controller", func() { shards := defaultShardCount deleteService := services[0] - By("check only one service created for each shard when ShardSvcAnnotationKey is not set") - Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compTplName, &shards, false) }).Should(Succeed()) - - By("check shards number services were created for each shard when ShardSvcAnnotationKey is set") - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { - if cluster.Annotations == nil { - cluster.Annotations = map[string]string{} - } - cluster.Annotations[constant.ShardSvcAnnotationKey] = compTplName - })()).ShouldNot(HaveOccurred()) - Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compTplName, &shards, true) }).Should(Succeed()) + By("check service created for sharding") + Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compTplName, &shards) }).Should(Succeed()) - By("delete a cluster shard service") + By("delete a sharding cluster service") delete(expectServices, deleteService.Name) Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { var svcs []appsv1.ClusterService @@ -715,14 +699,14 @@ var _ = Describe("Cluster Controller", func() { })()).ShouldNot(HaveOccurred()) By("check the service has been deleted, and the non-managed service has not been deleted") - Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compTplName, &shards, true) }).Should(Succeed()) + Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compTplName, &shards) }).Should(Succeed()) By("add the deleted service back") expectServices[deleteService.Name] = expectService{deleteService.Spec.ClusterIP, deleteService.Spec.Type} Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { cluster.Spec.Services = append(cluster.Spec.Services, deleteService) })()).ShouldNot(HaveOccurred()) - Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compTplName, &shards, true) }).Should(Succeed()) + Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compTplName, &shards) }).Should(Succeed()) } testClusterFinalizer := func(compName string, createObj func(appsv1.TerminationPolicyType)) { @@ -1122,7 +1106,7 @@ var _ = Describe("Cluster Controller", func() { testClusterServiceCreateAndDelete(defaultCompName, compDefObj.Name, createClusterObj) }) - It("should create and delete shard topology cluster service correctly", func() { + It("should create and delete sharding cluster service correctly", func() { testShardingClusterServiceCreateAndDelete(defaultCompName, compDefObj.Name, createClusterObjWithSharding) }) }) diff --git a/controllers/apps/transformer_cluster_component.go b/controllers/apps/transformer_cluster_component.go index f0e0a541b59..7f5ef4842e9 100644 --- a/controllers/apps/transformer_cluster_component.go +++ b/controllers/apps/transformer_cluster_component.go @@ -82,9 +82,7 @@ func (t *clusterComponentTransformer) reconcileComponents(transCtx *clusterTrans return err } - createCompSet := protoCompSet.Difference(runningCompSet) - updateCompSet := protoCompSet.Intersection(runningCompSet) - deleteCompSet := runningCompSet.Difference(protoCompSet) + createCompSet, deleteCompSet, updateCompSet := setDiff(runningCompSet, protoCompSet) // component objects to be deleted (scale-in) if err := deleteCompsInOrder(transCtx, dag, deleteCompSet, false); err != nil { @@ -600,3 +598,12 @@ func shardingNameFromComp(transCtx *clusterTransformContext, compName string) st } return "" } + +func setDiff(s1, s2 sets.Set[string]) (sets.Set[string], sets.Set[string], sets.Set[string]) { + return s2.Difference(s1), s1.Difference(s2), s1.Intersection(s2) +} + +func mapDiff[T interface{}](m1, m2 map[string]T) (sets.Set[string], sets.Set[string], sets.Set[string]) { + s1, s2 := sets.KeySet(m1), sets.KeySet(m2) + return setDiff(s1, s2) +} diff --git a/controllers/apps/transformer_cluster_service.go b/controllers/apps/transformer_cluster_service.go index 8a580beab36..537d282b911 100644 --- a/controllers/apps/transformer_cluster_service.go +++ b/controllers/apps/transformer_cluster_service.go @@ -24,10 +24,7 @@ import ( "reflect" "strings" - "golang.org/x/exp/slices" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" @@ -50,7 +47,8 @@ func (t *clusterServiceTransformer) Transform(ctx graph.TransformContext, dag *g return nil } if common.IsCompactMode(transCtx.OrigCluster.Annotations) { - transCtx.V(1).Info("Cluster is in compact mode, no need to create service objects", "cluster", client.ObjectKeyFromObject(transCtx.OrigCluster)) + transCtx.V(1).Info("Cluster is in compact mode, no need to create service objects", + "cluster", client.ObjectKeyFromObject(transCtx.OrigCluster)) return nil } @@ -62,118 +60,103 @@ func (t *clusterServiceTransformer) Transform(ctx graph.TransformContext, dag *g return err } - handleServiceFunc := func(origSvc, genSvc *appsv1.ClusterService) error { - service, err := t.buildService(transCtx, cluster, origSvc, genSvc) - if err != nil { - return err - } - if err = t.createOrUpdateService(ctx, dag, graphCli, service); err != nil { - return err - } - delete(services, service.Name) - return nil + protoServices, err := t.buildClusterServices(transCtx, cluster) + if err != nil { + return err + } + + toCreateServices, toDeleteServices, toUpdateServices := mapDiff(services, protoServices) + + for svc := range toCreateServices { + graphCli.Create(dag, protoServices[svc], inDataContext4G()) } + for svc := range toUpdateServices { + t.updateService(dag, graphCli, services[svc], protoServices[svc]) + } + for svc := range toDeleteServices { + graphCli.Delete(dag, services[svc], inDataContext4G()) + } + return nil +} +func (t *clusterServiceTransformer) buildClusterServices(transCtx *clusterTransformContext, + cluster *appsv1.Cluster) (map[string]*corev1.Service, error) { + services := make(map[string]*corev1.Service) for i := range cluster.Spec.Services { - svc := &cluster.Spec.Services[i] - if len(svc.ShardingSelector) > 0 && len(svc.ComponentSelector) > 0 { - return fmt.Errorf("the ShardingSelector and ComponentSelector of service can't be defined at the same time, service: %s", svc.Name) - } - genServices, err := t.genMultiServiceIfNeed(transCtx, cluster, svc) + service, err := t.buildClusterService(transCtx, cluster, &cluster.Spec.Services[i]) if err != nil { - return err + return nil, err } - for j := range genServices { - genSvc := genServices[j] - if err = handleServiceFunc(svc, genSvc); err != nil { - return err + services[service.Name] = service + } + return services, nil +} + +func (t *clusterServiceTransformer) buildClusterService(transCtx *clusterTransformContext, + cluster *appsv1.Cluster, service *appsv1.ClusterService) (*corev1.Service, error) { + sharding, err := t.shardingService(cluster, service) + if err != nil { + return nil, err + } + + var selectors map[string]string + if len(service.ComponentSelector) > 0 { + if sharding { + selectors = map[string]string{ + constant.KBAppShardingNameLabelKey: service.ComponentSelector, + } + } else { + selectors = map[string]string{ + constant.KBAppComponentLabelKey: service.ComponentSelector, } } } + return t.buildService(transCtx, cluster, service, selectors) +} - for svc := range services { - graphCli.Delete(dag, services[svc]) +func (t *clusterServiceTransformer) shardingService(cluster *appsv1.Cluster, service *appsv1.ClusterService) (bool, error) { + if len(service.ComponentSelector) == 0 { + return false, nil } - - return nil + for _, spec := range cluster.Spec.ShardingSpecs { + if spec.Name == service.ComponentSelector { + return true, nil + } + } + for _, spec := range cluster.Spec.ComponentSpecs { + if spec.Name == service.ComponentSelector { + return false, nil + } + } + return false, fmt.Errorf("the component of service selector is not exist, service: %s, component: %s", + service.Name, service.ComponentSelector) } func (t *clusterServiceTransformer) buildService(transCtx *clusterTransformContext, cluster *appsv1.Cluster, - origSvc, genSvc *appsv1.ClusterService) (*corev1.Service, error) { - var ( - namespace = cluster.Namespace - clusterName = cluster.Name - ) - - serviceName := constant.GenerateClusterServiceName(cluster.Name, genSvc.ServiceName) - builder := builder.NewServiceBuilder(namespace, serviceName). - AddLabelsInMap(constant.GetClusterLabels(clusterName)). - AddAnnotationsInMap(genSvc.Annotations). - SetSpec(&genSvc.Spec). + service *appsv1.ClusterService, selectors map[string]string) (*corev1.Service, error) { + serviceName := constant.GenerateClusterServiceName(cluster.Name, service.ServiceName) + builder := builder.NewServiceBuilder(cluster.Namespace, serviceName). + AddLabelsInMap(constant.GetClusterLabels(cluster.Name)). + AddAnnotationsInMap(service.Annotations). + SetSpec(&service.Spec). AddSelectorsInMap(t.builtinSelector(cluster)). + AddSelectorsInMap(selectors). Optimize4ExternalTraffic() - if len(genSvc.ShardingSelector) > 0 { - builder.AddSelector(constant.KBAppShardingNameLabelKey, genSvc.ShardingSelector) - if enableShardService(cluster, genSvc.ShardingSelector) { - builder.AddSelector(constant.KBAppComponentLabelKey, genComponentSelector(origSvc, genSvc)) - } - } else if len(genSvc.ComponentSelector) > 0 { - builder.AddSelector(constant.KBAppComponentLabelKey, genSvc.ComponentSelector) - } - - if len(genSvc.RoleSelector) > 0 { - compDef, err := t.checkComponent(transCtx, genSvc) + if len(service.RoleSelector) > 0 { + compDef, err := t.checkComponentDef(transCtx, cluster, service) if err != nil { return nil, err } - if err := t.checkComponentRoles(compDef, genSvc); err != nil { + if err := t.checkComponentRoles(compDef, service); err != nil { return nil, err } - builder.AddSelector(constant.RoleLabelKey, genSvc.RoleSelector) + builder.AddSelector(constant.RoleLabelKey, service.RoleSelector) } return builder.GetObject(), nil } -func (t *clusterServiceTransformer) genMultiServiceIfNeed(transCtx *clusterTransformContext, - cluster *appsv1.Cluster, clusterService *appsv1.ClusterService) ([]*appsv1.ClusterService, error) { - if len(clusterService.ShardingSelector) == 0 || len(cluster.Spec.ShardingSpecs) == 0 { - return []*appsv1.ClusterService{clusterService}, nil - } - - shardingName := "" - shardingCompSpecs := make([]*appsv1.ClusterComponentSpec, 0) - for k, v := range transCtx.ShardingComponentSpecs { - if k != clusterService.ShardingSelector { - continue - } - shardingName = k - shardingCompSpecs = v - } - - if len(shardingName) == 0 { - return nil, fmt.Errorf("the ShardingSelector of service is not defined, service: %s, shard: %s", clusterService.Name, clusterService.ShardingSelector) - } - - if !enableShardService(cluster, shardingName) { - return []*appsv1.ClusterService{clusterService}, nil - } - - shardOrdinalClusterSvcs := make([]*appsv1.ClusterService, 0, len(shardingCompSpecs)) - for _, shardingCompSpec := range shardingCompSpecs { - svc := clusterService.DeepCopy() - svc.Name = fmt.Sprintf("%s-%s", clusterService.Name, shardingCompSpec.Name) - if len(clusterService.ServiceName) == 0 { - svc.ServiceName = shardingCompSpec.Name - } else { - svc.ServiceName = fmt.Sprintf("%s-%s", clusterService.ServiceName, shardingCompSpec.Name) - } - shardOrdinalClusterSvcs = append(shardOrdinalClusterSvcs, svc) - } - return shardOrdinalClusterSvcs, nil -} - func (t *clusterServiceTransformer) builtinSelector(cluster *appsv1.Cluster) map[string]string { selectors := map[string]string{ constant.AppManagedByLabelKey: constant.AppName, @@ -182,18 +165,30 @@ func (t *clusterServiceTransformer) builtinSelector(cluster *appsv1.Cluster) map return selectors } -func (t *clusterServiceTransformer) checkComponent(transCtx *clusterTransformContext, clusterService *appsv1.ClusterService) (*appsv1.ComponentDefinition, error) { - compName := clusterService.ComponentSelector - for _, compSpec := range transCtx.ComponentSpecs { - if compSpec.Name == compName { - compDef, ok := transCtx.ComponentDefs[compSpec.ComponentDef] - if !ok { - return nil, fmt.Errorf("the component definition of service selector is not defined, service: %s, component: %s", clusterService.Name, compName) - } - return compDef, nil +func (t *clusterServiceTransformer) checkComponentDef(transCtx *clusterTransformContext, + cluster *appsv1.Cluster, service *appsv1.ClusterService) (*appsv1.ComponentDefinition, error) { + selector := service.ComponentSelector + + checkedCompDef := func(compDefName string) (*appsv1.ComponentDefinition, error) { + compDef, ok := transCtx.ComponentDefs[compDefName] + if !ok { + return nil, fmt.Errorf("the component definition of service selector is not defined, service: %s, component: %s", service.Name, selector) } + return compDef, nil } - return nil, fmt.Errorf("the component of service selector is not exist, service: %s, component: %s", clusterService.Name, compName) + + for _, spec := range cluster.Spec.ShardingSpecs { + if spec.Name == selector { + return checkedCompDef(spec.Template.ComponentDef) + } + } + for _, spec := range cluster.Spec.ComponentSpecs { + if spec.Name == selector { + return checkedCompDef(spec.ComponentDef) + } + } + + return nil, fmt.Errorf("the component of service selector is not exist, service: %s, component: %s", service.Name, selector) } func (t *clusterServiceTransformer) checkComponentRoles(compDef *appsv1.ComponentDefinition, clusterService *appsv1.ClusterService) error { @@ -224,60 +219,14 @@ func (t *clusterServiceTransformer) listOwnedClusterServices(transCtx *clusterTr return services, nil } -func (t *clusterServiceTransformer) createOrUpdateService(ctx graph.TransformContext, dag *graph.DAG, graphCli model.GraphClient, service *corev1.Service) error { - key := types.NamespacedName{ - Namespace: service.Namespace, - Name: service.Name, - } - originSvc := &corev1.Service{} - if err := ctx.GetClient().Get(ctx.GetContext(), key, originSvc, inDataContext4C()); err != nil { - if apierrors.IsNotFound(err) { - graphCli.Create(dag, service, inDataContext4G()) - return nil - } - return err - } - - newSvc := originSvc.DeepCopy() - newSvc.Spec = service.Spec - ctrlutil.MergeMetadataMapInplace(service.Labels, &newSvc.Labels) - ctrlutil.MergeMetadataMapInplace(service.Annotations, &newSvc.Annotations) - resolveServiceDefaultFields(&originSvc.Spec, &newSvc.Spec) - - if !reflect.DeepEqual(originSvc, newSvc) { - graphCli.Update(dag, originSvc, newSvc, inDataContext4G()) - } - return nil -} - -// func checkLegacyServiceExist(ctx graph.TransformContext, serviceName, namespace string) (bool, error) { -// key := types.NamespacedName{ -// Namespace: namespace, -// Name: serviceName, -// } -// obj := &corev1.Service{} -// if err := ctx.GetClient().Get(ctx.GetContext(), key, obj); err != nil { -// if apierrors.IsNotFound(err) { -// return false, nil -// } -// return false, err -// } -// return true, nil -// } - -func enableShardService(cluster *appsv1.Cluster, shardingName string) bool { - enableShardSvcList, ok := cluster.Annotations[constant.ShardSvcAnnotationKey] - if !ok || !slices.Contains(strings.Split(enableShardSvcList, ","), shardingName) { - return false - } - return true -} +func (t *clusterServiceTransformer) updateService(dag *graph.DAG, graphCli model.GraphClient, running, proto *corev1.Service) { + newSvc := running.DeepCopy() + newSvc.Spec = proto.Spec + ctrlutil.MergeMetadataMapInplace(proto.Labels, &newSvc.Labels) + ctrlutil.MergeMetadataMapInplace(proto.Annotations, &newSvc.Annotations) + resolveServiceDefaultFields(&running.Spec, &newSvc.Spec) -// genComponentSelector generates component selector for sharding service. -func genComponentSelector(origSvc, genSvc *appsv1.ClusterService) string { - origSvcPrefix := constant.GenerateShardingNameSvcPrefix(origSvc.Name) - if strings.HasPrefix(genSvc.Name, origSvcPrefix) { - return strings.TrimPrefix(genSvc.Name, origSvcPrefix) + if !reflect.DeepEqual(running, newSvc) { + graphCli.Update(dag, running, newSvc, inDataContext4G()) } - return genSvc.Name } diff --git a/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml b/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml index 19f781797f1..081ffee50ff 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml @@ -8350,8 +8350,10 @@ spec: type: object componentSelector: description: |- - Extends the ServiceSpec.Selector by allowing the specification of a component, to be used as a selector for the service. - Note that this and the `shardingSelector` are mutually exclusive and cannot be set simultaneously. + Extends the ServiceSpec.Selector by allowing the specification of components, to be used as a selector for the service. + + + If the `componentSelector` is set as a name of a sharding, the service will be exposed to all components in the sharding. type: string name: description: |- @@ -8390,12 +8392,6 @@ spec: maxLength: 25 pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ type: string - shardingSelector: - description: |- - Extends the ServiceSpec.Selector by allowing the specification of a sharding name, which is defined in - `cluster.spec.shardingSpecs[*].name`, to be used as a selector for the service. - Note that this and the `componentSelector` are mutually exclusive and cannot be set simultaneously. - type: string spec: description: |- Spec defines the behavior of a service. diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md index 2d227199eb3..5a365be5a2d 100644 --- a/docs/developer_docs/api-reference/cluster.md +++ b/docs/developer_docs/api-reference/cluster.md @@ -3083,20 +3083,6 @@ Service -shardingSelector
- -string - - - -(Optional) -

Extends the ServiceSpec.Selector by allowing the specification of a sharding name, which is defined in -cluster.spec.shardingSpecs[*].name, to be used as a selector for the service. -Note that this and the componentSelector are mutually exclusive and cannot be set simultaneously.

- - - - componentSelector
string @@ -3104,8 +3090,8 @@ string (Optional) -

Extends the ServiceSpec.Selector by allowing the specification of a component, to be used as a selector for the service. -Note that this and the shardingSelector are mutually exclusive and cannot be set simultaneously.

+

Extends the ServiceSpec.Selector by allowing the specification of components, to be used as a selector for the service.

+

If the componentSelector is set as a name of a sharding, the service will be exposed to all components in the sharding.

diff --git a/pkg/constant/flag.go b/pkg/constant/flag.go index 19207e4f3f8..76a06f1b129 100644 --- a/pkg/constant/flag.go +++ b/pkg/constant/flag.go @@ -26,11 +26,6 @@ const ( ) const ( - // ShardSvcAnnotationKey defines the feature gate of creating service for each shard. - // Sharding name defined in the annotation value, a set of Service defined in Cluster.Spec.Services with the ShardingSelector will be automatically generated for each shard when Cluster.Spec.ShardingSpecs[x].shards is not nil. - // Multiple sharding names are separated by ','. for example: "kubeblocks.io/enabled-shard-svc: proxy-shard,db-shard" - ShardSvcAnnotationKey = "kubeblocks.io/enabled-shard-svc" - // HostNetworkAnnotationKey defines the feature gate to enable the host-network for specified components or shardings. HostNetworkAnnotationKey = "kubeblocks.io/host-network"