klimax is now marina. Same tool, new name since v0.3. Existing install? Migrate with marina migrate →
Documentation menu

Hostname playbook

Every LoadBalancer Service already has an automatic name. For anything people or other services call, give it a chosen name with one annotation — under the cluster or under the fleet. This page says which, and wires up HTTPS for each.

The rule

Clients should reach…Name itCertificate Secret
the service wherever the fleet runs it — a gateway, SSO, a shared API<name>.<fleet>.demo.internalmarina-fleet-wildcard-tls
this cluster's instance — a per-region admin API, a per-cluster dashboard<name>.<cluster>.demo.internalmarina-wildcard-tls
nothing in particular — a quick testthe automatic <svc>.<ns>.<cluster>.demo.internalcert-manager with marina-ca, or none

The name goes in one annotation on the Service. A Service can carry several, comma-separated:

metadata:
  annotations:
    external-dns.kubernetes.io/hostname: gateway.lab.demo.internal,gateway.lab-east.demo.internal

Naming conventions

  • One label for the name: gateway, sso, grafana. It is what the wildcard certificate covers — api.gateway.lab.demo.internal would not be.
  • No namespace, no environment in the name. The cluster or fleet part already says where it lives.
  • Keep it stable across rebuilds. A name survives marina cluster delete and re-create; recipes, bookmarks and OIDC issuer URLs can depend on it.
  • A fleet and a cluster never share a name — both would own <name>.demo.internal, so marina refuses it.

Recipe: a fleet-wide gateway

A fleet lab with clusters lab-east, lab-west and lab-ops; the gateway runs in lab-east. Clients use one fleet-wide name; operators also get a per-cluster one.

apiVersion: v1
kind: Service
metadata:
  name: gateway
  namespace: gateway
  annotations:
    external-dns.kubernetes.io/hostname: gateway.lab.demo.internal,gateway.lab-east.demo.internal
spec:
  type: LoadBalancer
  selector: {app: gateway}
  ports: [{name: https, port: 443}]

HTTPS for the fleet name uses the fleet wildcard. It lives in default; copy it next to the gateway and mount it:

$ marina ca secret lab-east -n gateway --fleet
✓ gateway/marina-fleet-wildcard-tls
$ curl https://gateway.lab.demo.internal/

One certificate serves both names only if they share a zone; here they do not. Present the fleet wildcard for the fleet name, and — if clients use the cluster name over HTTPS too — the cluster wildcard (marina ca secret lab-east -n gateway) through SNI, or a cert-manager certificate listing both names.

Recipe: per-cluster names

For something that exists once per cluster and must be addressed per cluster — the admin API of each region, say — name it under the cluster:

external-dns.kubernetes.io/hostname: admin.lab-west.demo.internal

and serve marina-wildcard-tls (marina ca secret lab-west -n gateway). The same manifest applied to every cluster only differs by that one annotation value.

Recipe: Ingress hosts

By default Ingresses are not published. Put the hostnames on the ingress controller's Service instead (external-dns.kubernetes.io/hostname: shop.lab.demo.internal), or set network.dns.ingress: true and run marina dns attach <cluster>: any Ingress host under the cluster or the fleet zone then gets a record pointing at the ingress controller's LoadBalancer, and each Ingress also gets an automatic <ingress>.<namespace>.<cluster>.demo.internal.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: shop
  namespace: shop
spec:
  tls:
    - hosts: [shop.lab.demo.internal]
      secretName: marina-fleet-wildcard-tls     # marina ca secret lab-east -n shop --fleet
  rules:
    - host: shop.lab.demo.internal
      http:
        paths: [{path: /, pathType: Prefix, backend: {service: {name: shop, port: {number: 80}}}}]

The same fleet name on several clusters

If two members claim the same fleet name, the first one to publish it owns it; the other's claim is ignored and the name keeps a single address. Delete the owner and the next claimant takes over within about 30 seconds.

⚠

That is a handover, not load balancing: a fleet name never resolves to several clusters at once. Publish a fleet name from the cluster that serves it, and use per-cluster names when clients must pick a specific region.

Check a name

$ marina dns list | grep gateway                   # published? by which address?
$ dscacheutil -q host -a name gateway.lab.demo.internal
$ marina ca status                                   # the wildcards and their expiry
SymptomCause
The name never appears in marina dns listIt is outside the cluster's zone and its fleet's zone — each cluster may only publish under those two. A cluster outside any fleet cannot publish a fleet name: marina fleet adopt <fleet> <cluster>.
It resolves to the wrong clusterAnother member published the same fleet name first — see above.
The browser rejects the certificateThe name has two labels under the zone (api.gateway.lab…), or the Secret is the cluster wildcard for a fleet name. Or the root is not trusted: marina ca trust.
A new name does not resolve on the MacIt was looked up before it was published; macOS caches that for about 75 seconds.

See also