AxisOps Harbour
Labs

Insights

cgroups, and the decade before anyone noticed

Control groups merged into Linux 2.6.24, released January 2008 (kernel.org). For most of the six years that followed, they were something your init system set up and you never thought about again.

Then containers staked real isolation promises on them, and a design that had grown one controller at a time started showing its seams.

The v1 problem

v1 lets you have a separate hierarchy per controller. You can mount memory with one tree and cpu with a different one, and a process can sit at inconsistent positions in each.

That sounds like flexibility. In practice it makes two things very hard:

  • Reasoning about a process. Answering "what limits apply here" means walking several unrelated trees and hoping.
  • Delegating a subtree safely. Without a single hierarchy there's no single thing to hand over.

It also produces real ambiguity in accounting. There's no unarguable answer to which cgroup a page gets charged to when it's shared between processes in different cgroups, and v1 made several choices inconsistently across controllers.

What v2 changes

A single unified hierarchy. Every controller sees the same tree. Delegation becomes a coherent operation, because a subtree is a subtree for all controllers at once. Tejun Heo's rework has been landing piecewise since 3.16 behind the __DEVEL__sane_behavior mount flag (kernel source), and the direction is settled even if the merge is not.

The cost is a compatibility break, and that is the part to plan for. Every container runtime, every init system and every monitoring agent that reads /sys/fs/cgroup is written against v1 paths. Our bet is that distributions will keep defaulting to v1 for years after v2 lands, that runtimes will carry both code paths for most of a decade, and that you will be reading cgroup.controllers and memory.stat with two parsers for the whole of that period. Budget for the second parser now.

Delegation is the part worth being excited about, and it is the part nobody is talking about yet. A coherent subtree is a thing you can hand to someone who is not root.

Here at AxisOps that is the capability we want. Give a developer a slice of a real machine, with a hard memory ceiling and a CPU weight, and let them own it. No hypervisor, no second kernel to patch, no ticket to the infrastructure team to resize anything. The university department that today buys four underused servers because three research groups will not share one can run all three on one box and have the accounting to prove nobody is being robbed. The hosting company that today sells you a VM because that is the only unit it can bill safely can sell you a process instead, at a fraction of the overhead.

For engineering the win is a whole class of outage disappearing. The runaway job that eats all the RAM and takes the host with it is the oldest shared-box failure there is, and memory.max on a delegated subtree contains it: the job dies inside its own budget instead of taking the box with it. The box still shares a kernel, CPU and I/O, so the neighbour is contained rather than abolished. Every on-call engineer has been paged for the runaway job at least once.

And the mechanism is in your kernel, readable, with no licence and no account. That matters more than it sounds.

Who ends up owning this

The kernel side stays open; nobody can take /sys/fs/cgroup away from you. Ownership changes one layer up, at the registry.

docker pull goes to one default public index run by one company. The image format is open and so is the daemon, but the place everybody fetches from is neither distributed nor accountable. That is where the leverage sits: whoever runs the default registry decides what your build depends on, sees every pull your estate makes and can price or revoke access once enough of the industry has wired it into CI. A pull log is a remarkably good map of what a company is building and when it ships.

Our view, and we will keep saying it: run your own registry, mirror what you depend on and treat the public index as a convenience you can survive losing. The technology does not require a landlord. The default configuration supplies one anyway, and defaults are how estates get captured.

Why this one matters

It's the clearest example of a pattern that keeps returning: a mechanism designed as plumbing becomes an interface the moment something popular depends on it, and decisions that were fine as plumbing become constraints everyone downstream inherits, overnight.

It's the extension lead running under the carpet because it was only meant to be there for a fortnight; now the whole office is plugged into it.

The lesson isn't "design for the future". Nobody was going to predict containers from 2008. It's that the second system has to carry the first one for years, and that cost belongs in the estimate.