budgeted agents throttle at 90% of the cap; alert on repeated oom kills
This commit is contained in:
parent
c014b48c22
commit
11393bc538
3 changed files with 201 additions and 27 deletions
|
|
@ -446,11 +446,12 @@ changed cap reaches them at the next container start without a rebuild.
|
|||
`hyperhive-memory-cap-check.service` logs a warning naming the path in the
|
||||
container's journal. The container's `MemoryMax=` still applies.
|
||||
|
||||
A container with a finite `MemoryMax=` also gets `MemorySwapMax=0` in the same
|
||||
drop-in, so a budgeted agent never swaps: paging it out to host swap would
|
||||
move the pressure onto the host. `MemoryMax=infinity` leaves swap alone. Like
|
||||
the rest of the drop-in, it reaches a running agent at its next spawn or
|
||||
rebuild.
|
||||
A container with a finite `MemoryMax=` also gets, in the same drop-in,
|
||||
`MemorySwapMax=0` and `MemoryHigh=` at 90% of the cap (bytes, rounded down).
|
||||
A budgeted agent never swaps: paging it out to host swap would move the
|
||||
pressure onto the host. Past 90% the kernel slows the container and reclaims
|
||||
from it, and at 100% it kills. `MemoryMax=infinity` sets neither. Like the
|
||||
rest of the drop-in, they reach a running agent at its next spawn or rebuild.
|
||||
|
||||
When the container reaches its cap, the kernel kills inside it, in this order:
|
||||
|
||||
|
|
@ -474,6 +475,8 @@ is the memory the container has swapped out: nonzero only for an agent with
|
|||
no budget, or one whose container started before its drop-in carried
|
||||
`MemorySwapMax=0`.
|
||||
|
||||
More than 3 kills of one agent in an hour raise the `hh-agent-oom-kills` alert.
|
||||
|
||||
<details><summary>Implementation: swarm caps</summary>
|
||||
|
||||
swarm-controller keeps the caps in the `agent-limits` KV bucket, one key per
|
||||
|
|
|
|||
|
|
@ -560,6 +560,7 @@ The swarm Grafana (`nix/host-modules/swarm-grafana.nix`) alerts on these:
|
|||
| `hh-hive-degraded` | `hyperhive.hive.degraded` is `1` for 2 minutes |
|
||||
| `hh-hive-warning` | any `hyperhive.hive.warning` series other than `disk_pressure` exists (`pending_logins` only for a hive that doesn't export `hyperhive.agent.needs_login`) for 2 minutes |
|
||||
| `hh-agent-needs-login` | `hyperhive.agent.needs_login` is `1` for an agent for 5 minutes, one alert per agent |
|
||||
| `hh-agent-oom-kills` | `hyperhive.container.memory.oom_kills` grew by more than 3 in the last hour for an agent, one alert per agent, no delay |
|
||||
| `hh-host-disk-high` | `hyperhive.hive.nix_store.utilization` stays above 0.85 for 10 minutes |
|
||||
| `hh-host-disk-critical` | `hyperhive.hive.nix_store.utilization` stays above 0.95 for 2 minutes |
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ known operations; there is no arbitrary command pass-through:
|
|||
| `ReloadGatewayNginx` | `systemctl reload/start/reset-failed nginx` (host unit; the unit name is hard-coded, not a parameter) |
|
||||
| `WriteNspawnFlags` | write `/etc/nixos-containers/<container>.conf` (bind-mount list, network isolation vars, and `--ephemeral` after the root's salvage). hive-priv first copies a stopped container's root to the agent's `work/`, then renames it aside (it deletes nothing), following no link the container could have planted; for an agent whose closure record sets `private_users` it also adds `--private-users=pick`, mounts every bind `owneridmap`, and once chowns the agent's `state`, `harness`, `work` and `claude` dirs (never `config`, following no link) to the data owner |
|
||||
| `EnsureAgentSocketDir` | `mkdirat` `/run/hive-agent/<name>` `0751 root:root` under an `O_NOFOLLOW` parent fd; leaves an existing directory alone, refuses anything else; for an agent whose closure record sets `private_users` it then chowns the dir to the data owner |
|
||||
| `WriteResourceLimits` | write `CPUQuota=`/`MemoryMax=`/`CPUWeight=`/`IOWeight=` systemd drop-in for agent container, with an `ExecStartPre=` that runs `hive-priv check-rootfs <container>` (no-follow check of the root paths the start script touches; see persistence.md), and a GC root on the build it names |
|
||||
| `WriteResourceLimits` | write `CPUQuota=`/`MemoryMax=`/`MemoryHigh=`/`MemorySwapMax=`/`CPUWeight=`/`IOWeight=` systemd drop-in for agent container, with an `ExecStartPre=` that runs `hive-priv check-rootfs <container>` (no-follow check of the root paths the start script touches; see persistence.md), and a GC root on the build it names |
|
||||
| `RemoveServiceDropin` | remove `container@<name>.service.d/` drop-in on destroy, and the GC root of the hive-priv build it named |
|
||||
| `DaemonReload` | `systemctl daemon-reload` |
|
||||
| `ControlInfraContainer` | `systemctl <action> nginx.service` for the gateway — the `InfraContainer` enum is the allowlist, and serde rejects unknown names at the wire boundary (`hive-c0re`, the forge and the matrix have no variant, so no request can name them) |
|
||||
|
|
|
|||
Loading…
Reference in a new issue