Files
homelab/templates/httproute.yaml
T
forust 18c633c242
ci / lint-prettier (push) Skipped
ci / lint-ruff (push) Skipped
ci / lint-yaml (push) Skipped
ci / lint-dockerfiles (push) Skipped
ci / validate (push) Skipped
renovate-ci / validate-renovate (push) Skipped
renovate-ci / validate-renovate (pull_request) Skipped
ci / lint-compose (pull_request) Successful in 12s
ci / lint-actionlint (pull_request) Successful in 6s
ci / lint-shellcheck (pull_request) Successful in 13s
ci / lint-prettier (pull_request) Successful in 21s
ci / lint-ruff (pull_request) Successful in 7s
ci / lint-yaml (pull_request) Successful in 12s
ci / lint-dockerfiles (pull_request) Successful in 7s
ci / validate (pull_request) Successful in 7s
ci / build (pull_request) Skipped
feat(monitoring): add VictoriaMetrics trial stack
2026-10-06 17:45:44 +02:00

182 lines
6.4 KiB
YAML

# Exhaustive HTTPRoute reference (gateway.networking.k8s.io/v1).
# Attaches to a Gateway listener via parentRefs and routes HTTP(S) by
# hostname + path/method/headers/query. Rules are evaluated in order; the
# first matching rule wins.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app
namespace: example
labels:
app: app
spec:
parentRefs:
# Every entry picks one listener to bind to. Omit sectionName/port to
# attach to ALL listeners of the Gateway (common for simple setups).
- name: example
# namespace: Gateway's namespace. Omit when same-namespace (the norm;
# cross-namespace needs the Gateway to allow it).
# namespace: example
# kind/group: default Gateway / gateway.networking.k8s.io. Set
# explicitly only for non-Gateway parents (mesh service parents).
kind: Gateway
group: gateway.networking.k8s.io
# sectionName: the listener name from the Gateway (http/https/...).
sectionName: https
# port: narrow further to one listener port. RARE when sectionName is
# already set.
port: 443
# hostnames: which Host headers this Route serves. Must intersect the
# listener hostname; otherwise the Route is rejected as incompatible.
# Omit to match every hostname on the listener.
hostnames:
- app.example.com
- www.example.com
rules:
# Rule 1: API traffic with header manipulation and canary split.
- matches:
# All conditions inside one match are ANDed; several matches in the
# list are ORed.
- path:
# type: Exact (one URL), PathPrefix (subtree), RegularExpression.
type: PathPrefix
value: /api
method: POST
headers:
# type: Exact or RegularExpression. Names are case-insensitive
# per HTTP spec; values are case-sensitive.
- type: Exact
name: X-Api-Version
value: v2
queryParams:
# Match on ?debug=true style parameters.
- type: Exact
name: debug
value: "true"
filters:
# Filters run in order and transform the request/response.
- type: RequestHeaderModifier
requestHeaderModifier:
# add: append even if present (duplicates allowed). set:
# overwrite-or-add. remove: delete by name.
add:
- name: X-Gateway
value: example
set:
- name: X-Forwarded-Proto
value: https
remove:
- X-Internal-Token
- type: ResponseHeaderModifier
responseHeaderModifier:
set:
- name: X-Frame-Options
value: DENY
remove:
- Server
# backendRefs below carry per-backend filters too; rule-level filters
# apply to every backend of this rule.
backendRefs:
- name: app-service
# port: the Service port (number). Required - unlike backendRef in
# Ingress, there is no default.
port: 80
# group/kind: default Service / core (""). Other kinds (e.g. a
# ServiceImport for multi-cluster) set kind + group explicitly.
kind: Service
group: ""
# weight: traffic share. 90/10 below = canary: 90% stable, 10% new.
weight: 90
filters:
# Per-backend filter: only this backend's requests get it.
- type: RequestHeaderModifier
requestHeaderModifier:
set:
- name: X-Backend
value: stable
- name: app-canary-service
port: 80
weight: 10
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
set:
- name: X-Backend
value: canary
# timeouts: per-attempt deadlines. request = whole gateway-to-client
# exchange; backendRequest = single backend try.
timeouts:
request: 30s
backendRequest: 10s
# sessionPersistence: stick a client to one backend (cookie-based).
# Type Cookie or Header; absoluteTimeout caps the stickiness.
sessionPersistence:
sessionName: route-session
type: Cookie
absoluteTimeout: 1h
cookieConfig:
lifetimeType: Session
# Rule 2: redirect old path to a new URL.
- matches:
- path:
type: PathPrefix
value: /old-docs
filters:
- type: RequestRedirect
requestRedirect:
# Any combination: scheme/host/port/path/statusCode. Unset fields
# keep the original value.
scheme: https
hostname: docs.example.com
path:
# type: ReplaceFullPath or ReplacePrefixMatch (rewrite the
# matched prefix, keep the remainder).
type: ReplacePrefixMatch
replacePrefixMatch: /docs
port: 443
# statusCode: 301 (permanent) or 302 (temporary).
statusCode: 301
# Rule 3: rewrite the URL but still proxy (client sees no redirect).
- matches:
- path:
type: PathPrefix
value: /shop
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /store
# hostname: also rewrite the Host header sent upstream.
# hostname: store-internal.example.com
backendRefs:
- name: app-service
port: 80
# Rule 4: mirror (shadow) traffic to a second backend for testing.
# The mirror gets a copy; its response is discarded.
- matches:
- path:
type: Exact
value: /checkout
filters:
- type: RequestMirror
requestMirror:
backendRef:
name: app-shadow-service
port: 80
backendRefs:
- name: app-service
port: 80
# Rule 5: delegate to an implementation-specific filter (auth plugin,
# rate limit, wasm). The controller documents the group/kind it honors.
# - filters:
# - type: ExtensionRef
# extensionRef:
# group: example.com
# kind: AuthPolicy
# name: app-auth
# Catch-all rule (no matches): everything not matched above lands here.
- backendRefs:
- name: app-service
port: 80