Description:
When an Envoy Service is created with type: LoadBalancer and externalTrafficPolicy: Local (the Envoy Gateway default), Kubernetes allocates a health-check NodePort (healthCheckNodePort) from the cluster NodePort range. This port is used by external load balancers to determine which nodes have endpoints for the Service.
Because the port is auto-allocated, it's unpredictable across deployments and restarts, which makes it difficult to allowlist in network policies or firewall rules — operators have to open the entire NodePort range (e.g. 30000–32767) to reliably permit LB health-check traffic.
KubernetesServiceSpec already mirrors several corev1.ServiceSpec load-balancer fields (loadBalancerClass, allocateLoadBalancerNodePorts, loadBalancerSourceRanges, loadBalancerIP), but not healthCheckNodePort. Setting allocateLoadBalancerNodePorts: false closes the per-port NodePorts but has no effect on healthCheckNodePort, since Kubernetes treats those as separate allocators.
Proposal: add HealthCheckNodePort *int32 to KubernetesServiceSpec, forwarded to corev1.ServiceSpec.HealthCheckNodePort in the generated Service. CEL validation restricts it to type: LoadBalancer + externalTrafficPolicy: Local (matching Kubernetes' own rules). When unset, behavior is unchanged and Kubernetes continues to auto-allocate.
Use case context: the Tigera operator exposes KubernetesServiceSpec fields through its GatewayAPI CRD, and a downstream user asked for this capability specifically to allowlist a known port in network policies (tigera/operator#4718). The ask is general to anyone running Envoy Gateway on bare-metal, MetalLB, kube-vip, or similar environments where cloud load-balancer health probes reach pods via NodePort.
I have a PR ready and will open it shortly.
Relevant Links:
Description:
When an Envoy Service is created with
type: LoadBalancerandexternalTrafficPolicy: Local(the Envoy Gateway default), Kubernetes allocates a health-check NodePort (healthCheckNodePort) from the cluster NodePort range. This port is used by external load balancers to determine which nodes have endpoints for the Service.Because the port is auto-allocated, it's unpredictable across deployments and restarts, which makes it difficult to allowlist in network policies or firewall rules — operators have to open the entire NodePort range (e.g. 30000–32767) to reliably permit LB health-check traffic.
KubernetesServiceSpecalready mirrors severalcorev1.ServiceSpecload-balancer fields (loadBalancerClass,allocateLoadBalancerNodePorts,loadBalancerSourceRanges,loadBalancerIP), but nothealthCheckNodePort. SettingallocateLoadBalancerNodePorts: falsecloses the per-port NodePorts but has no effect onhealthCheckNodePort, since Kubernetes treats those as separate allocators.Proposal: add
HealthCheckNodePort *int32toKubernetesServiceSpec, forwarded tocorev1.ServiceSpec.HealthCheckNodePortin the generated Service. CEL validation restricts it totype: LoadBalancer+externalTrafficPolicy: Local(matching Kubernetes' own rules). When unset, behavior is unchanged and Kubernetes continues to auto-allocate.Use case context: the Tigera operator exposes
KubernetesServiceSpecfields through itsGatewayAPICRD, and a downstream user asked for this capability specifically to allowlist a known port in network policies (tigera/operator#4718). The ask is general to anyone running Envoy Gateway on bare-metal, MetalLB, kube-vip, or similar environments where cloud load-balancer health probes reach pods via NodePort.I have a PR ready and will open it shortly.
Relevant Links: