1. Архитектура Linux и продвинутая работа в терминале
Архитектура Linux и продвинутая работа в терминале
Представьте, что вы нажимаете кнопку включения сервера. Через доли секунды процессор начинает исполнять первые инструкции, а еще через мгновение операционная система берет под контроль гигабайты памяти и десятки ядер. Для обычного пользователя это магия, для системного администратора — штатный процесс, а для DevOps-инженера — фундамент, на котором строятся отказоустойчивые кластеры. Если вы не понимаете, как ядро взаимодействует с «железом» и почему процесс в Linux не может просто так «залезть» в память соседа, вы не сможете эффективно отлаживать контейнеры в Docker или настраивать пайплайны в CI/CD.
Иерархия уровней: от кремния до пользователя
Архитектуру Linux принято представлять в виде слоеного пирога. В самом низу находится аппаратное обеспечение (Hardware), а на самом верху — пользовательские приложения. Между ними располагается ядро (Kernel) и системные библиотеки.
Ключевое различие, которое отделяет Linux от примитивных систем, — это разделение адресного пространства на Kernel Space (пространство ядра) и User Space (пространство пользователя).
Чтобы программа из User Space могла, например, записать файл на диск или отправить пакет в сеть, она должна «попросить» об этом ядро. Этот запрос называется System Call (системный вызов).
> Системный вызов — это единственный легальный способ для программы выйти за пределы своей «песочницы» и взаимодействовать с внешним миром через ядро.
Когда вы вводите команду ls, происходит следующее: оболочка (shell) делает системный вызов fork() для создания нового процесса, затем execve() для запуска кода ls, а сама программа ls делает десятки вызовов openat() и getdents64() для чтения содержимого директории. Понимание этого механизма критично для отладки: если приложение «тормозит», DevOps-инженер использует инструмент strace, чтобы увидеть, на каких системных вызовах оно застревает.
Ядро Linux: монолит с модульным характером
Ядро Linux называют монолитным. Это означает, что все основные компоненты (планировщик задач, файловые системы, драйверы) работают в одном адресном пространстве. Однако оно обладает важным свойством — модульностью. Вам не нужно пересобирать всё ядро, чтобы добавить поддержку новой сетевой карты или файловой системы.
Модули ядра (LKM — Loadable Kernel Modules) можно загружать и выгружать «на лету». Это экономит память и делает систему гибкой. Например, если вы подключаете USB-накопитель, ядро автоматически подгружает модуль usb_storage.
Для управления модулями используются следующие инструменты:
lsmod: выводит список всех загруженных в данный момент модулей.modinfo <имя_модуля>: показывает информацию о модуле (автор, лицензия, параметры).insmod / rmmod: низкоуровневые команды для вставки и удаления модуля (используются редко).modprobe: «умная» команда, которая учитывает зависимости. Если модулю для работы нужен модуль , modprobe загрузит оба.В контексте DevOps модульность важна при работе с Docker и Kubernetes. Например, для работы сетевых плагинов (CNI) часто требуется модуль br_netfilter. Если он не загружен, контейнеры не смогут «общаться» друг с другом через мосты, и ваша задача как инженера — уметь проверить это через lsmod и настроить автозагрузку через файлы в /etc/modules-load.d/.
Файловая иерархия и стандарт FHS
В Linux «всё есть файл». Это не просто красивая фраза, а фундаментальная концепция. Жесткий диск — это файл в /dev/sda, оперативная память — файл (условно), текущие настройки ядра — файлы в /proc.
Чтобы в системе не царил хаос, существует стандарт FHS (Filesystem Hierarchy Standard). Основные точки, которые вы должны знать наизусть:
| Директория | Назначение |
| :--- | :--- |
| /bin, /sbin | Основные исполняемые файлы (ls, cp, ip, fdisk). sbin — для системного администрирования. |
| /etc | Конфигурационные файлы всей системы. Здесь лежат настройки Nginx, SSH, сетевых интерфейсов. |
| /var | Переменные данные: логи (/var/log), базы данных, кэши. |
| /home | Домашние директории пользователей. |
| /root | Домашняя директория суперпользователя. |
| /tmp | Временные файлы (очищаются при загрузке или по расписанию). |
| /proc, /sys | Виртуальные файловые системы. Через них можно смотреть состояние ядра и менять его параметры. |
Особое внимание уделим /proc. Это не данные на диске, это «окно» в память ядра. Например, файл /proc/cpuinfo расскажет всё о процессоре, а в директории /proc/[PID]/ можно найти информацию о конкретном запущенном процессе с идентификатором PID. Если вы хотите узнать, какие лимиты установлены для процесса базы данных, вы заглянете в /proc/1234/limits.
Жизненный цикл процесса и сигналы
Процесс — это экземпляр запущенной программы. У каждого процесса есть свой уникальный номер — PID (Process ID). Иерархия процессов начинается с systemd (или init), который всегда имеет . Все остальные процессы являются его «детьми» или «внуками».
Состояния процесса:
kill -9.Для управления процессами мы используем сигналы. Сигнал — это короткое уведомление, посылаемое процессу.
SIGTERM (15): просьба завершиться красиво. Процесс должен закрыть файлы, сохранить данные и выйти. Это сигнал по умолчанию для команды kill.SIGKILL (9): немедленное уничтожение процесса ядром. Процесс не может проигнорировать этот сигнал.SIGHUP (1): исторически — «обрыв связи с терминалом», сейчас часто используется для того, чтобы заставить сервис перечитать конфигурационные файлы без полной перезагрузки.Продвинутая работа в Bash: конвейеры и перенаправления
Терминал — это основной инструмент DevOps. Если вы тратите время на ручное копирование данных из одного окна в другое, вы работаете неэффективно. Мощь Linux заключается в возможности комбинировать простые утилиты для решения сложных задач.
Перенаправление потоков
У каждого процесса есть три стандартных потока:Примеры манипуляций:
ls > files.txt: направить вывод ls в файл (перезаписать).ls >> files.txt: дописать вывод в конец файла.command 2> error.log: сохранить только ошибки.command > output.log 2>&1: направить и обычный вывод, и ошибки в один файл.Конвейеры (Pipes)
Символ| позволяет передать stdout одной команды на stdin другой. Это основа философии Unix: «Пишите программы, которые делают одну вещь и делают её хорошо. Пишите программы, которые работают вместе».Рассмотрим задачу: найти 5 самых тяжелых лог-файлов в /var/log.
Разбор:
du -ah: оценивает размер файлов в человекочитаемом виде.sort -rh: сортирует строки как числа (-n не сработает с суффиксами G/M, поэтому используем -h) в обратном порядке (-r).head -n 5: оставляет только первые 5 строк.Текстовые процессоры: grep, sed, awk
DevOps-инженер постоянно работает с текстом: конфиги, логи, выводы команд. Умение пользоваться «святой троицей» текстовой обработки экономит часы работы.
Grep: поиск по шаблону
Самый простой инструмент. Позволяет фильтровать строки.grep "ERROR" app.log: найти все строки с ошибками.grep -v "DEBUG": исключить строки с DEBUG.grep -r "127.0.0.1" /etc/: рекурсивный поиск IP во всех файлах в директории.grep -E "[0-9]{1,3}\.": поиск с использованием расширенных регулярных выражений (например, поиск IP-адресов).Sed: потоковый редактор
Используется для замены текста «на лету».sed 's/localhost/127.0.0.1/g' config.conf: заменить все вхождения localhost на IP и вывести результат в терминал.sed -i 's/old/new/g' file.txt: флаг -i (in-place) вносит изменения прямо в файл. Это опасно, поэтому лучше сначала тестировать без него.sed -n '5,10p' file.txt: напечатать только строки с 5 по 10.Awk: мощный обработчик колонок
Awk воспринимает строку как набор полей (колонок). По умолчанию разделитель — пробел или табуляция.awk '{print 3}' file.txt: напечатать первую и третью колонку.last | awk '{print 3 > 1000) print 3) больше 1000.Переменные окружения и настройки Shell
Когда вы вводите python, система не ищет этот файл по всему диску. Она заглядывает в переменную окружения $PATH.
Переменные окружения (Environment Variables) — это глобальные настройки, доступные процессам.
PATH: список директорий, где лежат исполняемые файлы.HOME: путь к домашней директории текущего пользователя.USER: имя текущего пользователя.LANG: настройки локали и кодировки.Для DevOps критически важно понимать разницу между локальными переменными оболочки и переменными окружения.
Если вы запускаете скрипт деплоя, которому нужен API-ключ, вы должны сделать export API_KEY=..., иначе скрипт его не увидит.
Для автоматизации настройки терминала используются файлы инициализации:
~/.bashrc: выполняется для каждой новой интерактивной оболочки. Здесь удобно прописывать алиасы (псевдонимы команд).~/.bash_profile или ~/.profile: выполняется один раз при входе в систему (login shell).Пример полезного алиаса в .bashrc:
alias ll='ls -alFh' — теперь команда ll будет выводить подробный список файлов с размерами в мегабайтах.
Управление фоновыми задачами и мультиплексоры
Иногда процесс выполняется долго (например, бэкап базы данных), и вам не хочется держать терминал открытым.
cp -r /large_dir /backup &.Однако, если вы закроете SSH-сессию, все запущенные в ней процессы получат сигнал SIGHUP и завершатся. Чтобы этого избежать, используют nohup или, что гораздо профессиональнее, терминальные мультиплексоры.
Tmux — стандарт индустрии. Он позволяет создавать сессии, внутри которых можно открывать множество окон и панелей. Главное преимущество: если связь с сервером прервется, сессия в tmux продолжит жить. Вы сможете подключиться снова и увидеть всё в том же состоянии.
tmux new -s my_session: создать сессию.Ctrl+b, затем d: отсоединиться (detach).tmux attach -t my_session: вернуться в сессию.Диагностика системы: первые шаги при «пожаре»
Когда вам говорят «сервер тормозит», у вас должен быть четкий алгоритм проверки.
top или uptime. Это среднее количество процессов, которые находятся в состоянии Running или Uninterruptible Sleep.top или htop смотрим на процент использования. Важен параметр wa (I/O Wait) — если он высокий, значит, процессор простаивает, ожидая медленный диск.free -h. Не пугайтесь, если в колонке free мало места. Linux использует свободную память под кэш диска (buff/cache). Настоящий дефицит памяти виден, когда растет использование Swap (подкачки на диске).iostat -xz 1 (из пакета sysstat). Показывает утилизацию дисков. Если %util близок к 100, диск — узкое место.ss -tunlp. Показывает, какие порты открыты и какие процессы их слушают. Флаги: -t (TCP), -u (UDP), -n (числовые адреса), -l (listening), -p (process).Практический кейс: поиск причины сбоя
Представьте: веб-приложение выдает 500 ошибку. Вы заходите по SSH.
systemctl status nginx. Видите, что он запущен.tail -f /var/log/nginx/error.log. Видите ошибку "Permission denied" при попытке записи в /var/www/html/cache.ls -ld /var/www/html/cache. Видите, что владельцем является root, а Nginx работает от пользователя www-data.chown -R www-data:www-data /var/www/html/cache.Этот простой пример показывает, как знание иерархии ФС, процессов и базовых команд позволяет локализовать проблему за пару минут.
Архитектура Linux построена на логике и предсказуемости. Понимая, как ядро управляет ресурсами и как процессы общаются между собой, вы перестаете «тыкать пальцем в небо» и начинаете осознанно управлять инфраструктурой. В следующей главе мы углубимся в вопросы безопасности: разберемся, как именно работают права доступа и почему chmod 777 — это почти всегда плохая идея.