Skip to main content
The Gateways & Routes tab manages the north-south path: Gateway API objects, their listeners and certificates, and the routes that publish workloads through them. Which controller serves them — Envoy Gateway or Cilium Gateway API — is shown by the north-south engine pill in the page header. If the pill flags a conflict, both stacks’ CRDs are installed at once; resolve that before creating gateways, or two controllers will fight over the same objects. The Gateways & Routes tab — gateways with class chips, listeners, and the unified routes table

The shared gateway pattern

Celum’s ingress model is built on one Gateway, many namespaces. A shared Gateway holds a single LoadBalancer address; every listener on it allows routes from all namespaces, so an HTTPRoute anywhere in the cluster can attach to it cross-namespace. Each HTTPS listener with an issuer gets its own cert-manager certificate. The result: services and tenant APIs are published without consuming a LoadBalancer address each, and certificates renew without anyone touching a Secret.

The Gateways table

Each row shows the gateway’s class chip, its address, the hostnames it serves, and its ready state. Gateways created by Celum are fully editable; gateways created outside it are listed read-only — edit those through their own tooling.

Create a gateway

Add gateway asks for a name, a namespace, and optionally a requested IP — a specific address from a LoadBalancer pool instead of whatever the pool hands out next. You can change the address later from the row’s actions. With no listeners specified, the gateway starts with a single HTTP listener on port 80; add more with the listener editor. Default issuer. In the Add gateway and Edit gateway drawers, the Listeners section starts with a Default issuer picker. It lists the supervisor’s ClusterIssuers and marks the supervisor’s default as (cluster default). It also marks any issuer that is not ready. The picker starts on the gateway’s cert-manager.io/cluster-issuer annotation if the gateway has one, and otherwise on the supervisor’s default issuer. Each HTTPS listener you add after that gets this issuer as a proposal, and you can change it per listener. Choosing an issuer here issues nothing and changes no existing certificate. none — choose per listener proposes nothing. To list the issuers you need certs:GetStatus. Without it, the picker is disabled.

Listeners

The listener editor manages the gateway’s listeners — each is a name, protocol, port, and optional hostname:
Plain HTTP. Typically kept on port 80 for the automatic HTTPS redirect that route publication creates.
Each listener’s certificate is its own.
  • Create and Edit give each HTTPS listener with an issuer its own certificate from that issuer. Changing one listener’s issuer changes only that listener’s certificate. A route published on the same hostname keeps its own certificate.
  • A listener keeps a certificate that already serves its hostname from its issuer. Saving the drawer for another change re-issues nothing.
  • Saving does not wait for issuance. Until cert-manager writes the Secret, the gateway’s status for that listener reports the missing certificate. The API returns that status with the listeners; the edit drawer does not show it yet.
  • If a listener’s certificate cannot be requested, for example because the issuer does not exist, the listener keeps the certificate it had and a warning names it.
  • Removing a listener deletes its own certificate and Secret. Deleting the gateway deletes all of them. A Secret that another gateway serves stays.
A gateway created before Celum 1.296, or by an exposure before 1.297, can carry the cert-manager.io/cluster-issuer annotation. Under the annotation, cert-manager’s gateway-shim issues and owns a certificate for each listener that has none of its own, and a change to the annotation re-issues all of them. Celum does not remove the annotation. The edit drawer shows who owns each listener’s certificate. If you give a listener with a gateway-owned certificate its own issuer, that listener leaves the gateway’s set for good.
POST /api/supervisors/{name}/networking/gateways creates a gateway and PUT /api/supervisors/{name}/networking/gateways/{gw} replaces its listeners. Both need gateway:Create. A listener with protocol: HTTPS, a hostname and an issuer gets its own certificate. When a certificate could not be requested, applied or deleted, the response carries a warnings list. DELETE /api/supervisors/{name}/networking/gateways/{gw} needs gateway:Delete, and its response carries warnings the same way. GET /api/supervisors/{name}/networking/gateways/{gw}/listeners returns each listener with its certificate’s issuer and owner.
Listener names starting with tls- are reserved for tenant-API publications. The editor refuses them, and editing listeners never touches the reserved ones — so an operator edit can never silently unpublish a tenant API.

