Skip to content
3 changes: 3 additions & 0 deletions .changes/unreleased/Added-20250512-140119.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kind: Added
body: '`additionalPort` can be specified in GRPC Service spec to create a Service with 2 ports'
time: 2025-05-12T14:01:19.020259248+02:00
3 changes: 3 additions & 0 deletions .changes/unreleased/Added-20250512-143551.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kind: Added
body: Default 2135 port on the GRPC service can now be overridden
time: 2025-05-12T14:35:51.255373275+02:00
11 changes: 6 additions & 5 deletions api/v1alpha1/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ const (
DefaultDomainName = "cluster.local"
DNSDomainAnnotation = "dns.domain"

GRPCPort = 2135
GRPCServicePortName = "grpc"
GRPCProto = "grpc://"
GRPCSProto = "grpcs://"
GRPCServiceFQDNFormat = "%s-grpc.%s.svc.%s"
GRPCPort = 2135
GRPCServicePortName = "grpc"
GRPCServiceAdditionalPortName = "additional-grpc"
GRPCProto = "grpc://"
GRPCSProto = "grpcs://"
GRPCServiceFQDNFormat = "%s-grpc.%s.svc.%s"

InterconnectPort = 19001
InterconnectServicePortName = "interconnect"
Expand Down
3 changes: 3 additions & 0 deletions api/v1alpha1/service_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ type TLSConfiguration struct {
type GRPCService struct {
Service `json:""`

AdditionalPort int32 `json:"additionalPort,omitempty"`
Port int32 `json:"port,omitempty"`

TLSConfiguration *TLSConfiguration `json:"tls,omitempty"`
ExternalHost string `json:"externalHost,omitempty"`
ExternalPort int32 `json:"externalPort,omitempty"`
Expand Down
6 changes: 6 additions & 0 deletions deploy/ydb-operator/crds/database.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4073,6 +4073,9 @@ spec:
additionalProperties:
type: string
type: object
additionalPort:
format: int32
type: integer
externalHost:
type: string
externalPort:
Expand Down Expand Up @@ -4103,6 +4106,9 @@ spec:
description: IPFamilyPolicy represents the dual-stack-ness
requested or required by a Service
type: string
port:
format: int32
type: integer
tls:
properties:
CA:
Expand Down
6 changes: 6 additions & 0 deletions deploy/ydb-operator/crds/databasenodeset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2685,6 +2685,9 @@ spec:
additionalProperties:
type: string
type: object
additionalPort:
format: int32
type: integer
externalHost:
type: string
externalPort:
Expand Down Expand Up @@ -2715,6 +2718,9 @@ spec:
description: IPFamilyPolicy represents the dual-stack-ness
requested or required by a Service
type: string
port:
format: int32
type: integer
tls:
properties:
CA:
Expand Down
6 changes: 6 additions & 0 deletions deploy/ydb-operator/crds/remotedatabasenodeset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2686,6 +2686,9 @@ spec:
additionalProperties:
type: string
type: object
additionalPort:
format: int32
type: integer
externalHost:
type: string
externalPort:
Expand Down Expand Up @@ -2716,6 +2719,9 @@ spec:
description: IPFamilyPolicy represents the dual-stack-ness
requested or required by a Service
type: string
port:
format: int32
type: integer
tls:
properties:
CA:
Expand Down
6 changes: 6 additions & 0 deletions deploy/ydb-operator/crds/remotestoragenodeset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2713,6 +2713,9 @@ spec:
additionalProperties:
type: string
type: object
additionalPort:
format: int32
type: integer
externalHost:
type: string
externalPort:
Expand Down Expand Up @@ -2743,6 +2746,9 @@ spec:
description: IPFamilyPolicy represents the dual-stack-ness
requested or required by a Service
type: string
port:
format: int32
type: integer
tls:
properties:
CA:
Expand Down
6 changes: 6 additions & 0 deletions deploy/ydb-operator/crds/storage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5214,6 +5214,9 @@ spec:
additionalProperties:
type: string
type: object
additionalPort:
format: int32
type: integer
externalHost:
type: string
externalPort:
Expand Down Expand Up @@ -5244,6 +5247,9 @@ spec:
description: IPFamilyPolicy represents the dual-stack-ness
requested or required by a Service
type: string
port:
format: int32
type: integer
tls:
properties:
CA:
Expand Down
6 changes: 6 additions & 0 deletions deploy/ydb-operator/crds/storagenodeset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2712,6 +2712,9 @@ spec:
additionalProperties:
type: string
type: object
additionalPort:
format: int32
type: integer
externalHost:
type: string
externalPort:
Expand Down Expand Up @@ -2742,6 +2745,9 @@ spec:
description: IPFamilyPolicy represents the dual-stack-ness
requested or required by a Service
type: string
port:
format: int32
type: integer
tls:
properties:
CA:
Expand Down
75 changes: 75 additions & 0 deletions internal/controllers/storage/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,5 +305,80 @@ var _ = Describe("Storage controller medium tests", func() {
By("check that --auth-token-file arg was added to Statefulset template...")
Eventually(checkAuthTokenArgs, test.Timeout, test.Interval).ShouldNot(HaveOccurred())
})

By("Checking overriding port value in GRPC Service...", func() {
storage := v1alpha1.Storage{}
Expect(k8sClient.Get(ctx, types.NamespacedName{
Name: testobjects.StorageName,
Namespace: testobjects.YdbNamespace,
}, &storage)).Should(Succeed())

storage.Spec.Service.GRPC.Port = 2137

Expect(k8sClient.Update(ctx, &storage)).Should(Succeed())

var svc corev1.Service
serviceName := fmt.Sprintf("%v-grpc", testobjects.StorageName)

Eventually(func(g Gomega) bool {
err := k8sClient.Get(ctx,
client.ObjectKey{
Name: serviceName,
Namespace: testobjects.YdbNamespace,
},
&svc,
)
if err != nil {
return false
}

ports := svc.Spec.Ports
g.Expect(len(ports)).To(Equal(1), "expected 1 port but got %d", len(ports))
g.Expect(ports[0].Name).To(Equal(v1alpha1.GRPCServicePortName))
g.Expect(ports[0].Port).To(Equal(storage.Spec.Service.GRPC.Port))
return true
}, test.Timeout, test.Interval).Should(BeTrue(),
"Service %s/%s should eventually have proper ports", testobjects.YdbNamespace, serviceName,
)
})

By("Checking additionalPort propagation in GRPC Service...", func() {
storage := v1alpha1.Storage{}
Expect(k8sClient.Get(ctx, types.NamespacedName{
Name: testobjects.StorageName,
Namespace: testobjects.YdbNamespace,
}, &storage)).Should(Succeed())

storage.Spec.Service.GRPC.Port = 2135
storage.Spec.Service.GRPC.AdditionalPort = 2136

Expect(k8sClient.Update(ctx, &storage)).Should(Succeed())

var svc corev1.Service
serviceName := fmt.Sprintf("%v-grpc", testobjects.StorageName)
Eventually(func(g Gomega) error {
err := k8sClient.Get(ctx,
client.ObjectKey{
Name: serviceName,
Namespace: testobjects.YdbNamespace,
},
&svc,
)
if err != nil {
return err
}

ports := svc.Spec.Ports
g.Expect(len(ports)).To(Equal(2), "expected 2 ports but got %d", len(ports))
g.Expect(ports[0].Port).To(Equal(int32(2135)))
g.Expect(ports[0].Name).To(Equal(v1alpha1.GRPCServicePortName))
g.Expect(ports[1].Port).To(Equal(storage.Spec.Service.GRPC.AdditionalPort))
g.Expect(ports[1].Name).To(Equal(v1alpha1.GRPCServiceAdditionalPortName))
g.Expect(ports[1].TargetPort.IntVal).To(Equal(storage.Spec.Service.GRPC.AdditionalPort))
return nil
}, test.Timeout, test.Interval).Should(Succeed(),
"Service %s/%s should eventually have proper ports", testobjects.YdbNamespace, serviceName,
)
})
})
})
27 changes: 23 additions & 4 deletions internal/resources/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,7 @@ func (b *StorageClusterBuilder) GetResourceBuilders(restConfig *rest.Config) []R
Labels: grpcServiceLabels,
SelectorLabels: storageSelectorLabels,
Annotations: b.Spec.Service.GRPC.AdditionalAnnotations,
Ports: []corev1.ServicePort{{
Name: api.GRPCServicePortName,
Port: api.GRPCPort,
}},
Ports: b.buildGrpcServicePorts(),
IPFamilies: b.Spec.Service.GRPC.IPFamilies,
IPFamilyPolicy: b.Spec.Service.GRPC.IPFamilyPolicy,
},
Expand Down Expand Up @@ -214,6 +211,28 @@ func (b *StorageClusterBuilder) GetResourceBuilders(restConfig *rest.Config) []R
)
}

func (b *StorageClusterBuilder) buildGrpcServicePorts() []corev1.ServicePort {
firstPort := int32(api.GRPCPort)

if b.Spec.Service.GRPC.Port != 0 {
firstPort = b.Spec.Service.GRPC.Port
}

ports := []corev1.ServicePort{{
Name: api.GRPCServicePortName,
Port: firstPort,
}}

if b.Spec.Service.GRPC.AdditionalPort != 0 {
ports = append(ports, corev1.ServicePort{
Name: api.GRPCServiceAdditionalPortName,
Port: b.Spec.Service.GRPC.AdditionalPort,
})
}

return ports
}

func (b *StorageClusterBuilder) getNodeSetBuilders() []ResourceBuilder {
var nodeSetBuilders []ResourceBuilder

Expand Down