Skip to content

[Request]: --swap and a [container] swap default, so a container over its memory limit is reclaimed rather than killed #2181

Description

@MayCXC

Describe the feature

Give container run and container create a --swap option, and [container] swap in the configuration to default it, so a container whose workload exceeds its memory limit is reclaimed to a swap area rather than killed.

Motivation

A container that goes over --memory today meets the out of memory killer, with nothing between the two. The runtime it sits on can hand the guest a swap area to reclaim to instead, but nothing here asks for one.

Swap is also the only container resource with no configurable default: --cpus and --memory both fall back to their [container] keys, so a --swap added without [container] swap beside it would be the odd one out.

Shape I have implemented and would propose:

  • --swap takes a size, kept on the container's resources beside the memory limit it plays against. The size counts swap alone rather than the memory-and-swap total the runtime spec carries, so it reads against --memory rather than including it.
  • The area is made at bootstrap as a raw block file in the container's own bundle, alongside the root filesystem, which the guest agent writes a swap header to and enables. It holds nothing that outlives the container, so it is made afresh at each bootstrap and the host is told not to synchronize it.
  • The backing file is sparse. The guest reaches the area as a block device, which the kernel takes as a single extent without consulting the host's layout, so the hole-free requirement that binds a swap file inside the guest does not bind the host file backing the device: https://github.com/torvalds/linux/blob/master/mm/swapfile.c . Sparse backing costs the host only the pages the guest has actually swapped out and gives them back on discard.
  • [container] swap defaults to zero, so a container still gets no area unless one is asked for, and resolves the way cpus and memory resolve.

Alternatives considered

Leaving the limit as a hard wall and letting the OOM killer act: that is today's behaviour, and it is the right default, which is why the default here stays zero.

Dependency

The guest half lives in Containerization: apple/containerization#877 for the design discussion and apple/containerization#878 for the implementation. A --swap here needs that to be in the runtime the CLI sits on.

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions