Третья проблема — два контейнера были убиты OOM killer, но Docker не перезапустил их корректно. Причина: контейнеры не имели лимитов памяти и потребляли RAM без ограничений:
# Проверяем OOM-события
dmesg | grep -i 'out of memory\|oom-killer'
# [452167.234] Out of memory: Killed process 18234 (java)
# total-vm:8234567kB, anon-rss:4123456kB
# Текущее потребление памяти контейнерами
docker stats --no-stream --format \
'table {{.Name}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.PIDs}}'
# NAME MEM USAGE / LIMIT MEM % PIDS
# payment-gateway 1.8GiB / 15.5GiB 11.6% 45
# payment-worker 4.2GiB / 15.5GiB 27.1% 387
# notification-svc 892MiB / 15.5GiB 5.6% 12
Лимит «15.5 GiB» — это вся RAM хоста. Контейнер без лимита может сожрать всю память и убить соседей.
# docker-compose.yml — устанавливаем лимиты
services:
payment-gateway:
image: paygate/gateway:latest
deploy:
resources:
limits:
memory: 2G
cpus: '2.0'
reservations:
memory: 512M
cpus: '0.5'
# Политика перезапуска
restart: unless-stopped
Отдельная бомба замедленного действия — логи контейнеров. Docker по умолчанию хранит stdout/stderr контейнеров в JSON-файлах без ротации:
# Размер логов контейнеров
du -sh /var/lib/docker/containers/*/
# 8.7G /var/lib/docker/containers/a1b2c3.../ ← один контейнер!
ls -lh /var/lib/docker/containers/a1b2c3*/*-json.log
# -rw-r----- 1 root root 8.7G Mar 16 /var/lib/docker/containers/a1b2c3.../*-json.log
8.7 GB логов одного контейнера за полгода! Настраиваем ротацию глобально:
# /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "5"
},
"storage-driver": "overlay2",
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 65536,
"Soft": 65536
}
}
}
Оставить комментарий