mirror of
https://github.com/lukaszraczylo/traefik-llmgateway.git
synced 2026-10-12 04:54:45 +00:00
fix(examples): make the metrics scrape example actually reachable
The VMServiceScrape example scraped Traefik's pods directly, so the request carried Host: <pod-ip>:<port>. Traefik evaluates a router's match rule before any middleware runs, and the only router in this file requires Host(`llm.example.com`). The scrape request never matched it, the llmgateway middleware never ran, and /metrics 404ed before the plugin ever saw the request. Add a second, Host-free IngressRoute matching PathPrefix(`/metrics`) and carrying the same middleware, so an in-cluster scraper reaches the route regardless of what Host header it sends. Document the reachability trade-off this introduces (this route is not Host-restricted, though /metrics stays gated by its own auth inside the plugin) and name the alternative fix the review also offered: relabelConfigs rewriting __address__ to the ingress hostname before the request is sent, keeping one Host-scoped router instead.
This commit is contained in:
@@ -210,6 +210,48 @@ spec:
|
|||||||
- name: llmgateway-dummy-backend
|
- name: llmgateway-dummy-backend
|
||||||
port: 80
|
port: 80
|
||||||
|
|
||||||
|
---
|
||||||
|
# A SEPARATE, Host-free IngressRoute for the metrics scrape (review fix,
|
||||||
|
# adversarial verification 2026-08-23): Traefik evaluates a router's
|
||||||
|
# match rule BEFORE any middleware runs, and the ONLY router above
|
||||||
|
# requires Host(`llm.example.com`). A VMServiceScrape/ServiceMonitor (below)
|
||||||
|
# reaches this Service through its cluster-internal DNS name or the pod
|
||||||
|
# IP directly, so the scrape request's Host header is never
|
||||||
|
# llm.example.com — it never matches that rule, the llmgateway
|
||||||
|
# middleware (and therefore /metrics itself) never runs, and the scrape
|
||||||
|
# 404s. PathPrefix, not Host, is deliberate here: this router exists
|
||||||
|
# specifically so an in-cluster scraper, addressing this Service by
|
||||||
|
# whatever internal name/IP it resolves to, still reaches the metrics
|
||||||
|
# route regardless of Host. /metrics is already gated by its own auth
|
||||||
|
# inside the plugin (an admin key, or metrics.allowedCIDRs — see
|
||||||
|
# ../README.md#metrics), so this being reachable without a Host match is
|
||||||
|
# not a second, unguarded door — but if your own Traefik instance fronts
|
||||||
|
# other Host-restricted routers on the SAME entryPoint, this route is
|
||||||
|
# reachable via any of THEIR hostnames too, not only in-cluster; narrow
|
||||||
|
# entryPoints below to an internal-only one, or add your own Host()
|
||||||
|
# match for your cluster's internal DNS name, if that reachability is
|
||||||
|
# broader than you want. The alternative the review that flagged this
|
||||||
|
# also named — keeping one Host-scoped router and instead using
|
||||||
|
# VMServiceScrape's own relabelConfigs to rewrite __address__ to
|
||||||
|
# llm.example.com before the request is sent — works too; this file uses
|
||||||
|
# the simpler of the two.
|
||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: llmgateway-metrics
|
||||||
|
namespace: traefik
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- match: PathPrefix(`/metrics`)
|
||||||
|
kind: Rule
|
||||||
|
middlewares:
|
||||||
|
- name: llmgateway
|
||||||
|
services:
|
||||||
|
- name: llmgateway-dummy-backend
|
||||||
|
port: 80
|
||||||
|
|
||||||
---
|
---
|
||||||
# Scraping /metrics (../README.md#metrics): this cluster runs
|
# Scraping /metrics (../README.md#metrics): this cluster runs
|
||||||
# VictoriaMetrics, not Prometheus, so the CRD is VMServiceScrape
|
# VictoriaMetrics, not Prometheus, so the CRD is VMServiceScrape
|
||||||
@@ -222,7 +264,9 @@ spec:
|
|||||||
# IMPORTANT: /metrics is served by TRAEFIK ITSELF, not by
|
# IMPORTANT: /metrics is served by TRAEFIK ITSELF, not by
|
||||||
# llmgateway-dummy-backend above — this middleware intercepts the path
|
# llmgateway-dummy-backend above — this middleware intercepts the path
|
||||||
# before any backend service is ever reached (same as every other route
|
# before any backend service is ever reached (same as every other route
|
||||||
# this plugin owns). Point this scrape at YOUR Traefik installation's own
|
# this plugin owns), which is exactly why the Host-free IngressRoute
|
||||||
|
# above exists: without it this scrape 404s before the middleware ever
|
||||||
|
# sees the request. Point this scrape at YOUR Traefik installation's own
|
||||||
# Service (commonly named "traefik" — verify against your own Helm
|
# Service (commonly named "traefik" — verify against your own Helm
|
||||||
# release), never at a backend service this file defines. Adjust
|
# release), never at a backend service this file defines. Adjust
|
||||||
# selector/namespaceSelector/port to match your Traefik Service's real
|
# selector/namespaceSelector/port to match your Traefik Service's real
|
||||||
|
|||||||
Reference in New Issue
Block a user