Skip to main content

Declare the hostnames a data plane serves

Enterprise Tier

From 0.7.0 a data plane declares the hostnames it serves in its own chart, under global.gateway.hostnames, and reports them to the management plane on every configuration poll. The Admin Console lists them read-only. No console page or API call writes a declared hostname: adding or retiring one is a values change followed by tare upgrade or helm upgrade.


Persona: Platform operator with access to the data plane's Helm values or tare identity file, the DNS zone, and the load balancer in front of the cluster.

Estimated time: 10 minutes for the values change, plus DNS propagation and certificate issuance.

Outcomes​

By the end of this guide:

  • The data plane's serve-helm values list every hostname callers use to reach it, with the name callers should use first.
  • Each declared hostname resolves to the data plane's load balancer, presents a certificate that covers it, and routes to the data plane.
  • The Admin Console lists the hostnames on the data plane's page, and tare doctor confirms the certificate covers each one.

Prerequisites​

  • A self-hosted data plane on 0.7.0 or later. A data plane before 0.7.0 cannot declare hostnames and keeps the address stored for it through the admin API.
  • Control of the DNS zone for each hostname, and of the certificate the load balancer presents.
  • For a data plane that already serves traffic on a stored address, read Move a data plane to declared hostnames first. A partial list refuses later edits to gateway URLs that are missing from it.

Step 1: list the hostnames​

Add the list to the data plane's serve-helm values:

global:
gateway:
hostnames:
- eu.acme.example.com # first: the address the console prints
- dp.acme.example.com:8443 # a port, for callers that do not use 443

tare takes the same list as a repeatable flag:

# Declare two names at install time.
tare install /path/to/data-plane-credentials.json \
--gateway-hostname=eu.acme.example.com \
--gateway-hostname=dp.acme.example.com:8443

# Upgrade and keep the installed list. tare upgrade reads it from the release.
tare upgrade /path/to/data-plane-credentials.json

# Upgrade and replace the list.
tare upgrade /path/to/data-plane-credentials.json --gateway-hostname=eu.acme.example.com

There are 5 rules for the entries:

  1. An entry is a hostname, optionally with a port. The management plane stores the port apart from the name and joins them again when it prints an address. A scheme such as https:// is accepted and dropped.
  2. The first entry is the address the console prints wherever it shows a single address, such as the Base URL panel and the Playground. List the name callers should use first.
  3. Two data planes in one organization may declare the same name, which is how a pair behind a global server load balancer serves one hostname. The console lists both data planes under that name. Two organizations cannot claim one hostname, and two gateways on one data plane still cannot share one.
  4. Leaving the key out declares nothing. The data plane keeps the address stored for it through SetDataplaneURL and answers its readiness probe there. serve-helm leaves the key out by default, so upgrading to 0.7.0 with untouched values changes nothing about where the data plane serves.
  5. An empty list is a declaration. It says the data plane serves no hostname: the management plane retires every name it recorded for the data plane, and the readiness probe stops answering. Write hostnames: [], or run tare upgrade with --gateway-hostname="" alone, only to drain a data plane.
A plain helm upgrade can drop the list

Running helm upgrade without the values file that carries the hostnames drops the key, and the data plane falls back to its stored address. Keep the list in the values file applied on every upgrade. tare upgrade carries the installed list forward and does not have this problem.

Step 2: apply and confirm the declaration​

  1. Run tare upgrade or helm upgrade with the new values.

  2. Read what the chart rendered. The chart writes the list into the tars-gateway-declaration ConfigMap:

    kubectl -n tars-system get configmap tars-gateway-declaration -o jsonpath='{.data.gateway-hostnames}'
    ["eu.acme.example.com","dp.acme.example.com:8443"]

    An empty list renders []. A chart with the key left out renders no gateway-hostnames field at all, which the management plane reads as "declares nothing" rather than as an empty list.

  3. In the Admin Console, open Directory → Data Planes and select the data plane. The hostnames appear on its page once the data plane polls for configuration. A row tagged set through the management plane is a stored address, which means the chart still declares nothing.

Step 3: make each name serve​

Declaring a name tells the management plane that the data plane serves it. The chart creates no DNS record, certificate, or load balancer route. There are 3 things each declared name needs before a caller reaches it:

  1. A DNS record that points the name at the data plane's load balancer.
  2. A certificate on the load balancer, or on the cluster's own listener, that covers the name.
  3. A route at the load balancer that sends requests for the name to the data plane. Without it the TLS handshake succeeds and the request answers 404.

GKE with the gateway-serve-helm chart​

The gateway-serve-helm chart does not read global.gateway.hostnames. Pass the same names to it as gatewayHostnames, so its HTTPRoute matches each one beside serveUrl:

# gateway-serve-helm values (gateway.yaml)
customer: acme
serveUrl: proxy.acme.example.com
certificateMap:
name: acme-serve-certmap
gatewayHostnames:
- eu.acme.example.com
- dp.acme.example.com

