From a3cee17d48df28fde680be77ba90e2635e395d87 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 31 Aug 2026 11:29:25 +0200 Subject: [PATCH] Record what a container can see of the mesh's names, and what it cannot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found by a container failing to resolve a name every machine could: a container gets its own hosts file holding only its own hostname, and on the machine it always worked, which is what made it easy to miss. Declared containers are given the names. A container somebody starts by hand is not the mesh's to configure — which is a second, different reason to want a resolver, recorded beside the first rather than folded into it. --- 03-DESIGN/01-to-be/08-connectivity.md | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/03-DESIGN/01-to-be/08-connectivity.md b/03-DESIGN/01-to-be/08-connectivity.md index 9cb4d9c..95a4a96 100644 --- a/03-DESIGN/01-to-be/08-connectivity.md +++ b/03-DESIGN/01-to-be/08-connectivity.md @@ -250,6 +250,41 @@ name and overlay address. database before its own DNS existed; with [ADR 0004](../../02-DECISIONS/0004-a-node-and-how-it-joins.md) nothing needs a name before the link, and a fallback nothing needs is a path nothing tests. +### Names, and what a container can see + +*2026-08-31, from a container that could not resolve a name every machine could.* + +Internal names are `.internal` — the suffix is the one IANA reserved in 2024, so a name that +leaks into a public resolver fails rather than reaching a stranger's machine. They are computed +centrally, because a name set needs every node at once, and written to each machine's hosts file. + +**A file rather than a resolver**, and the reasoning holds: it works on every Linux, needs no +package, and has no failure mode of its own. The stated trigger for a daemon was *names that are +not one-per-node* — service names, wildcards. + +**But a container does not inherit the machine's names.** It gets its own hosts file holding only +its own hostname. So every name the mesh wrote was invisible to the majority of things that need +one — and *on the machine it always worked*, which is exactly what made it easy to miss. It was +found by a database client on one node failing to resolve another node, on a mesh where both names +were correct and present on both machines. + +**So the mesh gives its names to the containers it declares**, written into each container's own +hosts file by the runtime. That extends the file decision rather than overturning it. Given by the +mesh and not chosen by a module: a module that listed the machines would go stale the day one +joins, and a module that did not would be one whose containers cannot reach anything by name. + +**The boundary, which is deliberate and worth stating:** *declared* containers. A container +somebody starts by hand is not the mesh's to configure, and reaching into every container on a +machine — declared or not — is what a nameserver in `resolv.conf` would be for. + +**That is now the second reason to want a resolver**, and it is a different one from the trigger +above. Both remain unmet needs rather than plans: + +| | | +|---|---| +| names that are not one-per-node | `postgres.internal` meaning *wherever the database is* | +| containers the mesh did not declare | anything a person or another tool starts on a node | + ## 3 — Exposure Settled by [ADR 0007](../../02-DECISIONS/0007-connectivity.md); summarised here because