Ответ
В production средах я использую несколько уровней ограничения ресурсов Docker контейнеров для обеспечения стабильности и предотвращения "шумного соседа".
1. Ограничения на уровне docker run:
# CPU ограничения
docker run --cpus="1.5" myapp # Максимум 1.5 ядра
docker run --cpu-shares=512 myapp # Относительный вес (по умолчанию 1024)
docker run --cpuset-cpus="0-3" myapp # Закрепление за конкретными ядрами
# Память
docker run --memory="512m" --memory-swap="1g" myapp
# memory-swap = memory + swap, -1 отключает swap
# I/O ограничения
docker run
--device-read-bps="/dev/sda:1mb"
--device-write-iops="/dev/sda:100"
myapp
# Количество процессов (PID)
docker run --pids-limit=100 myapp # Защита от fork-бомб
2. Docker Compose (версия 3.x+):
version: '3.8'
services:
app:
image: myapp:latest
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.1'
memory: 128M
3. Практические примеры из моей практики:
Для базы данных PostgreSQL:
docker run --name postgres
--memory="2g" --memory-swap="2g" # Без swap для БД
--cpus="2"
--blkio-weight=500 # Приоритет дискового I/O
-e POSTGRES_PASSWORD=secret
postgres:14
Для кэша Redis:
docker run --name redis
--memory="1g" --memory-swap="1g"
--cpus="0.5"
--sysctl net.core.somaxconn=1024
redis:7-alpine
4. Мониторинг и диагностика:
# Проверка текущего использования
docker stats
# Детальная информация
docker inspect --format='{{.HostConfig.Memory}}' container_name
# Просмотр cgroups
cat /sys/fs/cgroup/memory/docker/<container-id>/memory.limit_in_bytes
5. Продвинутые сценарии:
-
CPU Quota и Period:
# Ограничение: 50% CPU каждые 100ms docker run --cpu-period=100000 --cpu-quota=50000 myapp -
OOM Killer настройки:
docker run --oom-kill-disable --memory="1g" --oom-score-adj=-500 # Меньше шансов быть убитым myapp -
ULIMITs наследование:
docker run --ulimit nofile=1024:1024 myapp
6. Интеграция с оркестраторами:
В Kubernetes эти ограничения задаются через:
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
Ключевые принципы, которых я придерживаюсь:
- Всегда устанавливаю limits для production контейнеров
- Начинаю с консервативных значений и настраиваю по метрикам
- Использую мониторинг (Prometheus + cAdvisor) для сбора метрик
- Тестирую ограничения под нагрузкой
- Для stateful сервисов (БД) отключаю или строго ограничиваю swap
- Регулярно ревьюю и корректирую лимиты на основе фактического использования