domino_admin_toolkit.checks.test_nginx_ingress module
nginx-ingress data-plane health checks.
Two golden checks sharing this file:
test_nginx_response_codes— per-(ingress, service) HTTP response-code mix over a recent window, the same signal an SRE reads off the operations-grafana “NGINX Ingress controller” dashboard. Survives high-cardinality customer installs via a server-sidetopkcap plus a synthetic(other)rollup row for the suppressed tail.test_nginx_config_reload— per-controller-pod config-reload status. When nginx-ingress fails to apply a new config (broken annotation, malformed Ingress, missing Secret) the pod stays Ready and silently serves the previous good config; the only signal is this gauge.
Both metrics are stable counters/gauges from upstream kubernetes/ingress-nginx and are scraped
on every standard Domino install.
- pydantic model domino_admin_toolkit.checks.test_nginx_ingress.NginxConfigReloadAnalyzer
Bases:
AnalyzerBase[ConfigReloadRow]FAILs any controller pod whose last config reload failed (gauge == 0).
- Fields:
- analyze(data)
Analyzes one row and returns a list of CheckResult instances.
- Return type:
- Args:
data: One row dict (
TRow). The Runner calls this once per DataFrame row.- Returns:
List[CheckResult]: A list containing the results of the analysis.
- Raises:
NotImplementedError: If this method is not implemented by subclasses.
- name: ClassVar[str] = 'NginxConfigReloadAnalyzer'
- pydantic model domino_admin_toolkit.checks.test_nginx_ingress.NginxResponseCodeAnalyzer
Bases:
AnalyzerBase[ResponseCodeRow]Flags (ingress, service) rows whose 5xx rate is high enough to matter (rate AND count).
- analyze(data)
Analyzes one row and returns a list of CheckResult instances.
- Return type:
- Args:
data: One row dict (
TRow). The Runner calls this once per DataFrame row.- Returns:
List[CheckResult]: A list containing the results of the analysis.
- Raises:
NotImplementedError: If this method is not implemented by subclasses.
- name: ClassVar[str] = 'NginxResponseCodeAnalyzer'
- domino_admin_toolkit.checks.test_nginx_ingress.nginx_reload_data(prometheus_client_v2)
Collect per-controller-pod nginx-ingress config-reload status from Prometheus.
- Return type:
- domino_admin_toolkit.checks.test_nginx_ingress.nginx_response_data(prometheus_client_v2)
Collect per-(ingress, service) nginx-ingress response-code counts from Prometheus.
- Return type:
- domino_admin_toolkit.checks.test_nginx_ingress.test_nginx_config_reload(nginx_reload_data, runner)
- Description: Reports each nginx-ingress controller pod’s last config-reload status. When the
controller fails to apply a new config (broken annotation, malformed Ingress, missing referenced Secret) the pod stays Ready and silently serves the previous good config — nothing else in the toolkit or the alert set notices.
- Failure Conditions: Any controller pod’s nginx_ingress_controller_config_last_reload_successful
gauge is 0 (last reload failed).
- Troubleshooting Steps:
Identify the controller pod from the output table.
Inspect controller logs for the reload error: kubectl logs -n <platform-namespace> <controller-pod> | grep -i reload.
Look for a recently applied Ingress/annotation/Secret change that the controller rejected.
- Resolution Steps:
Fix or revert the offending Ingress resource, annotation, or missing Secret.
The controller reloads automatically once the config is valid; confirm the gauge returns to 1.
Required Permissions: K8s cluster access (kubectl), Grafana read access. See also:
test_nginx_ingress.py::test_nginx_response_codes — a stale-config controller can show up there as unexpected 4xx/5xx for routes the new config would have fixed.
test_deployment_replicas.py — confirms the controller deployment itself is healthy.
test_container_restarts.py[platform_namespace] — a crashlooping controller is a different failure mode from a failed reload.
info/test_platform_logs.py[nginx-ingress-controller-controller] — raw controller logs.
- domino_admin_toolkit.checks.test_nginx_ingress.test_nginx_response_codes(nginx_response_data, runner)
- Description: Surfaces the per-(ingress, service) HTTP response-code mix (2xx/3xx/4xx/5xx) over
- the last hour from the nginx-ingress controller — the same signal an SRE reads off the
“NGINX Ingress controller” Grafana dashboard, captured into the support bundle.
High-cardinality installs are capped server-side with a topk; the suppressed tail is rolled up into an “(other)” row so a 5xx spike hiding beyond the cap still surfaces.
- Failure Conditions: An (ingress, service) — or the suppressed-tail rollup — exceeds the 5xx
rate threshold (default 5%) AND the 5xx count floor (default 10) over the window.
- Troubleshooting Steps:
Identify the failing (ingress, service) from the output table.
Open the “NGINX Ingress controller” Grafana dashboard, filter to that ingress/namespace, and inspect the per-status breakdown over a wider window.
Check the backing service’s pods: kubectl get pods -n <namespace> -l <service-selector>.
Review the service’s own logs/health — nginx 5xx usually mean the upstream is failing, not nginx itself.
- Resolution Steps:
Restore the unhealthy backing service (scale up, fix crashloop, check readiness).
If the rollup row fired, filter Grafana by namespace to locate the suppressed offender.
For 4xx-heavy rows, check client/auth misconfiguration rather than service health.
Required Permissions: K8s cluster access (kubectl), Grafana read access. See also:
test_nginx_ingress.py::test_nginx_config_reload — controller silently serving a stale config can masquerade as upstream errors here.
test_deployment_replicas.py — a missing/under-scaled backing deployment is the most common root cause of a 5xx row.
test_container_restarts.py[platform_namespace] — crashlooping upstream pods produce 5xx.
test_certificate_expiration.py — TLS-layer failures present differently; rule them out.
info/test_platform_logs.py[nginx-ingress-controller-controller] — raw controller logs.