Kubernetes (Helm)
The ingress controller sees every whistleblower's IP address. The chart
(charts/openwhistle/) sets
nginx.ingress.kubernetes.io/enable-access-log: "false" on its Ingress. It also
sets the bundled nginx's rate limit: limit-rps: "10",
limit-burst-multiplier: "3", a burst of 30. It raises
proxy-body-size to 55m, like the bundled nginx; ingress-nginx
otherwise refuses any upload over 1 MB.
The chart bundles no PostgreSQL and no Redis: set secrets.databaseUrl and
secrets.redisUrl to your own. A helm upgrade that changes a value
restarts the pods; with autoscaling.enabled the HPA alone sets the replica count.
- Your own
ingress.annotationsare merged with it; do not set it tonull. - Required:
error-log-level: critin the controller ConfigMap. Belowcrit, ingress-nginx logs every rate-limited request and upstream error with the client's IP address. - A rate-limited request gets
503, not429, unless the controller ConfigMap setslimit-req-status-code: "429"(controller-wide). - The limit is per peer address. Behind a load balancer the controller must see the real client, or every reporter shares one budget:
- L4 (TCP, SNAT): proxy protocol (
use-proxy-protocol: "true"in the controller ConfigMap, and on the load balancer), orexternalTrafficPolicy: Localon the controller Service. - L7 (HTTP):
use-forwarded-headers: "true"together withproxy-real-ip-cidrset to the load balancer's range. Without that range, any client sends its ownX-Forwarded-Forand escapes the limit.
- L4 (TCP, SNAT): proxy protocol (
- ingress-nginx always forwards
X-Forwarded-ForandX-Real-IP. OpenWhistle drops them, and the peer address, in its first middleware. The admin dashboard still warns that the proxy knows the addresses. - Other controllers (Traefik: access log off unless enabled): check their logging.
With several replicas, only the pod that wins the race to create the setup token logs it:
kubectl logs -l app.kubernetes.io/name=openwhistle | grep "Setup token" finds
it. Setting secrets.setupToken (chart) / SETUP_TOKEN avoids the
hunt: every replica uses that value.
A setting from the configuration table without a
values.yaml key goes into extraEnv as NAME: value
(for example SECURE_COOKIES: "false"). Secrets belong in secrets.