4.9 KiB
status, opened, located-in, fixed-by, amended-design
| status | opened | located-in | fixed-by | amended-design | |||
|---|---|---|---|---|---|---|---|
| located | 2026-10-01 |
|
190 — The container runtime's configuration is written by modules that are not the runtime's
What was observed
The runtime's configuration file and its service are declared by two parties, neither of which is the runtime:
- The resolver module writes the runtime's
dnskey (the machine's private address) andlive-restoreinto the runtime's file, written into rather than over (ADR 0102). It also declares the runtime's service, reloaded when that file changes. Thednskey has been written since the resolver module was converted from its predecessor on 2026-09-23;live-restoreand the service were added on 2026-09-30 while fixing issue 110, where containers silently resolved through a public resolver. - The private network writes the runtime's
insecure-registriesinto the same file, and declares the same service reloaded on it, as ADR 0082 and ADR 0102 decided. The controller generates both resources per machine.
On the three machines that run the resolver module, both declare one path and one unit. Nothing refuses it. The collision check compares the resources of catalogue modules. The private network is computed, so its resources are produced when a machine's declaration is composed, and the check never sees them.
The machine without the resolver module shows the other half. Its runtime still has the predecessor's
resolver and live-restore off, because the only module that sets them is a DNS server. A machine
gets a correct container runtime only as a side effect of being given a resolver.
Why this is here
The operator ruled it a defect, not a design: a module does not write another software's configuration. The need behind each write is real. Containers must resolve the mesh's names (ADR 0148 step 2). A daemon restart must not stop every container. Every machine on the network must trust the mesh's registry. But each of these is a fact the runtime must be given, and the module that gives it is the runtime's own. With three writers, nobody can say what the file should contain. Two of the facts are reloaded when one of them needs a restart (issue 110's first fault). And the moment a module for the runtime exists, it is refused on every machine with the resolver, or, through the private network's path, accepted without anyone noticing a collision.
What resolves it
ADR 0166 gives the runtime a module that holds its seat and owns its file and service. ADR 0164 gives that module declared settings with defaults. The fix, once both are accepted:
- The resolver module drops its runtime file and runtime service. It knows nothing of the runtime.
- The private network stops generating either resource. ADR 0082's decision stands — being on the network is what grants the trust, and no module author is involved — and only who writes it moves. The mesh gives the registry to the runtime module as a value. ADR 0082 and ADR 0102 each get a dated note saying where their mechanism now lives.
- The runtime module writes
dns,live-restoreandinsecure-registries, each a declared setting with its cost:dnscosts a restart, whichlive-restoremakes harmless. - Steps 1–3 land in one push. A runtime module declaring the file beside a resolver module still declaring it is refused.
- The collision check sees a computed module's resources as well, so a second writer cannot come back through generated code.
Open questions
- How the resolver's address reaches the runtime. Either the resolver seat (
node-dns-resolver) delivers an address its holder serves, or the runtime module reads a machine fact and the seat being held is only a precondition. The first tracks a resolver moving off the private address. The second needs nothing new. - What
dnsdefaults to on a machine with no resolver seat held. Nothing, leaving the runtime's own behaviour, is the honest default. A public resolver hides exactly the failure issue 110 took a day to find. - The adopted machine's predecessor values. The runtime module adopting a file with a
hand-written
dnsandlive-restore: falsereplaces both. That is intended, and is the one restart the operator must make on that machine.