A backend behind an HTTPS listener receives plain HTTP

This follows directly from “TLS terminated at the gateway” and catches people anyway, because nothing about it looks like a networking problem. The request that reaches your workload has scheme http, and its immediate peer is the gateway rather than the browser. An application that builds absolute URLs from what it sees — redirects, asset links, Secure cookie flags, an OIDC redirect_uri — will emit http:// on a site the browser loaded over HTTPS. The page then renders without its stylesheets, or a login bounces between schemes, and the route, the certificate and the listener are all fine. The client’s real scheme arrives in X-Forwarded-Proto, with its address in X-Forwarded-For. Configure the application to trust those headers — in most frameworks that is one setting — rather than changing anything on the route.
TLS passthrough does not have this property, because nothing is terminated: the backend completes the handshake itself and sees the original connection. It is the terminating listener types that introduce the hop.

Datapath modes

On Envoy-class gateways, each gateway can choose how its proxy runs — the switch actually reconfigures the underlying Envoy proxy deployment: Switching mode rolls the proxy; expect a brief connection blip on that gateway.

Routes

One table lists every route — HTTP and TLS — with its hostname, backend, parent gateway, and whether the gateway controller accepted it. An unaccepted route serves nothing; the row carries the controller’s message explaining why.

Publish a service

Publish service on the Routes card creates an HTTPRoute through a gateway, and a certificate for its hostname:
1

Start from a platform service, or enter your own

Platform services at the top of the drawer lists the platform’s own web UIs that are installed and not yet published: Grafana, Prometheus, Loki (log push), ClickHouse HTTP, the Ceph dashboard and Hubble UI. Click one to fill in the hostname, namespace, Service and port. For any other service, type the Namespace, the Service and the Port (80 by default).
2

Accept or edit the hostname

A platform service comes with <prefix>.<supervisor domain>, for example grafana.<supervisor domain>. Your own service gets no suggestion, so type the Hostname.
3

Pick the gateway and issuer

Gateway starts on the shared gateway. If the service is in a project that has its own gateway, the route goes on that gateway whatever you pick, because the project’s isolation keeps the shared gateway away from its pods. Another project’s own gateway is not offered: it admits routes from its own namespace only, and the API refuses it with 400. If you leave TLS · ClusterIssuer at default issuer (auto), Celum uses the supervisor’s pinned default issuer, or else the issuer it detects.
The route is named <service>-route. Celum refuses a hostname that another route or listener already serves, with 409, and an issuer the supervisor does not have, with 400, before it writes anything. Each hostname gets its own certificate from the issuer you chose, a ClusterIssuer or an AD CS issuer, so no other hostname’s certificate changes. Publishing a hostname again moves its listener to that certificate only when the listener serves no certificate; one that serves a certificate, whoever chose it, keeps it.
Networking → Gateways & Routes → Routes → Publish service.
An HTTP-to-HTTPS redirect (301) is created alongside the route automatically, so the plain-HTTP hostname never serves content.

Publish a tenant cluster’s API

Publish tenant API exposes a tenant cluster’s Kubernetes API through the shared gateway using TLS passthrough:
  • A passthrough listener for the chosen hostname is appended to the gateway (with the reserved tls- name prefix).
  • A TLSRoute forwards matching SNI traffic to the tenant’s API server Service.
  • The hostname is appended to the tenant API server certificate’s SANs, so kubectl trusts the published endpoint.
Unpublishing removes the route and its listener again. The table shows each published API’s accepted state — if it stays unaccepted with no controller status, the gateway controller may not watch TLSRoutes at all (Cilium’s Gateway API needs its alpha feature set for that).
Individual VM ports can also be published through a gateway. That flow lives with the VM — see VM networking.

Permissions

All are scoped to krn:celum:supervisor:<supervisor>:gateway:*.

VM networking

Publishing a single VM’s ports — LoadBalancer or gateway.

Pools & IPAM

Where a gateway’s LoadBalancer address comes from.

BGP & Egress

How the gateway’s address is advertised to the fabric.

Networking overview

The north-south engine and the rest of the model.