Пара 5 / октябрь
Пользователи, права доступа и файловые объекты Читать права Linux и устранять отказ в доступе без chmod 777.
Читать права Linux и устранять отказ в доступе без chmod 777. ls -l показывает тип, права, владельца и группу. Девять битов rwx разбиты на владельца, группу и остальных. Для файла r — читать, w — менять содержимое, x — запускать. Для каталога x позволяет проходить по пути, r — перечислять имена, w вместе с нужными правами позволяет менять записи. Удаление определяется правами родительского каталога, а не только правом записи самого файла. Это важный поворот для студентов: права — не характеристика «могу всё», а правила конкретной операции. Сначала выясняем пользователя id и путь namei -l, затем меняем минимальные права.
Контекст Доступ проверяется для конкретного пользователя и объекта.
Читать права Linux и устранять отказ в доступе без chmod 777.
ls -l показывает тип, права, владельца и группу. Девять битов rwx разбиты на владельца, группу и остальных. Для файла r — читать, w — менять содержимое, x — запускать. Для каталога x позволяет проходить по пути, r — перечислять имена, w вместе с нужными правами позволяет менять записи. Удаление определяется правами родительского каталога, а не только правом записи самого файла. Это важный поворот для студентов: права — не характеристика «могу всё», а правила конкретной операции. Сначала выясняем пользователя id и путь namei -l, затем меняем минимальные права.
Владелец, группа, остальные Доступ проверяется для конкретного пользователя и объекта.
01 Пользователь
→ 02 Владелец / группа
→ 03 Права объекта
→ 04 Разрешить / отказать
Аналогия: пропуск в коридор и ключ от комнаты — разные разрешения.
ls -l показывает тип, права, владельца и группу. Девять битов rwx разбиты на владельца, группу и остальных. Для файла r — читать, w — менять содержимое, x — запускать. Для каталога x позволяет проходить по пути, r — перечислять имена, w вместе с нужными правами позволяет менять записи. Удаление определяется правами родительского каталога, а не только правом записи самого файла. Это важный поворот для студентов: права — не характеристика «могу всё», а правила конкретной операции. Сначала выясняем пользователя id и путь namei -l, затем меняем минимальные права.
Числа прав 4 = чтение, 2 = запись, 1 = выполнение.
01 r = 4
02 w = 2
03 x = 1
04 640 = rw- r-- ---
Права не шифруют файл и не защищают от администратора системы.
Числовая запись суммирует биты: 6 означает чтение и запись, 5 — чтение и выполнение, 7 — всё. 640 даёт владельцу rw, группе r и остальным ничего; 750 подходит для каталога или программы с ограниченным доступом. Символьная запись chmod u+x иногда понятнее числа, потому что добавляет конкретное право. umask ограничивает начальные права новых файлов, но не исправляет существующие. Не превращаем 777 в универсальный рецепт: это часто маскирует неправильного владельца, путь или пользователя процесса. В WSL изучаем права на Linux-файловой системе в /home, поведение /mnt/c может зависеть от параметров монтирования.
sudo и секреты Повышаем привилегии только для обоснованной операции.
01 Минимальные права
→ 02 Отдельная конфигурация
→ 03 Не публиковать
→ 04 Ротация при утечке
Аналогия: мастер-ключ не используют, чтобы открыть собственный письменный стол.
sudo запускает разрешённую команду с другой идентичностью, часто root. Root может повредить систему; наличие sudo не означает, что его нужно ставить перед python или git. Секреты не кладём в репозиторий и не показываем на общем экране. .env — просто файл, а не защищённое хранилище. Ограничьте права учебного файла chmod 600 и добавьте .env в .gitignore позже. В учебных упражнениях применяем фиктивные значения. Если реальный секрет попал в историю Git, удалить строку недостаточно: секрет нужно отозвать и заменить. Здесь это принцип, а не требование настраивать корпоративный vault.
Команды и наблюдения Ubuntu / Bash
cd ~/devops-course/sandbox
printf "demo-only
" > private.env
chmod 600 private.env
ls -l private.env
id
printf "#!/usr/bin/env bash
printf 'hello\n'
" > hello.sh
chmod u+x hello.sh
./hello.shЗначение demo-only не является настоящим секретом. Обсудите разницу ./hello.sh и bash hello.sh: во втором случае файл читает интерпретатор. Ожидаемое наблюдение: private.env имеет -rw-------; hello.sh запускается после добавления x владельцу.
Разбор результата private.env имеет -rw-------; hello.sh запускается после добавления x владельцу.
Значение demo-only не является настоящим секретом. Обсудите разницу ./hello.sh и bash hello.sh: во втором случае файл читает интерпретатор.
Проверьте id, ls -l run.sh, namei -l путь. Для собственного файла chmod u+x run.sh. Для собственного каталога chmod u+x nested. Не делайте рекурсивную смену прав на домашней папке. Если студент случайно ограничил каталог, сохраняйте открытый терминал и восстанавливайте права конкретного каталога из его родителя.
На macOS Основные rwx и chmod переносимы. namei -l отсутствует: проверяйте каждый родительский каталог через ls -ld, а ACL через ls -le. macOS дополнительно применяет ACL, privacy-разрешения и системные защиты; Permission denied не всегда объясняется только девятью битами.
id
ls -l private.env
chmod 600 private.env
chmod u+x hello.sh
ls -lde . private.envКоманды macOS необходимо проверить на конкретном устройстве. Основные rwx и chmod переносимы. namei -l отсутствует: проверяйте каждый родительский каталог через ls -ld, а ACL через ls -le. macOS дополнительно применяет ACL, privacy-разрешения и системные защиты; Permission denied не всегда объясняется только девятью битами.
Исправить доступ по доказательствам Создайте run.sh без executable-бита; воспроизведите отказ через ./run.sh. Проверьте владельца и права, исправьте только право запуска владельца. Создайте вложенный каталог и уберите u+x; покажите проблему прохода, затем восстановите право. Объясните, почему chmod 777 и sudo bash не являются хорошим исправлением. Работа в парах: один оператор, второй проверяет гипотезу. Смена ролей в середине. Проверьте id, ls -l run.sh, namei -l путь. Для собственного файла chmod u+x run.sh. Для собственного каталога chmod u+x nested. Не делайте рекурсивную смену прав на домашней папке. Если студент случайно ограничил каталог, сохраняйте открытый терминал и восстанавливайте права конкретного каталога из его родителя.
Что должно получиться До/после прав и объяснение причины каждого отказа.
Скрипт работает без sudo; секретный учебный файл имеет права 600.
Проверьте id, ls -l run.sh, namei -l путь. Для собственного файла chmod u+x run.sh. Для собственного каталога chmod u+x nested. Не делайте рекурсивную смену прав на домашней папке. Если студент случайно ограничил каталог, сохраняйте открытый терминал и восстанавливайте права конкретного каталога из его родителя.
Ошибка для диагностики Ошибка возникает на родительском каталоге, а не на самом файле.
Симптом → Гипотеза → Проверка
Проверьте id, ls -l run.sh, namei -l путь. Для собственного файла chmod u+x run.sh. Для собственного каталога chmod u+x nested. Не делайте рекурсивную смену прав на домашней папке. Если студент случайно ограничил каталог, сохраняйте открытый терминал и восстанавливайте права конкретного каталога из его родителя.
Основные выводы Владелец rw, группа r, остальные без прав. Пользователя процесса, объект, родительские каталоги и нужную операцию. Владелец rw, группа r, остальные без прав.
Пользователя процесса, объект, родительские каталоги и нужную операцию.
После пары Описать минимальные права для кода, конфигурации и каталога данных учебного сервиса.
Конспект, команды и разбор → Проверьте критерии сдачи и дайте возможность повторной попытки. Первоисточники: https://ubuntu.com/server/docs/ https://man7.org/linux/man-pages/man1/chmod.1.html
Пара 6 / октябрь
Процессы, сигналы, IPC и наблюдение ресурсов Находить свой процесс и завершать его штатно; различать память и дисковое пространство.
Находить свой процесс и завершать его штатно; различать память и дисковое пространство. PID идентифицирует процесс в текущем пространстве имён. У процесса есть родитель, окружение, открытые файлы, память и код завершения. Один исполняемый файл может породить несколько процессов. ps показывает снимок, top — обновляемое представление. Процесс может работать, ждать I/O, спать или завершиться. Не делаем вывод «завис» только по нулевому CPU: сервис часто ждёт запрос. Фоновый запуск & возвращает shell управление, но не создаёт надёжный системный сервис. После закрытия сеанса процессы могут получить SIGHUP; для постоянного запуска позже используем менеджер служб.
Контекст Используем имена сигналов; их номера и обработка зависят от платформы.
Находить свой процесс и завершать его штатно; различать память и дисковое пространство.
Сигнал имеет имя и стандартное действие, если приложение не установило собственный обработчик или не изменило disposition. SIGINT связан с обычным Ctrl+C, SIGTERM используется для завершения, SIGKILL принудительно завершает без обработчика, SIGSTOP приостанавливает, SIGCONT продолжает. SIGCHLD сообщает об изменении состояния детей: сбор статуса выполняется wait. SIGPIPE может возникнуть при записи в pipe/socket без получателя; программа может обрабатывать ошибку другим способом. SIGHUP исторически связан с hangup; многие daemon используют его для reload только по собственному соглашению. SIGUSR1/2 также имеют смысл, установленный конкретной программой. SIGSEGV связан с ошибкой доступа к памяти, SIGALRM — с таймером. Не все сигналы означают смерть процесса. Стандартные сигналы могут объединяться при повторной доставке, поэтому их нельзя воспринимать как надёжную очередь произвольного числа событий; real-time сигналы имеют другую механику. Номера Linux и macOS могут различаться, особенно у USR и CHLD. Shell kill -l показывает локальные имена/номера.
PID и жизненный цикл Процесс — выполняющаяся программа с ресурсами и состоянием.
01 Запуск
→ 02 PID / ресурсы
→ 03 Работа / ожидание
→ 04 Завершение
Аналогия: рецепт — программа, повар за работой — процесс.
PID идентифицирует процесс в текущем пространстве имён. У процесса есть родитель, окружение, открытые файлы, память и код завершения. Один исполняемый файл может породить несколько процессов. ps показывает снимок, top — обновляемое представление. Процесс может работать, ждать I/O, спать или завершиться. Не делаем вывод «завис» только по нулевому CPU: сервис часто ждёт запрос. Фоновый запуск & возвращает shell управление, но не создаёт надёжный системный сервис. После закрытия сеанса процессы могут получить SIGHUP; для постоянного запуска позже используем менеджер служб.
Сигналы и корректное завершение Сначала просим остановиться, потом применяем крайние меры.
01 Проверить PID
→ 02 SIGTERM
→ 03 Ожидать
→ 04 SIGKILL при необходимости
Аналогия: просьба закрыть магазин и аварийное отключение электричества имеют разные последствия.
Ctrl+C обычно отправляет SIGINT группе процессов переднего плана. kill PID по умолчанию посылает SIGTERM; приложение может обработать его, завершить текущую работу и закрыть файлы. SIGKILL не даёт выполнить очистку и используется как крайний шаг после диагностики. Номер PID нужно проверить непосредственно перед сигналом: нельзя бездумно копировать чужой PID. Работаем только с созданным учебным sleep. Не используем широкие pkill python, которые могут остановить чужие задачи. Студент сначала показывает команду процесса, затем делает адресное завершение.
CPU, RAM и диск Ресурсы отвечают на разные диагностические вопросы.
01 CPU: вычисление
02 RAM: рабочие данные
03 Диск: сохранение
04 I/O: ожидание
Аналогия: повар, рабочий стол и кладовая — разные ограничения кухни.
free -h показывает память, df -h — свободное место файловых систем, du -sh — размер дерева файлов. Высокое использование RAM не всегда плохо: Linux использует кеш, поэтому обращаем внимание на available и характер нагрузки. При недостатке памяти ядро может убить процесс; нужно искать доказательство в доступных журналах, а не угадывать. Заполненный диск мешает записывать результаты, хотя памяти может быть достаточно. WSL2 имеет собственные ограничения ресурсов; не переносим числа со студенческого ноутбука на сервер. Объясните разницу единиц и то, что проценты зависят от числа ядер и инструмента.
Программа лежит на диске, процесс живёт в системе Один и тот же код может иметь несколько независимых экземпляров.
Один файл программы может быть запущен как два независимых процесса Файл app.py на диске Код: инструкция для запуска запуск запуск Процесс A · PID 4100 Адресное пространство, FD, cwd, UID Процесс B · PID 4200 Свои память, состояние, дескрипторы Переменная counter = 5 Переменная counter = 0 Программа — файл/код; процесс — выполняющийся экземпляр с ресурсами. Обычно нет: у разных процессов отдельные адресные пространства. Общую память нужно организовать отдельно.
Процесс — экземпляр выполнения с PID, виртуальным адресным пространством, открытыми дескрипторами, текущим каталогом, окружением и идентичностью пользователя. Код программы на диске и память работающего процесса — разные объекты: изменение app.py не обязано изменить уже запущенный процесс. Если дважды запустить одну программу, у экземпляров будут разные PID и своё состояние, даже когда они читают тот же исходник. PID имеет смысл внутри пространства имён и может быть повторно использован после завершения; не воспринимайте его как вечный уникальный идентификатор. PPID показывает текущего родителя. Процесс имеет хотя бы один поток исполнения. Команда ps показывает снимок, поэтому результат может поменяться между проверкой и действием. Перед отправкой сигнала сверяем PID и команду собственного учебного процесса.
Аналогия: две копии рецепта готовят два повара с разными рабочими столами. Общие файлы всё ещё могут создавать конфликты.
Обычно нет: у разных процессов отдельные адресные пространства. Общую память нужно организовать отдельно.
fork, exec и wait делают разные вещи Новый PID появляется при создании ребёнка; exec сохраняет PID.
fork создаёт ребёнка, exec заменяет программу ребёнка, wait собирает статус РОДИТЕЛЬ Shell · PID 4000 Запустить sleep fork Shell · PID 4000 Ждёт ребёнка waitpid Shell · PID 4000 Получил exit status ребёнок Копия · PID 4100 fork вернул 0 exec sleep · PID 4100 PID сохранился exit → wait Учебный путь fork + exec; реализации также используют posix_spawn / clone. Нет. Изменяется выполняемый образ программы в том же процессе.
В учебной Unix-модели shell создаёт ребёнка через fork. В родителе возвращается PID ребёнка, в ребёнке — 0, поэтому один исходный участок кода продолжает работу по двум веткам. Ребёнок затем вызывает exec: ядро заменяет его образ программы, загружает новый код и исходное состояние. При успешном exec выполнение к прежнему коду не возвращается. PID остаётся тем же: это не создание третьего процесса. Родитель может ждать ребёнка через waitpid и получить статус завершения. Современные runtime и shell могут использовать posix_spawn или другие механизмы; наша цель — понять модель, а не обещать одинаковый syscall trace любого запуска. В демонстрации используем однопоточный Python и простую дочернюю команду, чтобы не переносить сложные ограничения fork многопоточных приложений в вводную практику.
Аналогия: созданному сотруднику назначили новую инструкцию; его табельный номер остался прежним. Память процесса заменяется намного строже, чем человеческая инструкция.
Нет. Изменяется выполняемый образ программы в том же процессе.
fork не обязан сразу копировать всю RAM Copy-on-write откладывает копирование страниц до изменения.
При fork страницы памяти сначала разделяются, запись вызывает копирование Родитель Виртуальная страница A Ребёнок Виртуальная страница A Физическая страница Общее исходное содержимое Новая страница Изменение ребёнка write → copy Copy-on-write откладывает копирование. Запись ребёнка не меняет память родителя. Нет при обычной частной памяти. COW сохраняет отдельность адресных пространств.
В Linux fork использует copy-on-write: виртуальные адресные пространства различаются, но неизменённые страницы могут ссылаться на одни физические данные. Когда одна сторона пишет в такую страницу, ядро организует отдельную копию. Это объясняет, почему логическая копия процесса не всегда немедленно удваивает всю фактическую память. Изменение переменной в ребёнке не меняет переменную родителя. Общие описания открытых файлов — другое дело: наследованные дескрипторы могут ссылаться на один open file description и общий offset. RSS двух процессов нельзя механически складывать и считать уникальной потреблённой RAM; в более глубоком анализе учитывают разделяемые страницы и PSS. На первом курсе по DevOps важнее понять предел аналогии «fork копирует всё», чем вычислять память по одному ps.
Аналогия: две версии документа сначала ссылаются на общие страницы, но правки создают отдельную страницу. Это не общий изменяемый список.
Нет при обычной частной памяти. COW сохраняет отдельность адресных пространств.
Процесс владеет ресурсами, потоки выполняют код Потоки одного процесса разделяют память, поэтому нужен контроль совместных изменений.
Потоки одного процесса разделяют память, планировщик запускает потоки на CPU ПРОЦЕСС: ОБЩИЕ HEAP И FD Поток T1 Свои stack и registers Поток T2 Свои stack и registers Общие данные Нужна синхронизация CPU core 0 Исполняет runnable поток scheduler CPU core 1 Другой поток / процесс scheduler Много потоков не гарантирует ускорение: есть ожидание, блокировки и ограничения runtime. Потоки могут ждать I/O, блокировки, runtime или CPU; есть накладные расходы.
Потоки имеют собственный стек, регистры и контекст исполнения, но в пределах процесса обычно разделяют адресное пространство и таблицу дескрипторов. Два потока могут читать и изменять один объект — появляются гонки, которые не устраняются самим фактом «оба потока в Python». Планировщик распределяет runnable-потоки по CPU; ожидание сети или диска освобождает возможность выполнить других. На одном ядре параллельность ощущается через чередование, на нескольких ядрах возможна реальная одновременность. Число потоков не равно числу используемых CPU: runtime, блокировки, I/O и ограничения контейнера меняют картину. Версии CPython и режимы исполнения различаются, поэтому не формулируем вечное правило про любой Python. Для урока достаточно разделить процесс, поток и ядро CPU.
Аналогия: сотрудники работают за общим столом с общими бумагами. Несколько рук ускоряют не каждую операцию и требуют согласования.
Потоки могут ждать I/O, блокировки, runtime или CPU; есть накладные расходы.
Процесс может существовать и не использовать CPU Ожидание, остановка и завершение — разные состояния.
Состояния процесса: готов к CPU, выполняется, ждёт, завершился Runnable · R Готов / исполняется I/O Sleeping · S / D Ожидает событие событие завершилось Stopped · T SIGSTOP / SIGCONT STOP CONT exit Zombie · Z Остался статус завершения Удалена запись Родитель вызвал wait wait ps R включает running и runnable. D — непрерываемое ожидание; Z уже не исполняет код. Нет. Он может штатно ожидать таймер или данные; проверяем ожидаемое поведение.
В Linux ps STAT показывает состояние и дополнительные признаки. R объединяет выполнение и готовность к исполнению; S означает прерываемое ожидание, часто таймер, сеть или ввод. D — непрерываемое ожидание, часто связанное с I/O; сигнал может не проявиться до выхода из этого ожидания. T — остановленное состояние: код пока не выполняется, но ресурсы остаются. Z — процесс уже завершился, а запись со статусом ещё ожидает родителя. Состояния меняются быстро, поэтому ps даёт лишь моментальный снимок. Сон не равен сбою, а CPU 0% не доказывает исправность: процесс может ждать навсегда. На опыте sleep обычно S; SIGSTOP переводит собственный процесс в T, SIGCONT разрешает выполнение снова. Не отправляем сигналы PID 1 или произвольным процессам группы.
Аналогия: работник ждёт доставку, а не исчезает из штата. Зомби уже закончил работу и хранится только учётная запись.
Нет. Он может штатно ожидать таймер или данные; проверяем ожидаемое поведение.
kill — запрос ядру отправить сигнал SIGTERM позволяет обработку; SIGKILL не даёт программе выполнить очистку.
Штатное завершение даёт программе время очистить ресурсы Оператор / менеджер Отправляет SIGTERM Живой процесс Обработчик: завершиться Очистка → exit Закрыть данные и запросы Не завершён вовремя Истёк заданный timeout SIGKILL Нельзя обработать Ядро завершает Без cleanup приложения kill отправляет сигнал. Ctrl+C обычно посылает SIGINT foreground-группе. Она лишает приложение возможности штатно завершить работу и может скрыть причину отказа.
Сигнал — асинхронное уведомление процессу с определённым действием. SIGTERM обычно просит завершение; программа может установить обработчик, закончить текущую работу и выйти. Если обработчика нет, действует стандартное поведение. SIGKILL и SIGSTOP нельзя поймать или игнорировать. Ctrl+C в обычном терминале инициирует SIGINT для foreground process group, поэтому это не всегда сигнал только одному PID. Утилита kill не гарантирует, что процесс немедленно исчез: сигнал может быть обработан позже, а непрерываемое ожидание задерживает реакцию. Штатная остановка важна для сохранения данных, но сам SIGTERM ничего автоматически не сохраняет — очистка должна быть реализована приложением. В лабораторной начинаем с обычного TERM собственного sleep, затем ждём его через shell.
Аналогия: попросить закрыть магазин и выдернуть питание — разные действия. SIGKILL не является безопасной процедурой сохранения данных.
Она лишает приложение возможности штатно завершить работу и может скрыть причину отказа.
Зомби уже завершился, сирота потерял родителя Лечение зависит от того, какая связь нарушена.
Зомби и сирота означают разные события Ребёнок завершился Родитель ещё не вызвал wait Zombie: запись со статусом Родитель забирает статус → запись исчезает Родитель завершился первым Ребёнок ещё может работать Orphan: меняется родитель Reaper / subreaper / PID 1 в namespace Сирота может исполняться; зомби уже завершился. kill -9 не «оживляет» wait. Нет. Это завершённый процесс с ещё не собранным статусом; сирота — другая ситуация.
Когда ребёнок выходит, ядро сохраняет минимальную запись, чтобы родитель получил статус через wait. Пока этого не произошло, ps может показывать Z. Такой процесс уже не исполняет код; отправка kill не заменяет обязанности родителя собрать статус. Если первым завершился родитель, живой ребёнок становится сиротой. В Linux его подхватывает соответствующий reaper или subreaper, с учётом PID namespace; упрощение «любой сирота всегда получает host PID 1» неверно для всех контейнерных случаев. Сирота может продолжать полезную работу и не обязан стать зомби. Корректный менеджер процессов следит за детьми и собирает статусы. Поэтому PID 1 внутри контейнера должен правильно обрабатывать сигналы и дочерние процессы; небольшой init полезен, если приложение не выполняет эту роль.
Аналогия: зомби — незакрытая карточка законченной работы, сирота — продолжающий работу сотрудник с новым руководителем.
Нет. Это завершённый процесс с ещё не собранным статусом; сирота — другая ситуация.
POSIX-сигналы: уведомление и стандартное действие Используем имена сигналов; их номера и обработка зависят от платформы.
POSIX-сигналы: имена и назначение SIGINT Прерывание с терминала SIGCHLD Событие дочернего процесса SIGTERM Запрос завершения SIGPIPE Запись без читателя SIGKILL Без обработчика SIGUSR1/2 Событие по договору приложения SIGSTOP Остановить, не завершить SIGSEGV Ошибка доступа к памяти SIGCONT Продолжить исполнение SIGALRM Таймер SIGHUP Hangup; reload по договору SIGQUIT Прерывание с core по умолчанию Числа сигналов зависят от платформы. SIGKILL/SIGSTOP нельзя обработать; reload не встроен в SIGHUP. SIGHUP не перезагружает любую программу автоматически. SIGKILL и SIGSTOP невозможно поймать или игнорировать.
Сигнал имеет имя и стандартное действие, если приложение не установило собственный обработчик или не изменило disposition. SIGINT связан с обычным Ctrl+C, SIGTERM используется для завершения, SIGKILL принудительно завершает без обработчика, SIGSTOP приостанавливает, SIGCONT продолжает. SIGCHLD сообщает об изменении состояния детей: сбор статуса выполняется wait. SIGPIPE может возникнуть при записи в pipe/socket без получателя; программа может обрабатывать ошибку другим способом. SIGHUP исторически связан с hangup; многие daemon используют его для reload только по собственному соглашению. SIGUSR1/2 также имеют смысл, установленный конкретной программой. SIGSEGV связан с ошибкой доступа к памяти, SIGALRM — с таймером. Не все сигналы означают смерть процесса. Стандартные сигналы могут объединяться при повторной доставке, поэтому их нельзя воспринимать как надёжную очередь произвольного числа событий; real-time сигналы имеют другую механику. Номера Linux и macOS могут различаться, особенно у USR и CHLD. Shell kill -l показывает локальные имена/номера.
SIGHUP не перезагружает любую программу автоматически. SIGKILL и SIGSTOP невозможно поймать или игнорировать.
IPC: взаимодействие отдельных адресных пространств Канал и формат сообщения определяют, как процессы согласуют работу.
Процессы общаются через явные каналы, а не общую случайную переменную Процесс A Отдельная память Процесс B Отдельная память Pipe / FIFO Поток байтов Unix / TCP socket Согласованный протокол Shared memory + синхронизация доступа Сигналы уведомляют о событиях; они не заменяют протокол передачи большого сообщения. Отдельная память процессов не исключает общую память; она появляется только при специально организованном mapping и согласовании доступа.
Pipe передаёт поток байтов, FIFO даёт похожий механизм с именем в файловой системе. Unix-domain socket связывает локальные процессы, TCP/UDP socket — процессы через сетевой стек. Shared memory позволяет отображать общие страницы, но требует locks, semaphores или другого протокола синхронизации, иначе появляются гонки. Сигналы удобны для уведомлений вроде terminate/reload; большие данные лучше передавать через явный канал. Файлы тоже используются для взаимодействия, но тогда надо определить атомарность записи и обнаружение изменений. Протокол сообщает, где заканчивается сообщение, какая версия формата используется и что делать при ошибке. TCP даёт поток без встроенных границ JSON: один write не гарантирует один read. В нашем API HTTP задаёт рамки запроса и ответа, а серверные процессы читают данные через socket.
Отдельная память процессов не исключает общую память; она появляется только при специально организованном mapping и согласовании доступа.
Socket — объект ядра и программный интерфейс IP-адрес и порт относятся к сетевому варианту, Unix socket может быть локальным.
Socket API соединяет процессы локально или через сетевой стек Client socket connect → write/read TCP/IP стек Адрес, маршрут, порт Server socket bind → listen → accept Unix-domain socket Локальный канал: pathname / namespace; транспорт TCP/IP не требуется Socket — объект ядра с дескриптором. TCP-соединение не равно одному сообщению HTTP. LISTEN подтверждает слушателя. HTTP 200 дополнительно подтверждает конкретный ответ приложения; это разные уровни проверки.
Сервер создаёт socket, делает bind к выбранному адресу и порту, listen переводит TCP socket в режим приёма соединений, accept возвращает отдельный socket для клиента. Клиент делает connect, затем стороны читают и пишут. Listening socket и connected socket — разные объекты. TCP-соединение идентифицируется адресами/портами и протоколом, поэтому множество клиентов может приходить на один порт 8000. UDP не использует тот же listen/accept lifecycle; это datagram транспорт. Unix-domain socket работает локально и может использовать pathname, например /run/service.sock, либо другие namespace-механизмы. Сокет доступен через file descriptor, но это не обычный файл с сохранённой историей пакетов. Ss показывает Linux sockets и их состояние; macOS обычно используют lsof. Bind 127.0.0.1 принимает локальные обращения, 0.0.0.0 расширяет область слушания и требует понимания сетевого доступа.
LISTEN подтверждает слушателя. HTTP 200 дополнительно подтверждает конкретный ответ приложения; это разные уровни проверки.
top и htop — начало диагностики Загрузка CPU, ожидание I/O и нехватка RAM имеют разные признаки.
top/htop показывают симптомы, дальнейшая проверка связывает их с причиной Высокий CPU top / htop: процессы, threads Память / swap free, vmstat, OOM journal I/O / диск df, du, ожидание D Адресная проверка PID + журнал + реальный запрос Load average — не CPU%. В Linux учитывает runnable и непрерываемые ожидания. Ubuntu: top -b -n 1; ps -eo pid,ppid,stat,pcpu,pmem,comm --sort=-pcpu; free -h; vmstat 1 3.
Top периодически показывает нагрузку, CPU, память и процессы. Htop предоставляет другой интерактивный интерфейс, дерево и удобный выбор колонок; его установка не меняет механизм планирования Linux. %CPU относится к интервалу и выбранному режиму отображения; многопоточный процесс может использовать больше одного ядра. Linux load average учитывает runnable и задачи в непрерываемом ожидании, поэтому не равен проценту CPU. Высокий load при низком CPU может быть связан с I/O, но нужно подтвердить это состояниями и измерениями. RSS, VSZ и swap нельзя трактовать как одно число «памяти программы». Процесс D требует исследования устройства и kernel journal, S часто штатно ждёт. Для API связываем PID, состояние, журнал и запрос, иначе даже красивый график не доказывает причину. Режим top -b удобен для сохранения короткого снимка.
Ubuntu: top -b -n 1; ps -eo pid,ppid,stat,pcpu,pmem,comm --sort=-pcpu; free -h; vmstat 1 3.
sysctl — настройки работающего ядра Текущие значения и сохранённая конфигурация — разные состояния.
sysctl показывает или меняет отдельные параметры работающего ядра sysctl vm.swappiness Чтение текущего значения /proc/sys/vm/swappiness Linux-интерфейс runtime параметра /etc/sysctl.d/*.conf Политика после старта Загрузчик конфигурации Применяет настройки; файл сам не изменяет ядро В курсе читаем параметры. Изменение требует понятного эффекта и отката; sysctl Mac имеет другой набор ключей. Чтение безопасно для наблюдения; изменение параметра — отдельное управляемое действие, а не универсальный ремонт.
В Linux многие runtime-параметры доступны через /proc/sys. Sysctl читает или записывает эти значения; запись часто требует прав и может изменить сеть, память или безопасность немедленно. Файлы /etc/sysctl.d/*.conf описывают значения для применения системной инфраструктурой, но простое редактирование файла не равняется изменению текущего параметра. Не все свойства ядра настраиваются через sysctl, а набор ключей зависит от версии и сборки. На курсе используем чтение отдельных известных ключей, например vm.swappiness и net.ipv4.ip_forward. Копирование «ускоряющего набора sysctl» из блога не является диагностикой: нужны нагрузка, ожидаемый эффект и план возврата. Sysctl macOS имеет другой набор ключей и значения. Windows имеет другие механизмы конфигурации; Linux ключи туда не переносятся.
Чтение безопасно для наблюдения; изменение параметра — отдельное управляемое действие, а не универсальный ремонт.
Наблюдение механизмов python3 lab/experiments/process_lifecycle.py
sleep 30 &
pid=$!
ps -p "$pid" -o pid,ppid,stat,comm
kill -STOP "$pid"
ps -p "$pid" -o pid,ppid,stat,comm
kill -CONT "$pid"
kill -TERM "$pid"
wait "$pid"
printf "wait status: %s\n" "$?"Полный разбор команд в конспекте → Перед опытом нарисуйте два PID и место exec. Сравните печать child-before-exec и child-after-exec: PID должен совпасть. Родитель получает exit status 7; сам учебный сценарий завершается успешно после проверки. В опыте sleep запишите S/T после сигналов; wait для TERM даёт ненулевой статус (численное представление shell может различаться). Работает в Ubuntu и macOS с python3. Запускайте блок в интерактивном Bash/zsh без режима set -e. Не сохраняйте PID для следующего занятия: его могли переиспользовать.
Снимите три коротких наблюдения собственного сервиса: PID/STAT, LISTEN и ответ HTTP. IPC-опыт использует socketpair и не открывает внешний порт. На Mac доступны ps, top, lsof; Linux sysctl ключи заменяются только после проверки документации.
Команды и наблюдения Ubuntu / Bash
sleep 300 &
DEMO_PID=$!
ps -p "$DEMO_PID" -o pid,ppid,stat,comm
kill -TERM "$DEMO_PID"
wait "$DEMO_PID"
free -h
df -h .
du -sh ~/devops-course$! сохраняет PID именно запущенного фонового процесса. Не подставляем PID из чужого примера. Ожидаемое наблюдение: sleep виден до сигнала и завершается после него; wait может вернуть 143 при SIGTERM, это ожидаемая демонстрация.
Разбор результата sleep виден до сигнала и завершается после него; wait может вернуть 143 при SIGTERM, это ожидаемая демонстрация.
$! сохраняет PID именно запущенного фонового процесса. Не подставляем PID из чужого примера.
Для процесса достаточно ps -p "$DEMO_PID" -o pid,ppid,args и kill -TERM "$DEMO_PID". После wait повторный ps не должен показывать этот процесс. Для исчезнувшего сервиса соберите exit code, журнал, ограничения памяти, размер входа и данные о рестартах. Наличие кода 137 — признак SIGKILL, но само по себе ещё не доказывает OOM.
На macOS ps, сигналы, df и du похожи. free отсутствует: vm_stat показывает страницы памяти; размер страницы указан в первой строке, поэтому не предполагайте 4 KiB. Activity Monitor удобен для общей картины памяти/CPU. Linux-сведения OOM и /proc не переносятся напрямую.
sleep 300 &
DEMO_PID=$!
ps -p "$DEMO_PID" -o pid,ppid,stat,comm
kill -TERM "$DEMO_PID"
wait "$DEMO_PID"
vm_stat
sysctl hw.memsize
df -h .
du -sh ~/devops-courseКоманды macOS необходимо проверить на конкретном устройстве. ps, сигналы, df и du похожи. free отсутствует: vm_stat показывает страницы памяти; размер страницы указан в первой строке, поэтому не предполагайте 4 KiB. Activity Monitor удобен для общей картины памяти/CPU. Linux-сведения OOM и /proc не переносятся напрямую.
Паспорт ресурсов и процесса Запустите собственный sleep, найдите его через ps и запишите PID. Покажите команду и родительский PID; завершите SIGTERM. Сравните размер учебной папки с доступным местом файловой системы. Объясните, какие данные нужны, если сервис исчез при обработке большого входа. Работа в парах: один оператор, второй проверяет гипотезу. Смена ролей в середине. Для процесса достаточно ps -p "$DEMO_PID" -o pid,ppid,args и kill -TERM "$DEMO_PID". После wait повторный ps не должен показывать этот процесс. Для исчезнувшего сервиса соберите exit code, журнал, ограничения памяти, размер входа и данные о рестартах. Наличие кода 137 — признак SIGKILL, но само по себе ещё не доказывает OOM.
Что должно получиться Таблица CPU / RAM / диск и наблюдения процесса.
Ни один чужой процесс не остановлен; память и диск не смешаны.
Для процесса достаточно ps -p "$DEMO_PID" -o pid,ppid,args и kill -TERM "$DEMO_PID". После wait повторный ps не должен показывать этот процесс. Для исчезнувшего сервиса соберите exit code, журнал, ограничения памяти, размер входа и данные о рестартах. Наличие кода 137 — признак SIGKILL, но само по себе ещё не доказывает OOM.
Ошибка для диагностики Студент смотрит df вместо free и неверно объясняет нехватку RAM.
Симптом → Гипотеза → Проверка
Для процесса достаточно ps -p "$DEMO_PID" -o pid,ppid,args и kill -TERM "$DEMO_PID". После wait повторный ps не должен показывать этот процесс. Для исчезнувшего сервиса соберите exit code, журнал, ограничения памяти, размер входа и данные о рестартах. Наличие кода 137 — признак SIGKILL, но само по себе ещё не доказывает OOM.
Основные выводы Не позволяет приложению штатно закрыть ресурсы. Нет, они измеряют разные вещи: файловую систему и дерево файлов. Не позволяет приложению штатно закрыть ресурсы.
Нет, они измеряют разные вещи: файловую систему и дерево файлов.
После пары Написать диагностическую памятку для трёх симптомов: медленно, исчезает, не пишет файл.
Конспект, команды и разбор → Проверьте критерии сдачи и дайте возможность повторной попытки. Первоисточники: https://ubuntu.com/server/docs/ https://man7.org/linux/man-pages/man7/signal.7.html