Skip to content

Commit d144cac

Browse files
authored
feat: allows users to specify host ports when creating a cluster (#9892)
1 parent f932b2b commit d144cac

26 files changed

+1184
-389
lines changed

apis/apps/v1/types.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,42 @@ type ComponentNetwork struct {
252252
// +optional
253253
DNSPolicy *corev1.DNSPolicy `json:"dnsPolicy,omitempty"`
254254

255-
// Specifies the DNS parameters of a pod.
255+
// Specifies the DNS parameters of the pod.
256256
//
257257
// +optional
258258
DNSConfig *corev1.PodDNSConfig `json:"dnsConfig,omitempty"`
259+
260+
// HostPorts specifies the mapping of container ports to host ports.
261+
// The behavior varies based on the HostNetwork setting:
262+
//
263+
// 1. When HostNetwork is enabled:
264+
// - If this field is empty: All ports are automatically allocated by the host-port manager.
265+
// - If this field is specified:
266+
// a) Mappings for all ports defined in `cmpd.spec.hostNetwork` are MANDATORY.
267+
// b) Mappings for kbagent ports ("http", "streaming") are OPTIONAL.
268+
// You can explicitly map them here, or leave them omitted to be allocated by the host-port manager.
269+
//
270+
// 2. When HostNetwork is disabled:
271+
// It allows optional mapping for container ports to host ports.
272+
// - Mappings are restricted to ports defined in `cmpd.spec.runtime.containers.ports`.
273+
// - Any specified container ports not present in the runtime definition will be ignored.
274+
//
275+
// +optional
276+
HostPorts []HostPort `json:"hostPorts,omitempty"`
277+
}
278+
279+
type HostPort struct {
280+
// The name of the container port.
281+
//
282+
// +kubebuilder:validation:Required
283+
Name string `json:"name"`
284+
285+
// The port number of the host port.
286+
//
287+
// +kubebuilder:validation:Minimum=1
288+
// +kubebuilder:validation:Maximum=65535
289+
// +kubebuilder:validation:Required
290+
Port int32 `json:"port"`
259291
}
260292

261293
type Service struct {

apis/apps/v1/zz_generated.deepcopy.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/manager/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ func main() {
417417
client = multiClusterMgr.GetClient()
418418
}
419419

420-
if err := intctrlutil.InitHostPortManager(mgr.GetClient()); err != nil {
420+
if err := intctrlutil.InitDefaultHostPortManager(mgr.GetClient()); err != nil {
421421
setupLog.Error(err, "unable to init port manager")
422422
os.Exit(1)
423423
}

config/crd/bases/apps.kubeblocks.io_clusters.yaml

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2709,7 +2709,7 @@ spec:
27092709
description: Defines the network configuration for the Component.
27102710
properties:
27112711
dnsConfig:
2712-
description: Specifies the DNS parameters of a pod.
2712+
description: Specifies the DNS parameters of the pod.
27132713
properties:
27142714
nameservers:
27152715
description: |-
@@ -2774,6 +2774,40 @@ spec:
27742774
description: Host networking requested for this pod. Use
27752775
the host's network namespace.
27762776
type: boolean
2777+
hostPorts:
2778+
description: |-
2779+
HostPorts specifies the mapping of container ports to host ports.
2780+
The behavior varies based on the HostNetwork setting:
2781+
2782+
2783+
1. When HostNetwork is enabled:
2784+
- If this field is empty: All ports are automatically allocated by the host-port manager.
2785+
- If this field is specified:
2786+
a) Mappings for all ports defined in `cmpd.spec.hostNetwork` are MANDATORY.
2787+
b) Mappings for kbagent ports ("http", "streaming") are OPTIONAL.
2788+
You can explicitly map them here, or leave them omitted to be allocated by the host-port manager.
2789+
2790+
2791+
2. When HostNetwork is disabled:
2792+
It allows optional mapping for container ports to host ports.
2793+
- Mappings are restricted to ports defined in `cmpd.spec.runtime.containers.ports`.
2794+
- Any specified container ports not present in the runtime definition will be ignored.
2795+
items:
2796+
properties:
2797+
name:
2798+
description: The name of the container port.
2799+
type: string
2800+
port:
2801+
description: The port number of the host port.
2802+
format: int32
2803+
maximum: 65535
2804+
minimum: 1
2805+
type: integer
2806+
required:
2807+
- name
2808+
- port
2809+
type: object
2810+
type: array
27772811
type: object
27782812
offlineInstances:
27792813
description: |-
@@ -13959,7 +13993,7 @@ spec:
1395913993
description: Defines the network configuration for the Component.
1396013994
properties:
1396113995
dnsConfig:
13962-
description: Specifies the DNS parameters of a pod.
13996+
description: Specifies the DNS parameters of the pod.
1396313997
properties:
1396413998
nameservers:
1396513999
description: |-
@@ -14024,6 +14058,40 @@ spec:
1402414058
description: Host networking requested for this pod.
1402514059
Use the host's network namespace.
1402614060
type: boolean
14061+
hostPorts:
14062+
description: |-
14063+
HostPorts specifies the mapping of container ports to host ports.
14064+
The behavior varies based on the HostNetwork setting:
14065+
14066+
14067+
1. When HostNetwork is enabled:
14068+
- If this field is empty: All ports are automatically allocated by the host-port manager.
14069+
- If this field is specified:
14070+
a) Mappings for all ports defined in `cmpd.spec.hostNetwork` are MANDATORY.
14071+
b) Mappings for kbagent ports ("http", "streaming") are OPTIONAL.
14072+
You can explicitly map them here, or leave them omitted to be allocated by the host-port manager.
14073+
14074+
14075+
2. When HostNetwork is disabled:
14076+
It allows optional mapping for container ports to host ports.
14077+
- Mappings are restricted to ports defined in `cmpd.spec.runtime.containers.ports`.
14078+
- Any specified container ports not present in the runtime definition will be ignored.
14079+
items:
14080+
properties:
14081+
name:
14082+
description: The name of the container port.
14083+
type: string
14084+
port:
14085+
description: The port number of the host port.
14086+
format: int32
14087+
maximum: 65535
14088+
minimum: 1
14089+
type: integer
14090+
required:
14091+
- name
14092+
- port
14093+
type: object
14094+
type: array
1402714095
type: object
1402814096
offlineInstances:
1402914097
description: |-

