Ответ
Kubernetes для реализации limits и requests на уровне узлов (нод) полагается на механизм ядра Linux — control groups (cgroups). Именно cgroups обеспечивают изоляцию, учет и ограничение ресурсов (CPU, память, disk I/O) для группы процессов (в данном случае — для контейнера).
Как это работает:
- Когда kubelet создает контейнер через container runtime (например, containerd), он передает параметры лимитов.
- Runtime создает для контейнера cgroup в соответствующей подсистеме (например,
cpuиmemory). - В эту cgroup помещаются все процессы контейнера, и к ней применяются заданные ограничения.
Конкретные реализации:
- CPU limits: Используется подсистема
cpuи механизм CFS (Completely Fair Scheduler) Bandwidth Control. Лимит (cpu.cfs_quota_us) определяет, сколько микросекунд CPU времени контейнер может использовать за период (cpu.cfs_period_us, обычно 100ms). - Memory limits: Используется подсистема
memory. При достижении жесткого лимита (memory.limit_in_bytes) ядло Linux активирует OOM Killer, который завершает процесс в контейнере.
Пример манифеста и его низкоуровневое отображение:
# Pod spec в Kubernetes
spec:
containers:
- name: app
resources:
requests:
memory: "256Mi"
cpu: "500m"
limits:
memory: "512Mi"
cpu: "1"
На узле это приведет к созданию cgroup, например, по пути /sys/fs/cgroup/memory/kubepods/pod-<uid>/container-<id>/, где в файл memory.limit_in_bytes будет записано значение 536870912 (512 MiB).
Для работы необходима поддержка cgroups в ядре и корректная настройка kubelet (флаги --cgroup-driver, --enforce-node-allocatable).