Skip to content

fix(chart): proxy service honors service.nodePort#150

Open
kamir wants to merge 2 commits into
KafScale:mainfrom
kamir:pr/proxy-honor-nodeport
Open

fix(chart): proxy service honors service.nodePort#150
kamir wants to merge 2 commits into
KafScale:mainfrom
kamir:pr/proxy-honor-nodeport

Conversation

@kamir

@kamir kamir commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Problem

The proxy Service template did not render spec.ports[0].nodePort. With
proxy.service.type=NodePort, Kubernetes then assigns a random node port, so a
fixed host-to-node-port mapping (for example a kind hostPort: 9092 -> containerPort: 30092 mapping) can never reach the proxy. Without a fixed
nodePort, Kubernetes assigns a random one and a pinned host:port mapping never
reaches the proxy.

Fix

Render nodePort on the kafka port when type == NodePort and
proxy.service.nodePort is set; default empty keeps Kubernetes auto-assignment.
This lets operators pin the proxy to a known NodePort, which matters because the
proxy is the single Kafka entrypoint. Default render is byte-identical to
pre-PR; the key is opt-in.

Test

Added test/chart/proxy-nodeport_test.sh, a self-contained chart template test
(helm only, no plugins, no cluster). It runs helm template with three
value-sets and asserts the rendered nodePort:

Case Values Expected
1 type=NodePort, nodePort=30092 renders nodePort: 30092
2 type=NodePort, nodePort="" line omitted (Kubernetes auto-assigns)
3 type=LoadBalancer, nodePort=30092 line suppressed (only NodePort honours it)

Wired into the Makefile as make test-chart-proxy-nodeport:

==> chart proxy nodePort template test
PASS: NodePort + nodePort=30092 renders the value (nodePort="30092")
PASS: NodePort + empty nodePort omits the line (nodePort="")
PASS: LoadBalancer + nodePort=30092 suppresses the line (nodePort="")
==> chart proxy nodePort template test passed

Reproducible evidence

Case 1, NodePort with a pinned nodePort:

$ helm template kafscale deploy/helm/kafscale \
    --show-only templates/proxy-service.yaml \
    --set proxy.enabled=true \
    --set proxy.service.type=NodePort \
    --set proxy.service.nodePort=30092
spec:
  type: NodePort
  ...
  ports:
    - name: kafka
      port: 9092
      targetPort: kafka
      protocol: TCP
      nodePort: 30092

Case 2, NodePort with the default empty nodePort (the line is absent, so
Kubernetes auto-assigns):

$ helm template kafscale deploy/helm/kafscale \
    --show-only templates/proxy-service.yaml \
    --set proxy.enabled=true \
    --set proxy.service.type=NodePort
  ports:
    - name: kafka
      port: 9092
      targetPort: kafka
      protocol: TCP

Default render (no overrides) contains zero nodePort lines, confirming the
default is unchanged from before this PR.

In practice this is the mechanism behind a fixed host:port entrypoint: a proxy
Service pinned to nodePort 30092, mapped to a host port (for example
9092/9292), is what makes a Kafka client able to reach the proxy at a known
host:port instead of a random node port that changes every install.

Scope

This change is proxy-only, because the proxy is the single Kafka entrypoint that
external clients connect to. The console and mcp services also expose
service.type but are left as-is and tracked separately; widening this
chart-wide is out of scope for this fix.

README

Documented proxy.service.nodePort under a new "Proxy Service" section in the
chart README, including the valid NodePort range 30000-32767 (a value outside
it renders but is rejected at apply time).

Part of a small series upstreaming deployment-hardening deltas we currently
carry.

Scalytics and others added 2 commits June 4, 2026 19:31
The proxy Service template did not render spec.ports[0].nodePort, so with
type=NodePort Kubernetes assigned a random node port and a fixed host:port
mapping (e.g. a kind host 9092 -> 30092 mapping) could never reach the proxy.
Render nodePort when type==NodePort and a nodePort is set; default empty keeps
the auto-assign behaviour. Lets the proxy be pinned to a known NodePort, which
matters because the proxy is the single Kafka entrypoint.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a self-contained chart template test for the proxy Service nodePort
behaviour (test/chart/proxy-nodeport_test.sh), wired as
`make test-chart-proxy-nodeport`. It runs `helm template` with three
value-sets and asserts the rendered nodePort:

  1. type=NodePort + nodePort=30092 -> renders nodePort: 30092
  2. type=NodePort + empty           -> line omitted (auto-assign)
  3. type=LoadBalancer + value       -> line suppressed

helm only, no plugins, no cluster.

Document proxy.service.nodePort in the chart README under a new
"Proxy Service" section, including the valid NodePort range 30000-32767.
Note in values.yaml that the field is scoped to the proxy (the single
Kafka entrypoint); console/mcp expose service.type but are left as-is and
tracked separately.

Default render is unchanged; the field is opt-in.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant