The runtime's file is written by the runtime's module, not by what decides how a machine resolves (issue 190)
resolv-conf would have taken over dnsmasq's write into daemon.json — the same defect issue 190 names. docker, on every machine, now writes live-restore and reloads its own service. Log rotation is left as each machine has it.
This commit is contained in:
+37
-51
@@ -14,6 +14,8 @@ tools below are the module's own.
|
||||
| `socket` | `docker.socket` running, enabled at boot | given back as found when the module goes (ADR 0118) |
|
||||
| `prune-service`, `prune-timer` | `/etc/systemd/system/docker-prune.{service,timer}`, written whole | removed with the module |
|
||||
| `prune` | `docker-prune.timer` running, enabled at boot; restarted when either file changes | stopped and disabled with the module (the mesh made the unit) |
|
||||
| `daemon` | `live-restore` written into `/etc/docker/daemon.json`, beside other keys | the key given back as found when the module goes |
|
||||
| `runtime` | `docker.service` running, enabled at boot; reloaded, never restarted, when `daemon` changes | given back as found (ADR 0118) |
|
||||
|
||||
The weekly prune takes **dangling images and build cache unused for a week, and nothing else**. It
|
||||
takes no volume, no container and no image a container uses, so it never touches a container the mesh
|
||||
@@ -24,62 +26,47 @@ while the machine was off happens at the next boot.
|
||||
`container-runtime`: under ADR 0165, which is still proposed, that word means a running daemon, and
|
||||
the module that installs the daemon cannot require it.
|
||||
|
||||
## The runtime's own file and service (issue 190, hq ADR 0196)
|
||||
|
||||
This module writes one key into `/etc/docker/daemon.json` (`into: json`, ADR 0102): `live-restore`.
|
||||
`dnsmasq` used to write it, beside `dns`; it no longer writes either. Under ADR 0196 a container
|
||||
copies its machine's resolvers, so no module writes `dns`.
|
||||
|
||||
- `daemon`: `{"live-restore": true}`, merged into the file beside the keys others write.
|
||||
- `runtime`: `docker.service` running, enabled at boot, and **reloaded, never restarted**, when
|
||||
`daemon` changes. A restart stops every container. A reload turns `live-restore` on, and with it on
|
||||
a later restart keeps every container running.
|
||||
|
||||
In the apply that moves the key, the host first gives back `dnsmasq`'s resources, then applies this
|
||||
module's: `live-restore` is set again in the same apply, and the daemon is reloaded once.
|
||||
|
||||
`dns` is removed from the file then, but the daemon reads it only at its next start, and a running
|
||||
container keeps the resolvers it was created with. Each container pinned to a machine's own resolver
|
||||
is restarted before that machine's `dnsmasq` goes (ADR 0194, step 4).
|
||||
|
||||
Still elsewhere:
|
||||
|
||||
- **The private network**, generated by the controller (`internal/overlay/generator.go`), writes
|
||||
`insecure-registries`. The collision check does not see generated resources. **Later:** the
|
||||
controller hands the registry to this module as a value, and the overlay stops generating its two
|
||||
resources (issue 190, steps 2 and 5). The host merges disjoint keys correctly; the mesh-host
|
||||
`into.go` record is per resource.
|
||||
- **Nobody** writes log rotation. One machine has `log-driver` and `log-opts` by hand; they are left
|
||||
as they are until a size is chosen for every machine.
|
||||
|
||||
## What it does not declare yet, and why
|
||||
|
||||
Three things this module should own are already declared by other modules on every machine. The
|
||||
controller refuses two modules on one node that declare the same `path`, `unit`, `name` or `package`
|
||||
(`checkResources`, mesh-controller `internal/catalogue/resolve.go`). Declaring any of them here would
|
||||
make the module unassignable everywhere. The refusals were checked against the controller's own
|
||||
One thing this module should own is still declared elsewhere. The controller refuses two modules
|
||||
on one node that declare the same `path`, `unit`, `name` or `package` (`checkResources`,
|
||||
mesh-controller `internal/catalogue/resolve.go`), so declaring it here would make the module
|
||||
unassignable everywhere. The refusals were checked against the controller's own
|
||||
check:
|
||||
|
||||
```
|
||||
zsh and docker both declare the name "${machine:account}"
|
||||
dnsmasq and docker both declare the path "/etc/docker/daemon.json"
|
||||
dnsmasq and docker both declare the unit "docker.service"
|
||||
```
|
||||
|
||||
### 1. `/etc/docker/daemon.json` and `docker.service` (issue 190)
|
||||
|
||||
Today the file has three writers. Each writes into it (`into: json`, ADR 0102) and reloads the
|
||||
service:
|
||||
|
||||
- **`dnsmasq`** writes `dns` and `live-restore`, through `dnsmasq.runtime-dns` and `dnsmasq.runtime`.
|
||||
- **The private network**, generated by the controller (`internal/overlay/generator.go`), writes
|
||||
`insecure-registries`. The collision check does not see generated resources.
|
||||
- **Nobody** writes log rotation. One machine has `log-driver` and `log-opts` by hand.
|
||||
|
||||
**The change proposed, in one merge:**
|
||||
|
||||
1. `dnsmasq` drops its `runtime-dns` and `runtime` resources.
|
||||
2. `docker` adds the two resources below:
|
||||
|
||||
```json
|
||||
{"id": "daemon", "type": "file", "path": "/etc/docker/daemon.json", "mode": "0644", "into": "json",
|
||||
"content": "{\"dns\": [\"${machine:address}\"], \"live-restore\": true, \"log-driver\": \"json-file\", \"log-opts\": {\"max-size\": \"100m\", \"max-file\": \"5\"}}\n"},
|
||||
{"id": "runtime", "type": "service", "unit": "docker.service", "state": "running", "boot": "enabled", "reload-on": ["daemon"]}
|
||||
```
|
||||
|
||||
The service is **reloaded, never restarted**: a restart stops every container. The daemon reads
|
||||
`live-restore` on a reload. It reads `dns`, `log-driver` and `log-opts` only at its next start, so
|
||||
they apply then (to containers created afterwards, for the log keys). With `live-restore` on, that
|
||||
start keeps every container running.
|
||||
|
||||
**Why one merge, and only after this module is on every machine:**
|
||||
|
||||
- In one apply, the host first gives back the resources that are no longer declared, then applies
|
||||
the new ones (mesh-host `apply.go`).
|
||||
- `dnsmasq` gives back `dns` and `live-restore` to what they held before it, and `docker` sets them
|
||||
again in the same apply. The daemon is reloaded once, after both steps.
|
||||
- A machine pushed the new `dnsmasq` *without* this module would keep its pre-mesh values for both
|
||||
keys. On one machine that is `live-restore: false`, and the next daemon restart there would stop
|
||||
every container.
|
||||
|
||||
**Later:** the controller hands the registry to this module as a value, and the overlay stops
|
||||
generating its two resources (issue 190, steps 2 and 5). Until then the overlay keeps writing its one
|
||||
key beside this module's. The host merges disjoint keys correctly; the mesh-host `into.go` record is
|
||||
per resource.
|
||||
|
||||
### 2. The operator account's membership of the `docker` group
|
||||
### The operator account's membership of the `docker` group
|
||||
|
||||
The right shape is the host's `user` shape. Its `groups` are additive: the host runs
|
||||
`usermod --append` and never takes a group away.
|
||||
@@ -111,9 +98,8 @@ On the machine the mesh was first installed on, the foundation bundle declared `
|
||||
never sees them (mesh-host `store.go`).
|
||||
- So `docker.package` here is a **second record of the same package**. The apply says "already
|
||||
installed", and neither record ever uninstalls it.
|
||||
- This module does not declare `docker.service` today, so nothing overlaps there. The proposed step
|
||||
1 would add a second record of that unit. Its found state is *running*, because genesis started
|
||||
it, so undeclaring this module would leave the daemon running.
|
||||
- `docker.runtime` is likewise a second record of `docker.service`. Its found state is *running*,
|
||||
because genesis started it, so undeclaring this module leaves the daemon running.
|
||||
|
||||
## Tools
|
||||
|
||||
|
||||
@@ -50,6 +50,24 @@
|
||||
"state": "running",
|
||||
"boot": "enabled"
|
||||
},
|
||||
{
|
||||
"id": "daemon",
|
||||
"type": "file",
|
||||
"path": "/etc/docker/daemon.json",
|
||||
"mode": "0644",
|
||||
"into": "json",
|
||||
"content": "{\"live-restore\": true}\n"
|
||||
},
|
||||
{
|
||||
"id": "runtime",
|
||||
"type": "service",
|
||||
"unit": "docker.service",
|
||||
"state": "running",
|
||||
"boot": "enabled",
|
||||
"reload-on": [
|
||||
"daemon"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "prune-service",
|
||||
"type": "file",
|
||||
|
||||
@@ -18,23 +18,6 @@
|
||||
"path": "/etc/resolv.conf",
|
||||
"mode": "0644",
|
||||
"content": "# Managed by the mesh.\n#\n# For a machine where nothing else owns this file. On one where systemd-resolved\n# or NetworkManager does, assign that module instead — this one and those claim\n# the same thing, so the mesh refuses the pair rather than letting them take\n# turns overwriting each other, which is the failure this claim exists to stop.\n#\n# The mesh's one resolver first (novox/hq ADR 0194, 0196), by address — a machine\n# cannot resolve the name of the thing it resolves names with. It answers the\n# mesh's names itself and forwards every other name. A public resolver second,\n# asked only when the first does not answer at all — its machine or the tunnel\n# down, a captive portal holding the tunnel back — so public names keep\n# resolving then. An answer from the first, \"no such name\" included, is final,\n# so a mesh name is never asked of the public one while the mesh's answers. One\n# second and one attempt, so the wait before the fallback is short. Containers\n# copy these two lines from their machine.\nnameserver ${bound:wildcard-resolution:address}\nnameserver 1.1.1.1\noptions timeout:1 attempts:1 edns0\n"
|
||||
},
|
||||
{
|
||||
"id": "runtime-config",
|
||||
"type": "file",
|
||||
"path": "/etc/docker/daemon.json",
|
||||
"mode": "0644",
|
||||
"into": "json",
|
||||
"content": "{\"live-restore\": true}\n"
|
||||
},
|
||||
{
|
||||
"id": "runtime",
|
||||
"type": "service",
|
||||
"unit": "docker.service",
|
||||
"state": "running",
|
||||
"reload-on": [
|
||||
"runtime-config"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user