Разбор инцидента на Linux за десять команд: что смотреть в первые десять минут
Сервер тормозит или сервис упал. Десять команд, которые за несколько минут показывают, где проблема: перезагрузки, журнал ядра, упавшие службы, диск и inode, память, процессор и steal, процессы в состоянии D, ввод-вывод, сеть, время и контейнеры. Как читать их вместе и чего не делать до того, как собраны факты.
Коротко. До любых действий:
uptimeиlast(была ли перезагрузка), журнал ядра (OOM, ошибки диска),systemctl --failed,df -hиdf -i,freeиvmstat(обязательно колонкаst),psс сортировкой и процессы вD,iostatили/proc/pressure,ss,chronyc tracking,docker ps -a. Записывайте сессию черезscript. Перезагрузка без сбора фактов стирает причину.
Звонок: «всё тормозит» или «сервис не открывается». Рука тянется перезагрузить сервер. Иногда это даже помогает, но причину вы уже не узнаете: перезагрузка стирает журнал ядра в памяти, зависшие процессы и сетевые соединения, то есть все улики. Ниже десять команд, которые стоит выполнить до любых действий. Они только читают и безопасны на рабочем сервере. Вместе они занимают несколько минут и почти всегда показывают, в какую сторону копать: диск, память, процессор, сеть или время.
Симптом
- Пользователи жалуются на медленную работу или ошибки, причина неизвестна.
- Служба упала или перезапускается по кругу.
- Сервер отвечает на ping, а вход по SSH занимает минуту.
- Мониторинга нет или он показывает «всё зелёное».
Перед началом: запишите сессию
script -a ~/incident-$(date +%F-%H%M).log
Всё, что вы введёте и увидите дальше, сохранится в файл. Выход из записи по exit. Для разбора после инцидента
и для вендора этот файл ценнее любых воспоминаний.
Большинству команд ниже нужен sudo: журнал ядра и чужие процессы обычному пользователю видны не полностью.
Десять команд
1. Сколько работает и была ли перезагрузка
uptime
last -x reboot shutdown | head -5
uptime показывает время работы и среднюю нагрузку за 1, 5 и 15 минут. Нагрузку сравнивают с числом ядер
(nproc): 8 на восьмиядерном сервере это полная загрузка, 40 значит очередь из процессов. Если время работы
несколько минут, а перезагрузку никто не делал, дальше ищите в журнале, почему сервер перезапустился.
2. Журнал ядра
journalctl -k -p warning --since "1 hour ago"
# или, если journald не хранит журнал ядра:
dmesg -T --level=err,warn | tail -50
Здесь видно то, что не попадает в журналы приложений: срабатывание OOM killer
(Out of memory: Killed process), ошибки ввода-вывода
диска, task ... blocked for more than 120 seconds, недоступный сетевой диск
(nfs: server not responding). Одна такая строка часто сразу
объясняет инцидент.
3. Что упало
systemctl --failed
journalctl -p err -b --since "1 hour ago" | tail -50
Список служб в состоянии failed и все ошибки с момента загрузки за последний час. Для упавшей службы дальше
смотрят systemctl status имя и journalctl -u имя -n 100.
4. Диск: место и inode
df -hT -x tmpfs -x devtmpfs -x overlay
df -i
lsof -nP +L1 | head
Заполненный на 100 % раздел ломает всё сразу: база перестаёт писать, журналы обрываются, служба не стартует
(No space left on device). df -i показывает inode: место есть,
а файлы не создаются, потому что кончились inode, обычно из-за миллиона мелких файлов. lsof +L1 находит
удалённые файлы, которые ещё держит процесс: df показывает раздел полным, а du не находит, чем он занят.
5. Память и процессор одним взглядом
free -h
vmstat -w 1 5
В free смотрите колонку available, а не free: Linux занимает свободную память под кэш, и маленькое free
это норма. Тревожно, когда мало available и растёт использование swap.
vmstat раз в секунду показывает главные счётчики. Первую строку пропустите, это среднее с момента загрузки.
| Колонка | Что значит | Когда тревожно |
|---|---|---|
r |
процессы в очереди на процессор | постоянно больше числа ядер |
b |
процессы, ждущие ввода-вывода | больше нуля несколько секунд подряд |
si, so |
чтение и запись swap | не ноль: памяти не хватает |
wa |
процессор ждёт диск | десятки процентов |
st |
время, отнятое у виртуальной машины гипервизором | больше 5–10 % |
Колонку st часто пропускают. Высокое значение означает, что процессор забирают соседи по физическому
хосту. Мы видели виртуальные машины с отнятыми 60–70 % процессора: внутри всё выглядит как нехватка ядер,
и никакая настройка приложения не помогает. Это вопрос к администратору виртуализации или облака.
6. Кто ест ресурсы и кто завис
ps -eo pid,user,%cpu,%mem,rss,etime,cmd --sort=-%cpu | head -15
ps -eo pid,user,%cpu,%mem,rss,etime,cmd --sort=-rss | head -15
ps -eo stat,pid,wchan:32,cmd | grep '^D'
Первые две команды показывают лидеров по процессору и по памяти. Третья показывает процессы в состоянии D:
они ждут ввода-вывода и не реагируют даже на kill -9. Колонка wchan подсказывает, чего именно они ждут.
Много процессов в D с упоминанием nfs в wchan значит, что завис сетевой диск, а не приложение.
7. Ввод-вывод диска
iostat -xz 1 3
Команда из пакета sysstat. Смотрите на последний замер: %util близко к 100 и r_await или w_await
в десятки миллисекунд на SSD значат, что диск не справляется. Если sysstat не установлен, а ставить
пакеты во время аварии не хочется, есть счётчики давления ядра:
cat /proc/pressure/io /proc/pressure/memory /proc/pressure/cpu
some avg10=35.00 значит, что за последние 10 секунд хотя бы один процесс 35 % времени ждал этот ресурс.
Строка full показывает время, когда ждали все. Счётчики есть в ядрах начиная с 4.20, если они включены
при сборке.
8. Сеть
ss -s
ss -tlnp
ss -tan state time-wait | wc -l
ss -s даёт сводку соединений. ss -tlnp показывает, какие порты слушаются и каким процессом: если служба
работает, а порта в списке нет, она запустилась, но не открыла порт. Десятки тысяч соединений в TIME-WAIT
говорят о том, что приложение открывает новое соединение на каждый запрос вместо того, чтобы держать пул.
Доступность соседей проверяйте по имени, как это делает приложение:
getent hosts db01
curl -sv --max-time 5 https://db01:8443/ -o /dev/null
getent проверяет разрешение имени так же, как приложение, с учётом /etc/hosts. curl -v показывает,
на каком шаге всё ломается: DNS, соединение, TLS или ответ.
9. Время
timedatectl
chronyc tracking
Расхождение часов не проявляется явно. Вход по Kerberos отказывает
(Clock skew too great), токены считаются просроченными,
журналы разных серверов не сходятся при разборе. System clock synchronized: no или смещение в секунды
стоит исправить, даже если причина инцидента окажется не в этом.
10. Контейнеры
docker ps -a --format 'table {{.Names}}\t{{.Status}}'
docker stats --no-stream
Ищите статусы Restarting и Exited и время работы: контейнер, который «Up 2 minutes» на сервере
с недельным аптаймом, перезапускается. Код выхода 137 означает, что контейнер убили, чаще всего за превышение
лимита памяти (OOMKilled, exit code 137). Для Podman команды те же.
Как читать вместе
| Что видно | Куда копать |
|---|---|
Высокая нагрузка, процессор простаивает, высокий wa, процессы в D |
диск или сетевой диск |
Высокий st в vmstat |
гипервизор, соседи по хосту |
Мало available, si/so не ноль, OOM в журнале ядра |
память, утечка или лимиты |
r намного больше числа ядер, us под 100 % |
процессор, конкретный процесс из ps |
Раздел 100 % или IUse% 100 % |
место или inode |
Служба активна, порта в ss -tlnp нет |
служба не поднялась до конца, смотреть её журнал |
Ошибки входа и токенов, смещение в chronyc |
время |
Что сделать
- Сохранить вывод команд и время каждого шага: по ним потом восстанавливают последовательность событий.
- Снять симптом: освободить место, перезапустить упавшую службу, отключить источник нагрузки. Только после того, как собраны факты.
- Записать, какое правило мониторинга сработало бы раньше пользователей: место на разделе, steal, процессы
в
D, смещение времени. Какие правила стоит держать, разобрано в статье про мониторинг Directum RX.
Чего не делать
- Не перезагружать сервер до сбора фактов. Журнал ядра в памяти, зависшие процессы и соединения исчезнут вместе с причиной.
- Не удалять большой журнал, в который пишет процесс. Место не освободится, пока процесс держит файл открытым.
Очищайте содержимое через
truncate -s 0 файлили перезапускайте процесс. - Не запускать
du -sh /*илиfind /на перегруженном диске и на сетевых дисках. Вы добавите нагрузку на тот самый ресурс, который и так не справляется. Начните сdfи узкого каталога. - Не лечить память через
echo 3 > /proc/sys/vm/drop_caches. Кэш освободится и тут же наполнится снова, а диску станет только хуже. - Не убивать процессы базы данных через
kill -9. Для PostgreSQL это аварийный перезапуск всего кластера с восстановлением.
Похожая картина у вас?
Разберём ваш контур за 30 минут бесплатного созвона: версия RX, состав сервисов, что болит сильнее всего.
Написать