Какие механизмы позволяют лимитировать ресурсы для контейнера в Linux?

«Какие механизмы позволяют лимитировать ресурсы для контейнера в Linux?» — вопрос из категории Linux, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Ограничение ресурсов для контейнеров в Linux обеспечивается в первую очередь двумя ключевыми механизмами ядра: cgroups и namespaces. Docker, containerd и другие контейнерные runtime являются пользовательскими интерфейсами для управления ими.

1. Control Groups (cgroups): Это механизм ядра для ограничения, учета и изоляции использования ресурсов группой процессов.

  • CPU: Можно ограничить долю CPU (cpu.shares) или установить жесткий лимит (cpu.cfs_quota_us / cpu.cfs_period_us).
  • Память: Устанавливается лимит на использование RAM (memory.limit_in_bytes) и подкачки (memory.memsw.limit_in_bytes). При превышении лимита OOM Killer завершит процесс в контейнере.
  • I/O диска: Ограничение скорости чтения/записи для блочных устройств (blkio.throttle.read_bps_device).

2. Namespaces: Обеспечивают изоляцию, позволяя контейнеру иметь собственное представление о системе (сеть, процессы, файловая система и т.д.). Хотя namespaces напрямую не лимитируют ресурсы, они являются необходимой основой для изоляции.

Практический пример через Docker:

# Запуск контейнера с ограничениями
sudo docker run -d 
  --name limited-app 
  --memory="512m"           # Лимит оперативной памяти
  --memory-swap="1g"        # Лимит памяти + swap
  --cpus="1.5"             # Доступно 1.5 ядра CPU
  --cpu-shares=512          # Относительный вес при конкуренции за CPU
  --blkio-weight=100        # Относительный вес для I/O
  nginx:alpine

# Проверка установленных лимитов
sudo docker stats limited-app

Проверка cgroups напрямую (внутри контейнера):

# Для просмотра лимита памяти
cat /sys/fs/cgroup/memory/memory.limit_in_bytes
# Для просмотра лимита CPU (в микросекундах)
cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
cat /sys/fs/cgroup/cpu/cpu.cfs_period_us

Именно cgroups позволяют гарантировать, что один "шумный" контейнер не исчерпает все ресурсы хоста, влияя на другие сервисы.