Guided Problem
MiniDock Build 26: Resolve Live Names Without Leaking Them
- Time
- 25m
- Level
- intermediate
- Artifacts
- not specified
DNS and Service Discovery
Design claim: Service discovery should resolve stable network-scoped names to current endpoints rather than expose container lifetimes.
Starting model
- You can expose one private service endpoint without changing what the external client sees.
- The useful vocabulary at this point is deliberately small: embedded DNS, service name, network scope, live endpoint.
Stable intent meets replaceable endpoints
A route worker must reach the current cache instance after replacements without learning or storing its changing address. Connectivity is a set of scoped attachments, routes, and names, not an intrinsic property of a container record.
The tempting shortcut is straightforward: write container IP addresses into application configuration. The shortcut works only while addresses are static and every participant shares one host or trust zone. Container endpoints are allocated and released dynamically, and the same name may resolve differently across isolated networks. Endpoint churn, isolation, or a second host exposes the missing scope and ownership information.
Derive names from live membership
The engine maintains network-scoped name records derived from live endpoint membership and answers queries through an embedded resolver. The mechanism separates membership from packet movement so drivers can implement the same connection contract at different boundaries.
Read the topology by following an endpoint from its sandbox through the selected network boundary, keeping control information separate from packet flow.
flowchart LR
APP["app in sandbox
resolv.conf → 127.0.0.11"] --> EDNS["embedded DNS
(engine-served)"]
EDNS -- "name on a shared network?" --> TBL[("engine's live tables
db → 172.19.0.3")]
EDNS -- "unknown name" --> UP["upstream DNS
(host's resolvers)"]
TBL --> A1["answer: container IP"]
UP --> A2["answer: internet IP"]
It places an embedded resolver between network-scoped names and current endpoints. Its central claim is that name resolution reflects current membership within the caller's network scope; the labels therefore describe authority rather than decorative grouping.
Register on join, forget on leave
Dynamic IPs are only a problem if anything remembers them. The fix: make the engine the authority for names. Each sandbox's /etc/resolv.conf points at 127.0.0.11 — an address the engine intercepts and serves itself, backed by its live container tables. Resolution is scoped: a lookup for db answers only if a container named db (or carrying that network alias) shares a network with the asker — the same segmentation from Lesson 28, extended to names. Anything unknown (like example.com) is forwarded to real upstream DNS. Because answers come from live state, recreating db with a new IP updates the answer instantly; nothing anywhere holds a stale address.
Endpoint join registers names, a sandbox query is answered within its network scope, and leave removes the stale address before reuse. Trace both the forward and cleanup paths; connectivity is correct only when allocation and removal agree about ownership.
The second figure tests the same model in motion: it traces registration, query, replacement, withdrawal, and fresh resolution.
sequenceDiagram
participant A as app (in web's sandbox)
participant D as embedded DNS (127.0.0.11)
participant T as engine tables
participant U as upstream DNS
A->>D: resolve "db"
D->>T: container "db" on a network shared with web?
T-->>D: yes — 172.19.0.3
D-->>A: 172.19.0.3 (fresh from live state)
A->>D: resolve "api.stripe.com"
D->>U: forward
U-->>D: 54.187.x.x
D-->>A: 54.187.x.x
It traces registration, query, replacement, withdrawal, and fresh resolution. The ordering is valid only when it continues to preserve the stated invariant under retries and interruption.
Freshness and scope are part of the answer
A cache container is replaced, so the old address must stop resolving and the new endpoint must become discoverable without leaking across networks. A stale or conflicting attachment must be refused or withdrawn locally rather than corrupting unrelated network state.
Name resolution reflects current membership within the caller's network scope. The rule binds reachability to explicit, current membership within the correct scope.
Give MiniDock live service names
MiniDock lets ParcelFlow depend on service names while keeping endpoint churn inside the network control plane. MiniDock now needs that connectivity property without being told which component to edit.
What carries forward
- Name resolution reflects current membership within the caller's network scope.
- Keep service discovery current and prevent private names from leaking across network boundaries.
- The rejected shortcut remains a diagnostic: if the design starts depending on it again, the original constraint has probably been lost.
See what actually stuck.
Take the practice scenarios now.