Merge pull request 'Issue 109: a container keeps the address it was made with' (#96) from issues/109-a-container-keeps-the-address-it-was-made-with into main
This commit was merged in pull request #96.
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
---
|
||||
status: located
|
||||
opened: 2026-09-24
|
||||
located-in: [mesh-host internal/apply]
|
||||
fixed-by:
|
||||
amended-design:
|
||||
---
|
||||
|
||||
# 109 — A container keeps the address it was made with, and nothing recreates it when the node moves
|
||||
|
||||
## What was observed
|
||||
|
||||
On the control-node, 2026-09-24, minutes after the mesh took over the predecessor's tunnel
|
||||
([ADR 0105](../../02-DECISIONS/0105-the-mesh-adopts-the-predecessors-tunnel-in-place.md)).
|
||||
|
||||
Adopting the tunnel moves the mesh onto the tunnel's range, so the hub's private address changed.
|
||||
Everything the controller composes followed it: the declaration's hosts entries for every container
|
||||
said the new address within one push. Nothing on the machine followed. The forge's container had
|
||||
the **old** address written in its own hosts file — put there when the container was created — and
|
||||
so lost its database. It reported healthy for as long as its existing connections lasted, then
|
||||
answered failures, and the public name went down.
|
||||
|
||||
```
|
||||
declared: novox.internal -> <new hub address>
|
||||
in the container: novox.internal -> <old hub address>
|
||||
```
|
||||
|
||||
The container was not recreated, and was still running from before the move. Removing it and
|
||||
letting the mesh make it again fixed it in one step.
|
||||
|
||||
The service beside it was untouched by the same change, which is the part worth keeping: it sits on
|
||||
a network of its own, so it asks a resolver for the name rather than reading a copy of the answer.
|
||||
Only a container on the runtime's default network gets the answer baked in.
|
||||
|
||||
## Why it matters beyond this instance
|
||||
|
||||
The mesh's rule is that an address is read where it is used and never recorded
|
||||
([issue 102](../102-an-address-recorded-at-genesis-or-build-does-not-follow-the-nodes-ports/00-report.md)).
|
||||
This is that rule broken one level further down: the controller obeys it, and then the runtime
|
||||
writes the answer into the container at creation, where it stays for the life of the container.
|
||||
|
||||
A node's address changes more often than it looks: adopting a tunnel, moving a machine between
|
||||
sites, renumbering a range. Each time, every container made before the change keeps pointing at
|
||||
where the node used to be — and says nothing, because from the mesh's side the declaration is
|
||||
correct and the node reports it applied.
|
||||
|
||||
It is the same shape as
|
||||
[issue 103](../103-a-container-is-not-recreated-when-a-file-it-reads-changes/00-report.md), whose fix
|
||||
made the *content of a file* a container reads part of what the host compares. The hosts entries a
|
||||
container is made with are the same kind of input, read once at creation, and are not compared.
|
||||
|
||||
## Open questions
|
||||
|
||||
- Should the hosts entries a container is created with be part of what the host compares, so a
|
||||
changed address recreates it — accepting that a node's address change restarts every container on
|
||||
it?
|
||||
- Or should a container never be given the answer at all, and always ask the resolver — which is
|
||||
what the containers that survived this do? That makes the resolver a dependency of every module
|
||||
and is the stronger statement; it is also what the mesh's own resolver exists for.
|
||||
- Either way: what tells an operator that a container is running with an address the node no longer
|
||||
has? Nothing did.
|
||||
Reference in New Issue
Block a user