The chart drops a port, a scheme, and a path from each entry, because a Gateway API hostname carries no port. Confirm the route after the upgrade:

kubectl -n tars-gateway get httproute proxy-route -o jsonpath='{.spec.hostnames}'

The chart names the certificate map and never creates its entries. tare gateway install creates one map entry, for the serve host only. Create a certificate and a map entry for every further name:

HOST=eu.acme.example.com
SLUG=$(echo "$HOST" | tr . -)
MAP=acme-serve-certmap

gcloud certificate-manager dns-authorizations create "$SLUG-dns-auth" --domain="$HOST"
# Publish the CNAME this prints in the zone that holds $HOST.
gcloud certificate-manager dns-authorizations describe "$SLUG-dns-auth" --format='value(dnsResourceRecord)'

gcloud certificate-manager certificates create "$SLUG" \
--domains="$HOST" --dns-authorizations="$SLUG-dns-auth"
gcloud certificate-manager maps entries create "$SLUG-entry" \
--map="$MAP" --certificates="$SLUG" --hostname="$HOST"

The certificate stays PROVISIONING until the DNS authorization record is published. Point the name's A record at the Gateway's address once the certificate is ACTIVE.

AWS, Azure, and other load balancers​

No chart provisions the edge on AWS or Azure. The DNS record, the certificate (an ACM certificate on an ALB or NLB, or a Key Vault certificate on an Application Gateway), and the listener or Ingress rule for each name are the operator's own. Where the Ingress or listener uses host-based rules, add a rule for each declared name. See Gateway installation on EKS and Gateway installation on AKS.

Step 4: check the certificate the data plane reads​

A data plane on 0.7.0 or later reads the certificate serving each declared name and reports it beside the name: the subject alternative names, the issuer, the fingerprint, the validity window, the address the handshake reached, and where the reading was taken from. By default it dials each declared name over HTTPS, honouring HTTPS_PROXY and NO_PROXY, so it reads what a load balancer in front of the cluster presents as well as a certificate on the cluster's own listener.

global.gateway.certificateProbe changes where the data plane dials. There are 3 shapes:

  1. A private load balancer the cluster reaches but cannot resolve by name. Name its address, and optionally a port, an SNI, and a CA bundle that decides whether the chain reads as trusted:

    global:
    gateway:
    certificateProbe:
    address: dp-internal.eu-west-1.elb.amazonaws.com
    port: 8443
    sni: eu.acme.example.com # defaults to each declared name
  2. A GKE global external load balancer. Name the forwarding rule's address and leave sni out, so each declared name is sent in turn and the certificate map answers with the certificate it holds for that name:

    global:
    gateway:
    certificateProbe:
    address: 34.120.0.1
  3. An endpoint nothing inside the trust boundary can reach, such as a DMZ appliance or a CDN whose origin is unroutable. Turn the dial off:

    global:
    gateway:
    certificateProbe:
    enabled: false

    Every address then reads as not observed and says the chart disabled the probe. The data plane stays healthy.

certificateProbe says where to look. Nothing in it changes what the certificate says, so an expired certificate never reads as healthy.

Run the same reading from the command line:

tare doctor /path/to/data-plane-credentials.json --only gateway

tare doctor reads the listener certificate where a listener carries one, and otherwise dials each declared address the same way the data plane does, honouring certificateProbe. It reports:

ReadingSeverity
The certificate does not cover a declared nameWARN, naming the hostname
The certificate has expired, or is not valid yetERROR, with the time validity starts or ended. A not-yet-valid certificate points at the cluster clock or the issuing CA
The certificate expires soonReported with the time left
The address could not be reachedINFO, with the openssl s_client command to read it by hand. The data plane stays healthy

Troubleshooting​

SymptomCauseFix
A declared name appears in the console but requests to it answer 404The load balancer has no route for the name. TLS completes, then nothing matchesAdd the name to the load balancer's routes. On GKE, add it to gatewayHostnames on gateway-serve-helm
The GKE certificate for a new name stays PROVISIONINGThe DNS authorization record is not publishedPublish the record that gcloud certificate-manager dns-authorizations describe prints, then wait for ACTIVE
CreateProjectGateway, UpdateProjectGateway, or SetProjectGatewayURL fails with FailedPrecondition naming global.gateway.hostnames, including a console edit that resends an unchanged URLThe data plane declares hostnames, and the URL's hostname is not one of themAdd the hostname to the list and upgrade the chart. See Move a data plane to declared hostnames
/healthz/membership answers 404 on one declared name while others answer 200The name is missing from the rendered ConfigMap, or the request's Host carries a non-standard portRead tars-gateway-declaration as in Step 2. The probe answers on port 443 only
The console lists the old stored address again after an upgradehelm upgrade ran without the values file, so the key was droppedRe-run the upgrade with the values file, or use tare upgrade, which carries the list forward
tare doctor warns that the certificate does not cover a nameThe certificate's subject alternative names lack the declared nameReissue the certificate with the name, or remove the name from the list