config/crd/bases/apps.kubeblocks.io_components.yaml

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2488,7 +2488,7 @@ spec:
24882488
description: Defines the network configuration for the Component.
24892489
properties:
24902490
dnsConfig:
2491-
description: Specifies the DNS parameters of a pod.
2491+
description: Specifies the DNS parameters of the pod.
24922492
properties:
24932493
nameservers:
24942494
description: |-
@@ -2553,6 +2553,40 @@ spec:
25532553
description: Host networking requested for this pod. Use the host's
25542554
network namespace.
25552555
type: boolean
2556+
hostPorts:
2557+
description: |-
2558+
HostPorts specifies the mapping of container ports to host ports.
2559+
The behavior varies based on the HostNetwork setting:
2560+
2561+
2562+
1. When HostNetwork is enabled:
2563+
- If this field is empty: All ports are automatically allocated by the host-port manager.
2564+
- If this field is specified:
2565+
a) Mappings for all ports defined in `cmpd.spec.hostNetwork` are MANDATORY.
2566+
b) Mappings for kbagent ports ("http", "streaming") are OPTIONAL.
2567+
You can explicitly map them here, or leave them omitted to be allocated by the host-port manager.
2568+
2569+
2570+
2. When HostNetwork is disabled:
2571+
It allows optional mapping for container ports to host ports.
2572+
- Mappings are restricted to ports defined in `cmpd.spec.runtime.containers.ports`.
2573+
- Any specified container ports not present in the runtime definition will be ignored.
2574+
items:
2575+
properties:
2576+
name:
2577+
description: The name of the container port.
2578+
type: string
2579+
port:
2580+
description: The port number of the host port.
2581+
format: int32
2582+
maximum: 65535
2583+
minimum: 1
2584+
type: integer
2585+
required:
2586+
- name
2587+
- port
2588+
type: object
2589+
type: array
25562590
type: object
25572591
offlineInstances:
25582592
description: |-

