Found reviewing the resolver's conversion. Nothing fails while the node is adopted; it fails at the flip, and it is the same split that decided which container survived the hub's address change.
54 lines
2.6 KiB
Markdown
54 lines
2.6 KiB
Markdown
---
|
|
status: open
|
|
opened: 2026-09-24
|
|
located-in: []
|
|
fixed-by:
|
|
amended-design:
|
|
---
|
|
|
|
# 110 — On a converged node, a container on the runtime's own network cannot reach the resolver
|
|
|
|
## What was observed
|
|
|
|
Reviewing the resolver's conversion from the predecessor's, 2026-09-24, before it is assigned
|
|
anywhere.
|
|
|
|
The resolver answers on the private network's interface and on loopback, and it declares that it
|
|
listens **from the mesh** — so the filter a converged node loads admits queries whose source is a
|
|
private-network address. A container asks in one of two ways:
|
|
|
|
- on a network the module declared, the runtime answers from the container's own namespace and
|
|
forwards to the resolver **from the machine itself**, which the filter admits;
|
|
- on the runtime's **default** network, the container is handed the resolver's address directly and
|
|
asks from its own address on that network — which is not a private-network address, and the filter
|
|
drops it.
|
|
|
|
So on a converged node a container on the default network has no DNS. It is not hypothetical: the
|
|
forge's container on this machine is on the default network, and the service beside it is not —
|
|
which is exactly why one survived the hub's address change and the other did not
|
|
([issue 109](../109-a-container-keeps-the-address-it-was-made-with/00-report.md)).
|
|
|
|
Nothing fails today, because the node is adopted and the predecessor's firewall is still in force.
|
|
It fails at the flip.
|
|
|
|
## Why it matters beyond this instance
|
|
|
|
Two of the mesh's answers depend on this working. The resolver exists so that a machine and its
|
|
containers resolve the mesh's names; and [issue 109](../109-a-container-keeps-the-address-it-was-made-with/00-report.md)
|
|
asks whether a container should be given no address at all and always ask the resolver. That answer
|
|
is only available if every container can reach it.
|
|
|
|
It also means the flip is not as previewed. Converging lists the ports it will close; it does not
|
|
say "and the containers on the runtime's default network will stop resolving names", because nothing
|
|
knows that is what the rule means.
|
|
|
|
## Open questions
|
|
|
|
- Should the resolver's `listens` say it is reachable from the container runtime's own networks —
|
|
the same exception the mesh's guard already makes for them, by the interface a packet arrives on
|
|
rather than by its source address?
|
|
- Or should every module be required to declare a network, so no container of the mesh's is ever on
|
|
the runtime's default one? That is a stronger rule and would have prevented 109 as well.
|
|
- What checks it? A converged bed with a container on the default network resolving a mesh name is
|
|
the missing assertion; nothing in the resolver's own beds covers the filter.
|