При эксплуатации Linux-сервисов периодически встречается ситуация: процесс завершается, но в логах приложения нет явной причины ошибки.
Первое, что обычно проверяем — состояние сервиса через systemd:
systemctl status api.service
Например, в выводе можно увидеть:
Active: failed (Result: signal)
Этот статус показывает только факт завершения процесса, но не объясняет, что именно произошло. Чтобы найти причину, нужно посмотреть сообщения ядра Linux. Одна из распространённых причин внезапного завершения процессов — срабатывание
OOM Killer.OOM Killer — это механизм ядра, который включается при критической нехватке памяти и завершает выбранные процессы, чтобы система продолжила работу. При этом важно понимать: причина может быть не только в полном исчерпании памяти сервера, но и в ограничениях, заданных через cgroup.Проверяем события
OOM в логах ядра:journalctl -k | grep -Ei "out of memory|killed process|oom"
Также можно использовать:
dmesg -T | grep -Ei "killed process|out of memory|oom"
Например:
Out of memory: Killed process 4210 (java)
anon-rss:16000000kB
Из этого видно, что ядро завершило процесс Java из-за проблем с памятью. Следующий вопрос при расследовании — почему именно этот процесс был выбран.
Для работающего процесса можно проверить значение:
cat /proc/<PID>/oom_score
oom_score показывает относительную вероятность выбора процесса механизмом OOM Killer. Чем выше значение, тем выше вероятность завершения процесса при нехватке памяти.Также существует параметр:
cat /proc/<PID>/oom_score_adj
Он позволяет изменить приоритет процесса. Значения находятся в диапазоне от -1000 до 1000. Чем ниже значение, тем меньше вероятность завершения процесса. Значение -1000 полностью исключает процесс из выбора
OOM Killer.Для сервисов под systemd такие настройки корректнее задавать через unit-файл:
[Service]
MemoryMax=4G
OOMScoreAdjust=-500
После изменения конфигурации:
systemctl daemon-reload
systemctl restart api.service
При работе с контейнерами важно учитывать ещё один сценарий: проблема может быть не в памяти хоста, а в ограничении
cgroup.Например, сервер может иметь свободную память, но контейнер ограничен параметром
memory limit. После превышения этого значения процесс внутри контейнера будет завершён.Проверяем ограничение памяти Docker:
docker inspect -f '{{.HostConfig.Memory}}' container_name
Текущее потребление:
docker stats
Для анализа
cgroup также полезно проверить события памяти:memory.events
В Kubernetes аналогичная ситуация отображается через:
kubectl describe pod api
В выводе будет:
Reason: OOMKilled
Это означает, что контейнер превысил установленный
limits.memory. При диагностике OOM важно определить, где именно возникло ограничение: на уровне памяти хоста, systemd/cgroup, Docker или Kubernetes.🔥 Основная задача при расследовании — определить, какой процесс был завершён, какой механизм инициировал завершение и какое ограничение памяти стало причиной события.
🚪 Linux Ready | #практика