controllers/apps/cluster/suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ var _ = BeforeSuite(func() {
162162
viper.SetDefault("HOST_PORT_CM_NAME", "kubeblocks-host-ports")
163163
viper.SetDefault(constant.EnableRBACManager, true)
164164

165-
err = intctrlutil.InitHostPortManager(k8sClient)
165+
err = intctrlutil.InitDefaultHostPortManager(k8sClient)
166166
Expect(err).ToNot(HaveOccurred())
167167

168168
err = (&apps.ClusterDefinitionReconciler{

controllers/apps/component/component_controller.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
151151
&componentMonitorContainerTransformer{},
152152
// allocate ports for host-network component
153153
&componentHostNetworkTransformer{},
154+
// map for container ports to host ports
155+
&componentHostPortTransformer{},
154156
// handle component services
155157
&componentServiceTransformer{},
156158
// handle component system accounts

controllers/apps/component/suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ var _ = BeforeSuite(func() {
168168
viper.SetDefault("HOST_PORT_CM_NAME", "kubeblocks-host-ports")
169169
viper.SetDefault(constant.EnableRBACManager, true)
170170

171-
err = intctrlutil.InitHostPortManager(k8sClient)
171+
err = intctrlutil.InitDefaultHostPortManager(k8sClient)
172172
Expect(err).ToNot(HaveOccurred())
173173

174174
err = (&apps.ComponentDefinitionReconciler{

controllers/apps/component/transformer_component_deletion.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ func (t *componentDeletionTransformer) deleteCompResources(transCtx *componentTr
147147
}
148148

149149
// release the allocated host-network ports for the component
150-
pm := intctrlutil.GetPortManager()
150+
pm := intctrlutil.GetPortManager(comp.Spec.Network)
151151
if err = pm.ReleaseByPrefix(comp.Name); err != nil {
152152
return intctrlutil.NewRequeueError(time.Second*1, fmt.Sprintf("release host ports for component %s error: %s", comp.Name, err.Error()))
153153
}

controllers/apps/component/transformer_component_hostnetwork.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,18 @@ func (t *componentHostNetworkTransformer) Transform(ctx graph.TransformContext,
4343
}
4444

4545
synthesizedComp := transCtx.SynthesizeComponent
46-
ports, err := allocateHostPorts(synthesizedComp)
46+
ports, err := t.allocateHostPorts(synthesizedComp)
4747
if err != nil {
4848
return err
4949
}
5050

5151
comp := transCtx.Component
52-
updateObjectsWithAllocatedPorts(synthesizedComp, comp, ports)
52+
t.updateObjectsWithAllocatedPorts(synthesizedComp, comp, ports)
5353

5454
return nil
5555
}
5656

57-
func allocateHostPorts(synthesizedComp *component.SynthesizedComponent) (map[string]map[string]int32, error) {
57+
func (t *componentHostNetworkTransformer) allocateHostPorts(synthesizedComp *component.SynthesizedComponent) (map[string]map[string]int32, error) {
5858
ports := map[string]map[string]bool{}
5959
for _, c := range synthesizedComp.HostNetwork.ContainerPorts {
6060
for _, p := range c.Ports {
@@ -65,18 +65,18 @@ func allocateHostPorts(synthesizedComp *component.SynthesizedComponent) (map[str
6565
}
6666
}
6767

68-
pm := intctrlutil.GetPortManager()
68+
pm := intctrlutil.GetPortManager(synthesizedComp.Network)
6969
needAllocate := func(c string, p string) bool {
7070
containerPorts, ok := ports[c]
7171
if !ok {
7272
return false
7373
}
7474
return containerPorts[p]
7575
}
76-
return allocateHostPortsWithFunc(pm, synthesizedComp, needAllocate)
76+
return t.allocateHostPortsWithFunc(pm, synthesizedComp, needAllocate)
7777
}
7878

79-
func allocateHostPortsWithFunc(pm *intctrlutil.PortManager, synthesizedComp *component.SynthesizedComponent,
79+
func (t *componentHostNetworkTransformer) allocateHostPortsWithFunc(pm intctrlutil.PortManager, synthesizedComp *component.SynthesizedComponent,
8080
needAllocate func(string, string) bool) (map[string]map[string]int32, error) {
8181
ports := map[string]map[string]int32{}
8282
insert := func(c, pk string, pv int32) {
@@ -87,7 +87,7 @@ func allocateHostPortsWithFunc(pm *intctrlutil.PortManager, synthesizedComp *com
8787
}
8888
for _, c := range synthesizedComp.PodSpec.Containers {
8989
for _, p := range c.Ports {
90-
portKey := intctrlutil.BuildHostPortName(synthesizedComp.ClusterName, synthesizedComp.Name, c.Name, p.Name)
90+
portKey := pm.PortKey(synthesizedComp.ClusterName, synthesizedComp.Name, c.Name, p.Name)
9191
if needAllocate(c.Name, p.Name) {
9292
port, err := pm.AllocatePort(portKey)
9393
if err != nil {
@@ -104,7 +104,7 @@ func allocateHostPortsWithFunc(pm *intctrlutil.PortManager, synthesizedComp *com
104104
return ports, nil
105105
}
106106

107-
func updateObjectsWithAllocatedPorts(synthesizedComp *component.SynthesizedComponent,
107+
func (t *componentHostNetworkTransformer) updateObjectsWithAllocatedPorts(synthesizedComp *component.SynthesizedComponent,
108108
comp *appsv1.Component, ports map[string]map[string]int32) {
109109
synthesizedComp.PodSpec.HostNetwork = true
110110
if comp.Spec.Network != nil && comp.Spec.Network.DNSPolicy != nil {

0 commit comments

Comments
 (0)