Skip to content

Commit 99ab33a

Browse files
feat(helm): add configurable NodePort to router service (#875)
* feat(helm): add configurable NodePort to router service Add optional `routerSpec.nodePort` field that, when set alongside `routerSpec.serviceType: NodePort`, pins the NodePort to a fixed value instead of letting Kubernetes assign a random one on every helm upgrade. Closes #763 Signed-off-by: Keyu Chen <54015474+keyuchen21@users.noreply.github.com> * fix(helm): move nodePort schema to routerSpec and use truthiness check - Move nodePort JSON schema property from servingEngineSpec to routerSpec where it belongs - Replace hasKey check with truthiness check in service-router.yaml to correctly handle nodePort: null Signed-off-by: Keyu Chen <54015474+keyuchen21@users.noreply.github.com> * docs(helm): document nodePort field in Router Configuration table Add routerSpec.nodePort entry to the Helm README to document the configurable NodePort introduced for the router service. Signed-off-by: Keyu_Chen <54015474+km5ar@users.noreply.github.com> --------- Signed-off-by: Keyu Chen <54015474+keyuchen21@users.noreply.github.com> Signed-off-by: Keyu_Chen <54015474+km5ar@users.noreply.github.com> Co-authored-by: Keyu_Chen <54015474+km5ar@users.noreply.github.com> Co-authored-by: Rui Zhang <51696593+ruizhang0101@users.noreply.github.com>
1 parent 80e2f84 commit 99ab33a

4 files changed

Lines changed: 224 additions & 0 deletions

File tree

helm/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ This table documents all available configuration values for the Production Stack
216216
| `routerSpec.containerPort` | integer | `8000` | Port the router container is listening on |
217217
| `routerSpec.serviceType` | string | `"ClusterIP"` | Kubernetes service type for the router |
218218
| `routerSpec.serviceAnnotations` | map | `{}` | Service annotations for LoadBalancer/NodePort |
219+
| `routerSpec.nodePort` | integer | `-` | (Optional) Fixed NodePort for the router service when `serviceType` is `NodePort`. If unset, Kubernetes assigns a random port (30000-32767). |
219220
| `routerSpec.servicePort` | integer | `80` | Port the router service will listen on |
220221
| `routerSpec.serviceDiscovery` | string | `"k8s"` | Service discovery mode ("k8s" or "static") |
221222
| `routerSpec.k8sServiceDiscoveryType` | string | `"pod-ip"` | Service discovery Type ("pod-ip" or "service-name") if serviceDiscovery is "k8s" |

helm/templates/service-router.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ spec:
1717
port: {{ .Values.routerSpec.servicePort }}
1818
targetPort: {{ .Values.routerSpec.containerPort }}
1919
protocol: TCP
20+
{{- if and (eq .Values.routerSpec.serviceType "NodePort") .Values.routerSpec.nodePort }}
21+
nodePort: {{ .Values.routerSpec.nodePort }}
22+
{{- end }}
2023
- name: "lmcache-port"
2124
port: 9000
2225
targetPort: lmcache-port

helm/values.schema.json

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,12 @@
759759
"servicePort": {
760760
"type": "integer"
761761
},
762+
"nodePort": {
763+
"type": "integer",
764+
"description": "Fixed NodePort for the router service when serviceType is NodePort. If unset, Kubernetes assigns a random port.",
765+
"minimum": 30000,
766+
"maximum": 32767
767+
},
762768
"serviceDiscovery": {
763769
"type": "string",
764770
"description": "Service discovery mode. Available values: k8s or static.",
@@ -846,6 +852,217 @@
846852
}
847853
}
848854
}
855+
},
856+
"cacheserverSpec": {
857+
"type": "object",
858+
"description": "Configuration for the LMCache cache server deployment",
859+
"properties": {
860+
"repository": {
861+
"type": "string",
862+
"description": "Docker image repository for the cache server"
863+
},
864+
"tag": {
865+
"type": "string",
866+
"description": "Docker image tag for the cache server"
867+
},
868+
"imagePullSecrets": {
869+
"type": "array",
870+
"description": "Image pull secrets for private container registries",
871+
"items": {
872+
"type": "object",
873+
"properties": {
874+
"name": {
875+
"type": "string"
876+
}
877+
},
878+
"required": [
879+
"name"
880+
]
881+
}
882+
},
883+
"replicaCount": {
884+
"type": "integer",
885+
"description": "Number of replicas for the cache server pod"
886+
},
887+
"containerPort": {
888+
"type": "integer",
889+
"description": "Port the cache server container is listening on"
890+
},
891+
"servicePort": {
892+
"type": "integer",
893+
"description": "Port the cache server service will listen on"
894+
},
895+
"serviceType": {
896+
"type": "string",
897+
"description": "Kubernetes service type for the cache server"
898+
},
899+
"serde": {
900+
"type": "string",
901+
"description": "Serialization/deserialization format for the cache server"
902+
},
903+
"labels": {
904+
"type": "object",
905+
"description": "Customized labels for the cache server deployment",
906+
"properties": {
907+
"environment": {
908+
"type": "string"
909+
},
910+
"release": {
911+
"type": "string"
912+
}
913+
}
914+
},
915+
"podAnnotations": {
916+
"type": "object",
917+
"description": "Annotations to add to the cache server pods",
918+
"additionalProperties": {
919+
"type": "string"
920+
}
921+
},
922+
"strategy": {
923+
"type": "object",
924+
"description": "Deployment strategy for the cache server pods",
925+
"additionalProperties": true
926+
},
927+
"maxUnavailablePodDisruptionBudget": {
928+
"type": "string",
929+
"description": "Configuration for the PodDisruptionBudget maxUnavailable field"
930+
},
931+
"tolerations": {
932+
"type": "array",
933+
"description": "Tolerations configuration for the cache server pods",
934+
"items": {
935+
"type": "object",
936+
"additionalProperties": true
937+
}
938+
},
939+
"nodeSelectorTerms": {
940+
"type": "array",
941+
"description": "Node selector terms. Ignored if affinity is specified.",
942+
"items": {
943+
"type": "object",
944+
"additionalProperties": true
945+
}
946+
},
947+
"runtimeClassName": {
948+
"type": "string",
949+
"description": "RuntimeClassName configuration for the cache server pods"
950+
},
951+
"schedulerName": {
952+
"type": "string",
953+
"description": "SchedulerName configuration for the cache server pods"
954+
},
955+
"priorityClassName": {
956+
"type": "string",
957+
"description": "Priority class for the cache server pods"
958+
},
959+
"securityContext": {
960+
"type": "object",
961+
"description": "Pod-level security context configuration",
962+
"additionalProperties": true
963+
},
964+
"containerSecurityContext": {
965+
"type": "object",
966+
"description": "Container-level security context configuration",
967+
"additionalProperties": true
968+
},
969+
"affinity": {
970+
"type": "object",
971+
"description": "Affinity configuration. If specified, takes precedence over nodeSelectorTerms.",
972+
"additionalProperties": true
973+
},
974+
"resources": {
975+
"type": "object",
976+
"description": "Resource requests and limits for the cache server container",
977+
"properties": {
978+
"requests": {
979+
"type": "object",
980+
"properties": {
981+
"cpu": {
982+
"type": "string"
983+
},
984+
"memory": {
985+
"type": "string"
986+
}
987+
}
988+
},
989+
"limits": {
990+
"type": "object",
991+
"properties": {
992+
"cpu": {
993+
"type": "string"
994+
},
995+
"memory": {
996+
"type": "string"
997+
}
998+
}
999+
}
1000+
}
1001+
},
1002+
"startupProbe": {
1003+
"type": "object",
1004+
"description": "Configuration for the startup probe",
1005+
"properties": {
1006+
"initialDelaySeconds": {
1007+
"type": "integer"
1008+
},
1009+
"periodSeconds": {
1010+
"type": "integer"
1011+
},
1012+
"failureThreshold": {
1013+
"type": "integer"
1014+
},
1015+
"timeoutSeconds": {
1016+
"type": "integer"
1017+
},
1018+
"httpGet": {
1019+
"type": "object",
1020+
"properties": {
1021+
"path": {
1022+
"type": "string"
1023+
},
1024+
"port": {
1025+
"type": "integer"
1026+
}
1027+
}
1028+
}
1029+
}
1030+
},
1031+
"livenessProbe": {
1032+
"type": "object",
1033+
"description": "Configuration for the liveness probe",
1034+
"properties": {
1035+
"initialDelaySeconds": {
1036+
"type": "integer"
1037+
},
1038+
"periodSeconds": {
1039+
"type": "integer"
1040+
},
1041+
"failureThreshold": {
1042+
"type": "integer"
1043+
},
1044+
"timeoutSeconds": {
1045+
"type": "integer"
1046+
},
1047+
"httpGet": {
1048+
"type": "object",
1049+
"properties": {
1050+
"path": {
1051+
"type": "string"
1052+
},
1053+
"port": {
1054+
"type": "integer"
1055+
}
1056+
}
1057+
}
1058+
}
1059+
}
1060+
},
1061+
"required": [
1062+
"repository",
1063+
"tag",
1064+
"containerPort"
1065+
]
8491066
}
8501067
}
8511068
}

helm/values.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,9 @@ routerSpec:
418418
serviceType: ClusterIP
419419
# -- Service annotations if you use a LoadBalancer or NodePort service type
420420
serviceAnnotations: {}
421+
# -- Fixed NodePort for the router service when serviceType is NodePort.
422+
# -- If not set, Kubernetes assigns a random port (range 30000-32767).
423+
# nodePort: 30080
421424

422425
# -- Service port
423426
servicePort: 80

0 commit comments

Comments
 (0)