---
title: Gateway routes and DNS
description: Two Cilium Gateways, one wildcard certificate, and external-dns reading hostnames from HTTPRoute objects.
weight: 10
icons: [cilium, cloudflare, tailscale, netbird]
tags: [cilium, gateway-api, external-dns, cloudflare, tls]
---

Ingress is two `Gateway` objects, both from the Cilium class, one on the home LAN and
one on the OCI VM. Each terminates TLS with the same certificate and accepts routes
from every namespace, so an application owns its `HTTPRoute` and nothing else.

## Addresses and what serves them

| entry                   | address           | class                    | notes                                                                    |
| ----------------------- | ----------------- | ------------------------ | ------------------------------------------------------------------------ |
| `cilium-gateway-svt`    | `192.168.107.200` | `io.cilium/l2-announcer` | dedicated VIP from `gateway-svt-pool`, announced on the LAN              |
| `cilium-gateway-oracle` | node IPs          | `io.cilium/node`         | Node IPAM; only nodes without the external-load-balancer exclusion label |

The difference is not cosmetic. The svt gateway owns an address of its own, so it is
reachable from the LAN regardless of which node runs the proxy. The oracle gateway
advertises node addresses instead, which is what the OCI NAT forwards to, and Node
IPAM skips any node labelled
`node.kubernetes.io/exclude-from-external-load-balancers`, a label Talos puts on
control-plane nodes.

## Certificate

`*.kubexa.tech` alone does not cover the apex. The certificate carries
`*.kubexa.tech`, `kubexa.tech` and `*.chat.kubexa.tech` as extra names, and the same
Secret is referenced by both gateways.

## Hostnames come from routes

external-dns watches `HTTPRoute` objects, reads their `hostnames`, and writes the
records. Two annotations decide the shape: the origin the record should carry, and
whether Cloudflare proxies it. Because the record is derived, deleting a route removes
the hostname on the next reconcile.

A wildcard listener does not match the apex, so `kubexa.tech` and `www.kubexa.tech`
have their own listener entries (`https-apex`, `http-apex`, `http-www`). Without them
the route attaches to nothing and the hostname answers nothing.

## Meshes

Three network paths exist for different reasons. Tailscale carries the tailnet,
subnet-router mode from the Flint 3, which is how a laptop reaches `192.168.107.0/24`
without a VPN config. NetBird is the newer mesh, self-hosted on the oracle node, with
groups fed from Zitadel claims. KubeSpan is Talos's own WireGuard mesh between the
nodes themselves.
