Files
zeekayandHanzo Dev 15d100931d
Hanzo CI/CD / cicd (push) Failing after 9m46s
CI/CD / cicd (push) Failing after 10m4s
Name the ingress in the docs, and fix what that exposed
Most of it was stale, not cosmetic: the docs taught `TRAEFIK_*` env,
`traefik.http.*` labels, `traefik.ingress.kubernetes.io/` annotations,
`.traefik.yml` plugins and `traefik_*` metrics. This binary answers to
`INGRESS_*`, `ingress.http.*`, `ingress.kubernetes.io/`, `.ingress.yml` and
`ingress.*` — a reader following the old text configured nothing.

Two were worse than stale. Gateway API examples gave `group: traefik.io` for an
IngressService backendRef, which kubernetes.go:1265 refuses against hanzo.ai.
The contributing guide built with `github.com/traefik/ingress` ldflags against
a module that is `github.com/hanzoai/ingress/v3`.

script/code-gen.sh globs `hanzo.ai_*.yaml` and matched nothing — the per-CRD
dumps had been deleted and never regenerated, so `cat` failed the script under
`set -e`. controller-gen v0.19.0 restores all ten; they concatenate
byte-for-byte into the committed definition and fixture.

CHANGELOG.md is untouched: 6,789 lines of imported release history, where a
rewrite would falsify the record rather than rebrand it. `@traefiklabs/faency`,
`traefik/whoami`, k3s's `--disable=traefik`, the `traefik.io` CRD group and the
MIT attribution stay — upstream's addresses, not our brand.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-16 13:01:19 -07:00

6.7 KiB

title, description
title description
IngressRouteUDP Understand the routing configuration for the Kubernetes IngressRouteUDP & Hanzo Ingress CRD

IngressRouteUDP is the CRD implementation of a UDP router.

Before creating IngressRouteUDP objects, you need to apply the Kubernetes CRDs to your Kubernetes cluster.

This registers the IngressRouteUDP kind and other CRD resources.

Configuration Example

apiVersion: hanzo.ai/v1alpha1
kind: IngressRouteUDP
metadata:
  name: ingressrouteudpfoo
  namespace: apps
spec:
  ingressClassName: ingress-lb
  entryPoints:
    - fooudp  # The entry point where Hanzo Ingress listens for incoming traffic.
  routes:
  - services:
    - name: foo # The name of the Kubernetes Service to route to.
      port: 8080
      weight: 10
      nativeLB: true # Enables native load balancing between pods.

Configuration Options

Field Description Default Required
ingressClassName Defines the IngressClass cluster resource to use. It replaces the deprecated kubernetes.io/ingress.class annotation.
The spec field takes precedence over the annotation.
No
entryPoints List of entrypoints names. No
routes List of routes. Yes
routes[n].services List of Kubernetes service definitions. See here for ExternalName Service setup. No
services[n].name Defines the name of a Kubernetes service. Yes
routes[n].services[n].port Defines the port of a Kubernetes service. This can be a reference to a named port. Yes
routes[n].services[n].weight Defines the weight to apply to the server load balancing. 1 No
routes[n].services[n].nativeLB Controls, when creating the load-balancer, whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. false No
routes[n].services[n].nodePortLB Controls, when creating the load-balancer, whether the LB's children are directly the nodes internal IPs using the nodePort when the service type is NodePort. It allows services to be reachable when Hanzo Ingress runs externally from the Kubernetes cluster but within the same network of the nodes. See here for more information. false No

ExternalName Service

Hanzo Ingress backends creation needs a port to be set, however Kubernetes ExternalName Service could be defined without any port. Accordingly, Hanzo Ingress supports defining a port in two ways:

  • only on IngressRouteUDP service
  • on both sides, you'll be warned if the ports don't match, and the IngressRouteUDP service port is used

Thus, in case of two sides port definition, Hanzo Ingress expects a match between ports.

=== "Ports defined on Resource"

```yaml tab="IngressRouteUDP"
apiVersion: hanzo.ai/v1alpha1
kind: IngressRouteUDP
metadata:
  name: test.route
  namespace: apps

spec:
  entryPoints:
    - foo
  routes:
  - match: Host(`example.net`)
    kind: Rule
    services:
    - name: external-svc
      port: 80
```

```yaml tab="Service ExternalName"
apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: apps

spec:
  externalName: external.domain
  type: ExternalName
```

=== "Port defined on the Service"

```yaml tab="IngressRouteUDP"
apiVersion: hanzo.ai/v1alpha1
kind: IngressRouteUDP
metadata:
  name: test.route
  namespace: apps

spec:
  entryPoints:
    - foo
  routes:
  - match: Host(`example.net`)
    kind: Rule
    services:
    - name: external-svc
```

```yaml tab="Service ExternalName"
apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: apps

spec:
  externalName: external.domain
  type: ExternalName
  ports:
    - port: 80
```

=== "Port defined on both sides"

```yaml tab="IngressRouteUDP"
apiVersion: hanzo.ai/v1alpha1
kind: IngressRouteUDP
metadata:
  name: test.route
  namespace: apps

spec:
  entryPoints:
    - foo
  routes:
  - match: Host(`example.net`)
    kind: Rule
    services:
    - name: external-svc
      port: 80
```

```yaml tab="Service ExternalName"
apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: apps

spec:
  externalName: external.domain
  type: ExternalName
  ports:
    - port: 80
```

NativeLB

To avoid creating the server load-balancer with the pods IPs and use Kubernetes Service clusterIP directly, one should set the NativeLB option to true. By default, NativeLB is false.

apiVersion: hanzo.ai/v1alpha1
kind: IngressRouteUDP
metadata:
  name: test.route
  namespace: default
spec:
  entryPoints:
    - foo
routes:
- services:
  - name: svc
    port: 80
    # Here, nativeLB instructs to build the servers load balancer with the Kubernetes Service clusterIP only.
    nativeLB: true
apiVersion: v1
kind: Service
metadata:
  name: svc
  namespace: default
spec:
  type: ClusterIP
  ...