Вернуться к главной странице, списку всех тем
1. Linux, Bash-скрипты и текстовые редакторы
Что ты узнаешь: как устроен сервер, на котором работают программы, как отдавать ему команды через терминал, как запускать программу в фоне и как автоматизировать рутину bash-скриптом
Что нужно знать заранее: ничего — это первая тема курса
Сколько времени займёт: 5 часов видео + 6–8 часов практики
Твой шаг в сквозном проекте: запустишь сервис «Заметки» на своей машине и сделаешь так, чтобы он поднимался сам после перезагрузки
Зачем всё это: как появляются программы и при чём тут DevOps
IT — это работа с информацией: её хранение, изменение, извлечение пользы или распространение. Помогают нам в этом программы — инструменты, которые принимают данные (вход), обрабатывают их и выдают результат (выход)
Вот несколько примеров программ:
- Калькулятор принимает числа, считает и выводит ответ
- База данных принимает запрос на добавление данных и особенным способом записывает их на диск, а на другой запрос выдаёт данные обратно
- Веб-приложение (приложение, к которому можно отправлять запросы через интернет) принимает запрос на отображение страницы ВК и отдаёт нам страницу
По своей сути все сайты, банки, игры — это набор таких маленьких приложений, каждое из которых делает свою функцию. Тебе не нужно держать в голове всю картину их взаимодействия сразу
Программы появляются в результате этапов:
- Анализ требований — бизнес объясняет, какая ему нужна программа, сайт или сервис
- Проектирование — архитектор продумывает, как всё будет работать
- Написание кода — разработчики создают программы
- Тестирование — тестировщики (их ещё называют QA) проверяют, что все программы работают вместе как нужно
- Внедрение и поддержка — инженеры мониторинга смотрят, чтобы программы не ломались, инженеры SRE чинят программы в случае поломки
DevOps автоматизирует этапы с 3-го по 5-й, что ускоряет и упрощает создание и поддержку программ. Кроме того, DevOps улучшает взаимодействие между теми, кто проектирует, пишет код и тестирует
Где ты будешь в этой картине. Твоя работа начинается там, где код разработчика должен превратиться в работающий сервис: собрать, упаковать, выкатить, следить, чинить. Весь курс — это девять слоёв над одной и той же маленькой программой, и первый слой мы кладём прямо сейчас
Сквозной проект курса: сервис «Заметки»
Чтобы теория не осталась теорией, через весь курс мы ведём одно приложение — простой веб-сервис «Заметки» (notes). Он отдаёт по HTTP список заметок из файла. Программа намеренно крошечная: интерес не в ней, а в том, что мы вокруг неё построим
Что произойдёт с «Заметками» по темам курса:
| Тема | Что добавляем |
|---|---|
| 1. Linux | Запускаем на своей машине, оформляем как systemd-сервис |
| 2. Сеть | Ставим спереди nginx, включаем HTTPS, разбираем путь запроса |
| 3. Git | Кладём код в репозиторий, настраиваем автоматическую проверку |
| 4. Docker | Упаковываем в контейнер, поднимаем вместе с базой через Compose |
| 5. Kubernetes | Запускаем в трёх копиях, переживаем падение одной из них |
| 6. Облака | Выносим на арендованный сервер в интернете |
| 7. Ansible/Terraform | Описываем инфраструктуру кодом, разворачиваем с нуля одной командой |
| 8. Мониторинг | Добавляем метрики, дашборд, алерты и SLO |
| 9. Vault/Flux | Убираем пароли из кода, деплоим автоматически из git |
Заводить приложение будем в задании 8 этой темы
Подготовка места для запуска программ, Linux
Сервера, на которых мы будем запускать программы, работают на ядре Linux. Это специальная программа, которую устанавливают на сервер в первую очередь. Она помогает нашим программам общаться с «железками» компьютера при помощи драйверов (программа, в которой описано, как общаться с тем или иным устройством). Например, ядро объясняет нашей программе, как записать данные на диск или вывести картинку на экран
Основные «железные» ресурсы сервера, с которыми работают наши программы:
- Диск — место, куда можно записывать и хранить информацию. Способ, которым данные хранятся, называется файловая система
- Процессор (CPU) — «мозг» компьютера. Он обрабатывает информацию. Принцип работы как у программ: даём ему задачу, он её решает и отдаёт результат
- Оперативная память (RAM) — быстрая память, которая очищается при перезагрузке сервера. Программы хранят в ней данные, с которыми работают прямо сейчас
Эти три ресурса будут преследовать тебя весь курс: контейнеру мы будем ставить лимит по CPU и памяти, Kubernetes будет решать, на какой сервер поместится приложение, а мониторинг — кричать, что память кончается
Ядро, системные вызовы и процессы
Программа не умеет сама писать на диск или отправлять данные в сеть — «железо» ей недоступно напрямую. Вместо этого она просит ядро: «открой файл», «прочитай из него», «отправь эти байты в сеть». Такая просьба называется системный вызов (syscall)
Запущенная программа называется процессом. У каждого процесса есть:
- PID — номер процесса, по которому к нему можно обратиться
- родитель — процесс, который его запустил (все процессы — потомки процесса с PID 1)
- владелец — пользователь, от имени которого процесс работает; от этого зависит, к каким файлам у него есть доступ
Посмотреть процессы можно командой ps aux (список) или top / htop (живая картина, обновляется каждую секунду)
Файловая система: всё есть файл
В Linux нет дисков C: и D:. Есть одно дерево, которое начинается с корня — /. Всё остальное растёт из него
Основные каталоги, которые встретятся тебе в работе:
| Каталог | Что в нём |
|---|---|
/etc |
Конфигурационные файлы всех программ |
/var/log |
Логи — записи о том, что программы делали |
/home/имя |
Домашний каталог пользователя, сокращённо ~ |
/usr/bin, /usr/local/bin |
Исполняемые файлы программ |
/tmp |
Временные файлы, очищаются при перезагрузке |
/proc |
Не настоящие файлы, а окно в состояние ядра и процессов |
/opt |
Софт, установленный вручную, не через пакетный менеджер |
/proc — особый случай, о нём часто спрашивают на собеседовании. Этих файлов нет на диске: ядро придумывает их содержимое в момент, когда ты пытаешься прочитать. Например, cat /proc/cpuinfo покажет процессор, а cat /proc/1/status — состояние процесса с PID 1
Путь бывает абсолютный (/var/log/syslog — от корня, всегда однозначен) и относительный (log/syslog — от каталога, в котором ты сейчас). . означает текущий каталог, .. — на уровень выше
Пользователи, права и sudo
У каждого файла есть владелец и права: кто может читать (r), писать (w) и запускать (x). Посмотреть их — ls -l:
-rwxr-xr-- 1 eugene devops 512 Aug 1 10:00 run.sh
│└┬┘└┬┘└┬┘ └──┬─┘ └──┬─┘
│ │ │ │ │ └── группа
│ │ │ │ └───────── владелец
│ │ │ └───────────────── права для всех остальных: только чтение
│ │ └──────────────────── права для группы: чтение и запуск
│ └─────────────────────── права для владельца: чтение, запись, запуск
└───────────────────────── тип: «-» файл, «d» каталог, «l» ссылка
Права удобно задавать числом: чтение = 4, запись = 2, запуск = 1. Складываем и получаем цифру для каждой из трёх групп. chmod 750 run.sh — владельцу всё (4+2+1), группе чтение и запуск (4+1), остальным ничего
root — пользователь с неограниченными правами. Работать под ним постоянно опасно: одна опечатка в команде удаления — и сервера нет. Поэтому обычно работают под своим пользователем, а когда нужны права root, пишут sudo перед командой. Кому что разрешено делать через sudo, описано в файле /etc/sudoers, который правят только командой visudo (она проверяет синтаксис — ошибка в этом файле может отрезать тебе доступ)
Сигналы: как правильно останавливать программы
Чтобы попросить процесс завершиться, ему посылают сигнал:
| Сигнал | Номер | Что означает |
|---|---|---|
SIGTERM |
15 | «Пожалуйста, завершись» — программа успевает дописать файлы и закрыть соединения. Это поведение kill по умолчанию |
SIGINT |
2 | То же, что нажать Ctrl+C в терминале |
SIGHUP |
1 | Часто используется как «перечитай конфиг, не перезапускаясь» |
SIGKILL |
9 | Убить немедленно. Процесс не может его перехватить и ничего не успевает сохранить |
Правило: сначала SIGTERM, и только если через 10–30 секунд процесс не умер — SIGKILL. Привычка сразу писать kill -9 приводит к битым данным. Ровно эта же логика позже встретится в Docker (docker stop шлёт SIGTERM, потом SIGKILL) и в Kubernetes (terminationGracePeriodSeconds)
systemd: как программы работают в фоне
Если запустить программу в терминале и закрыть терминал, программа умрёт. А сервис должен работать всегда: подниматься при старте сервера, перезапускаться после падения, писать логи. Этим занимается systemd — первый процесс системы (PID 1), который запускает и присматривает за всеми остальными
Описание одной программы для systemd называется юнит и лежит в файле /etc/systemd/system/имя.service. Основные команды:
systemctl start notes # запустить
systemctl stop notes # остановить
systemctl restart notes # перезапустить
systemctl status notes # посмотреть состояние: работает ли, когда упал, последние строки логов
systemctl enable notes # включать автоматически при загрузке сервера
journalctl -u notes -f # смотреть логи сервиса в реальном времени
Разница между start и enable — частая путаница: start запускает сейчас, enable включает автозапуск после перезагрузки. Обычно нужны обе
Сокеты и порты
Сокет — «розетка», через которую два процесса обмениваются данными. Сокеты бывают сетевые (общение по сети, адресуются парой IP-адрес + порт) и локальные, файловые (общение процессов на одной машине, выглядят как файл, например /var/run/docker.sock)
Порт — номер от 1 до 65535, который отличает одну программу на сервере от другой. Веб-сервер обычно слушает 80 (HTTP) и 443 (HTTPS), база PostgreSQL — 5432, наш сервис «Заметки» будет слушать 8080. Посмотреть, кто какой порт занял: ss -tulpn
Текстовые редакторы и форматы конфигов
Почти вся работа DevOps — это правка текстовых файлов. Редакторы, которые нужно знать:
- nano — простой, подсказки внизу экрана. Выход с сохранением:
Ctrl+O,Enter,Ctrl+X. С него начинают - vim — есть на любом сервере, даже в аварийном режиме. Минимум:
i— режим ввода,Esc— выйти из него,:wq— сохранить и выйти,:q!— выйти без сохранения - VS Code — основной редактор на своём ноутбуке, умеет подключаться к серверу по SSH
Форматы, в которых пишут конфигурацию:
JSON — машиночитаемый, строгий, без комментариев. На нём общаются программы между собой:
{
"service": "notes",
"port": 8080,
"replicas": 3
}
YAML — то же самое, но для людей: вложенность задаётся отступами, есть комментарии. На нём написаны Docker Compose, Kubernetes, Ansible, GitLab CI — то есть почти весь остаток курса:
service: notes # имя сервиса
port: 8080
replicas: 3
Главное правило YAML: отступы только пробелами, никаких табов, и на одном уровне вложенности одинаковое число пробелов. Это источник примерно половины ошибок новичков
Markdown — разметка для текста: # заголовок, **жирный**, - список, `код`. На нём написан этот курс и почти все README в мире
Bash-скрипты
Bash-скрипт — текстовый файл с набором команд, которые выполняются одна за другой. Он превращает «я каждый раз делаю эти шесть команд» в «я запускаю одну»
Скелет любого приличного скрипта:
#!/usr/bin/env bash
# Строка выше называется shebang: она говорит системе, чем запускать этот файл
set -euo pipefail
# -e — прервать скрипт при первой же ошибке, а не идти дальше как ни в чём не бывало
# -u — считать ошибкой обращение к несуществующей переменной (защита от опечаток)
# -o pipefail — считать ошибкой падение любой команды в конвейере a | b | c
NAME="${1:-мир}" # первый аргумент скрипта, а если его нет — слово «мир»
echo "Привет, ${NAME}!"
Без set -euo pipefail скрипт, у которого не получилось скачать файл, спокойно продолжит работу и «задеплоит» пустоту. Пиши эту строку всегда
Полезные конструкции:
if [ -f /etc/hosts ]; then echo "файл есть"; fi # проверка существования файла
if ! command -v jq >/dev/null; then echo "нет jq"; fi # проверка, установлена ли программа
for f in *.log; do echo "нашёл ${f}"; done # цикл по файлам
DATE="$(date '+%Y-%m-%d %H:%M:%S')" # результат команды в переменную
Кавычки вокруг "${NAME}" — не украшение: без них имя файла с пробелом развалится на два аргумента
Уроки для просмотра и конспектирования
- Уроки с 3-го по 20-й —
4 часа - Уроки с 3-го по 5-й —
1 час
Начало работы в IT: готовим рабочее место
- Нужен ноутбук с Ubuntu. Если у тебя Windows — установи
WSLи в нёмUbuntu. Если macOS — терминал есть, но часть команд отличается, поэтому лучше тоже поставить Ubuntu в виртуальной машине или WSL-аналоге - Установи Visual Studio Code и запусти, посмотри, как выглядит. Эта программа нужна для редактирования конфигов и написания кода
- Установи браузер, которым будешь пользоваться для работы — например, Яндекс Браузер или Chrome. Пригодятся инструменты разработчика (
F12), в теме 2 мы будем смотреть в них сетевые запросы - Установи и пока не трогай, понадобится в темах 4 и 5: Docker Desktop и Lens
- Заведи привычку спрашивать у ИИ-ассистента то, что непонятно — например, у GigaChat. Хороший запрос:
Объясни как ребёнку, зачем DevOps нужен Kubernetes. Плохой: копировать ответ в задание, не поняв его - Зарегистрируйся на сайтах:
Теоретические вопросы
Ответь своими словами, не подглядывая. Ответы ниже — для самопроверки
-
Что такое ядро Linux и зачем оно нужно? Ответ: Программа, которая загружается на сервере первой и управляет «железом»: процессором, памятью, диском, сетью. Обычные программы не работают с железом напрямую — они просят об этом ядро
-
Что такое системный вызов? Ответ: Обращение программы к ядру с просьбой сделать то, что ей самой недоступно: открыть файл, выделить память, отправить данные в сеть. Примеры:
open,read,write,fork,execve -
Что такое
sudoи как им пользоваться? Ответ: Команда, которая выполняет другую команду от имени root (администратора). Пишется перед командой:sudo apt update. Права, кому что можно, описаны в/etc/sudoers -
Как сделать, чтобы
sudoне спрашивал пароль каждый раз? Ответ: Открытьsudo visudoи добавить строкуимя_пользователя ALL=(ALL) NOPASSWD: ALL. Править только черезvisudo— он проверяет синтаксис. На рабочих серверах так делать не стоит, это дыра в безопасности; уместно на своей учебной машине -
Что такое systemd-сервис? Ответ: Описание программы, которой systemd управляет: чем её запускать, под каким пользователем, что делать при падении, когда стартовать. Лежит в файле
/etc/systemd/system/имя.service -
Как проверить состояние systemd-сервиса? Ответ:
systemctl status имя— активен ли, с каким PID, когда запущен, последние строки логов. Полные логи —journalctl -u имя -
Чем
systemctl startотличается отsystemctl enable? Ответ:startзапускает сервис прямо сейчас,enableвключает автозапуск при загрузке сервера. Это независимые вещи, обычно нужны обе -
Что такое сокет? Ответ: Точка соединения для обмена данными между процессами. Сетевой сокет адресуется парой «IP-адрес + порт», локальный (unix-сокет) выглядит как файл, например
/var/run/docker.sock -
Какие есть kill-сигналы и чем они отличаются? Ответ:
SIGTERM(15) — вежливая просьба завершиться, процесс успевает прибраться;SIGINT(2) — то же, чтоCtrl+C;SIGHUP(1) — часто «перечитай конфиг»;SIGKILL(9) — убийство без предупреждения, перехватить нельзя -
Как правильно завершить запущенный процесс? Ответ: Найти PID (
ps aux | grep имяилиpgrep имя), послатьkill PID(это SIGTERM), подождать. Если не умер —kill -9 PID. Для сервисов правильнееsystemctl stop имя -
Что такое корень файловой системы? Ответ: Каталог
/— начало единого дерева каталогов. В Linux нет отдельных дисковC:/D:, все накопители подключаются в какую-то точку внутри этого дерева -
Чем
/procотличается от остальных каталогов? Ответ: Это виртуальная файловая система: файлов в ней физически нет на диске, их содержимое ядро формирует в момент чтения. Через неё видно состояние ядра и каждого процесса -
Что такое
load averageв выводеuptime? Ответ: Среднее число процессов, которые хотят работать (выполняются или ждут диск), за 1, 5 и 15 минут. Ориентир: значение примерно равное числу ядер — полная загрузка, заметно больше — очередь, система не справляется -
В чём разница между JSON и YAML? Ответ: Одни и те же данные. JSON строгий, без комментариев, удобен машинам. YAML читаемее для человека, вложенность задаётся отступами, комментарии есть. Конфиги DevOps-инструментов почти всегда YAML
-
Почему в YAML нельзя использовать табы? Ответ: Спецификация запрещает табы для отступов, парсер их не примет. Вложенность строится только пробелами, и на одном уровне их должно быть одинаковое количество
-
Что делает
set -euo pipefailв начале скрипта? Ответ:-eпрерывает скрипт на первой ошибке,-uругается на необъявленные переменные,-o pipefailзамечает падение команды внутри конвейера. Без этого скрипт продолжает работать после ошибки и делает не то, что задумано -
Что такое shebang? Ответ: Первая строка скрипта вида
#!/usr/bin/env bash. Указывает, какой программой запускать файл. Без неё скрипт можно запустить только явно:bash script.sh -
Как сделать файл исполняемым и почему
./script.sh, а неscript.sh? Ответ:chmod +x script.sh. Точка со слешем означает «файл в текущем каталоге»; без неё оболочка ищет команду только в каталогах из переменнойPATH, а текущего каталога там нет — из соображений безопасности -
Что такое cron? Ответ: Планировщик: запускает команды по расписанию. Расписание задаётся пятью полями — минута, час, день месяца, месяц, день недели.
* * * * *— каждую минуту,0 3 * * *— каждый день в 03:00 -
Что такое SSH и зачем нужны клиент и сервер? Ответ: Протокол защищённого удалённого доступа к серверу. На сервере работает
sshd(принимает подключения), на твоём ноутбуке — клиентssh(подключается). Весь трафик шифруется, вход обычно по ключу, а не по паролю
Вопросы с собеседований
Это то, что реально спрашивают на собеседованиях сверх основного списка выше
-
Какие основные поля есть в конфигурации systemd-юнита? Ответ: Три секции.
[Unit]:Description,After(после чего запускать),Requires.[Service]:ExecStart(чем запускать),User,WorkingDirectory,Environment,Restart,RestartSec,Type(simpleпо умолчанию,forkingдля процессов, уходящих в фон).[Install]:WantedBy— на каком этапе загрузки включать -
Как посмотреть версию ядра Linux? Ответ:
uname -r— только версия,uname -a— вся информация о системе. Дистрибутив —lsb_release -aилиcat /etc/os-release -
Как передать права на файл или каталог другому пользователю? Ответ:
chown пользователь:группа файл, рекурсивно —chown -R. Только группу меняетchgrp. Права доступа при этом не меняются, за них отвечаетchmod -
Как посмотреть список уже запланированных задач cron? Ответ:
crontab -l— задачи текущего пользователя,sudo crontab -l -u имя— конкретного пользователя. Системные задачи лежат в/etc/crontabи каталогах/etc/cron.d/,/etc/cron.daily/ -
Что нужно, чтобы подключиться к серверу по SSH? Ответ: Адрес сервера, имя пользователя и способ аутентификации — ключ или пароль. При входе по ключу открытая часть должна лежать на сервере в
~/.ssh/authorized_keys, закрытая — у тебя в~/.ssh/id_ed25519с правами600 -
Как проверить, запущен ли SSH-сервер, и где его конфигурация? Ответ:
systemctl status ssh(в некоторых системахsshd) либоss -tulpn | grep :22. Конфигурация сервера —/etc/ssh/sshd_config, конфигурация клиента —/etc/ssh/ssh_configи~/.ssh/config. После правки нуженsystemctl reload ssh -
Где хранятся SSH-ключи текущего пользователя? Ответ: В каталоге
~/.ssh/. Закрытый ключ —id_ed25519(илиid_rsa), открытый — с расширением.pub. Права на каталог должны быть700, на закрытый ключ600, иначе SSH откажется его использовать -
Как посмотреть информацию о команде или программе? Ответ:
man команда— полное руководство,команда --help— краткая справка,apt show пакет— сведения о пакете,which команда— путь к исполняемому файлу,type команда— чем она является: файлом, встроенной командой или псевдонимом -
Как заменить одно слово на другое в файле? Ответ:
sed -i 's/старое/новое/g' файл. Здесь-iправит файл на месте,gзаменяет все вхождения в строке, а не только первое. Перед правкой важного файла делают резервную копию:sed -i.bak -
Что такое файловый дескриптор? Ответ: Число, которым процесс обозначает открытый файл, сокет или канал. Три всегда открыты:
0— стандартный ввод,1— стандартный вывод,2— поток ошибок. Отсюда привычные конструкции:2>/dev/null(спрятать ошибки),2>&1(объединить ошибки с обычным выводом). Список открытых процессом дескрипторов —ls -l /proc/PID/fd/ -
Чем
>отличается от>>? Ответ:>перезаписывает файл с нуля,>>дописывает в конец. Одна из самых дорогих опечаток новичка:>вместо>>в скрипте, который ведёт журнал, стирает всю историю при каждом запуске -
Что такое inode и чем жёсткая ссылка отличается от символической? Ответ: Inode — структура с метаданными файла: права, владелец, размер, расположение данных на диске. Имя файла — лишь запись в каталоге, указывающая на inode. Жёсткая ссылка (
ln) — ещё одно имя того же inode: файл исчезнет, только когда удалят последнее имя; работает лишь в пределах одной файловой системы и не применяется к каталогам. Символическая (ln -s) — отдельный маленький файл с путём внутри: может указывать куда угодно, но «повисает», если цель переместили -
Диск заполнен, но крупных файлов
duне находит. В чём дело? Ответ: Два типичных случая. Первый: файл удалили, но его держит открытым работающий процесс — место освободится только после его перезапуска, найти виновника можно черезlsof +L1. Второй: кончились не байты, а inode — так бывает при миллионах крошечных файлов; проверяется командойdf -i -
Что означают коды возврата 0, 1, 127, 137 и 143? Ответ:
0— успех,1— общая ошибка,126— файл найден, но не исполняемый,127— команда не найдена. Коды больше 128 означают завершение по сигналу:128 + номер сигнала. Отсюда130— прервали черезCtrl+C(SIGINT),143— корректная остановка (SIGTERM),137— убит SIGKILL, чаще всего это нехватка памяти. Код137у контейнера в теме 4 читается именно так -
Что такое OOM killer? Ответ: Механизм ядра: когда память кончилась, оно выбирает процесс с наибольшей «оценкой» и убивает его, чтобы спасти систему. Следы ищут в
dmesgилиjournalctl -kпо словуOut of memory. Коварство в том, что жертвой становится не обязательно виновник — обычно это самый прожорливый процесс, а им часто оказывается база данных -
Что такое
ulimitи когда о нём вспоминают? Ответ: Ограничения на процесс: число открытых файлов, процессов, размер стека. Вспоминают при ошибкеToo many open files— по умолчанию лимит дескрипторов часто мал для нагруженного сервера. Смотрятulimit -n, меняют в/etc/security/limits.conf, а для сервисов — директивойLimitNOFILEв systemd-юните -
Что такое umask? Ответ: Маска, которая убирает права у создаваемых файлов. При
umask 022новые файлы получают644, каталоги —755: маска вычитается из666и777соответственно. Это объясняет, почему созданный файл не является исполняемым сам по себе -
Что делают биты setuid и sticky? Ответ:
setuidзаставляет программу работать с правами владельца файла, а не запустившего — такpasswdменяет системный файл паролей от имени обычного пользователя. Sticky-бит на каталоге (как у/tmp) разрешает удалять файлы только их владельцу, иначе любой стёр бы чужие -
Как посмотреть логи сервиса и не дать им забить диск? Ответ:
journalctl -u имя— логи сервиса,-fследить,--since "1 hour ago"за период,-p errтолько ошибки,-kсообщения ядра. Размер журнала —journalctl --disk-usage, очистка —journalctl --vacuum-time=7d. Для обычных файлов в/var/logза ротацию отвечаетlogrotateс настройками в/etc/logrotate.d/ -
Как найти все файлы больше 100 МБ, изменённые за последнюю неделю? Ответ:
find /var -type f -size +100M -mtime -7. Добавив-exec ls -lh {} \;или| xargs ls -lh, получим подробности.xargsнужен, потому что многие команды читают аргументы, а не стандартный ввод; для имён с пробелами безопасна связкаfind ... -print0 | xargs -0 -
Что произойдёт, если ошибиться в
/etc/fstab? Ответ: Файл описывает, что монтировать при загрузке. Ошибка в нём способна оставить сервер в аварийном режиме без сети — а это в облаке означает поход в консоль восстановления. Поэтому после правки проверяютmount -aдо перезагрузки, а необязательным разделам добавляют опциюnofail -
Чем
nohupиtmuxотличаются от systemd-сервиса? Ответ:nohupиtmuxпозволяют процессу пережить закрытие терминала — это удобно для разовой долгой команды. Но они не поднимут программу после перезагрузки сервера и не перезапустят её после падения. Всё, что должно работать постоянно, оформляют systemd-юнитом
Практическая часть
Задания идут по нарастанию. Для каждого записывай результат: скриншот или скопированный вывод команды — это твой конспект и отчёт
Задание 1. Навигация по файловой системе
Цель: свободно перемещаться по дереву каталогов и понимать, где находишься
Шаги:
pwd # показать полный путь к текущему каталогу
cd /tmp # перейти в /tmp
pwd
cd - # вернуться в предыдущий каталог
cd ~ # перейти в домашний каталог пользователя
cd .. # подняться на уровень выше
cd / # перейти в корень
ls -la # посмотреть содержимое, включая скрытые файлы
Ожидаемый вывод: после cd ~ команда pwd печатает /home/твоё_имя; после cd / — просто /
Ответь письменно: куда именно ведёт cd ~? Какие основные каталоги ты видишь в корне и за что отвечает каждый?
Типичные ошибки:
cdбез аргументов — не ошибка, а способ попасть домой, эквивалентcd ~- Пути с пробелами нужно брать в кавычки:
cd "Мои файлы"
Задание 2. Файлы и каталоги
Цель: создавать, перемещать и удалять — без этого дальше никуда
Шаги:
cd ~
touch config binary # создать два пустых файла
mkdir app # создать каталог
mv config binary app/ # переместить оба файла в каталог
ls -l app/
mkdir -p app/temp/info/users # создать вложенные каталоги одной командой
ls -R app # посмотреть дерево целиком
cd ~
rm -r app # удалить каталог со всем содержимым
Ожидаемый вывод: ls -R app показывает binary, config и цепочку temp/info/users
Типичные ошибки:
mkdir app/temp/info/usersбез-pупадёт сNo such file or directory— без флага создаётся только последний каталог, а промежуточных ещё нетrm -rудаляет молча и безвозвратно, корзины нет. Перед удалением полезно сделатьlsтого, что собираешься удалить. Никогда не запускайrm -rf /и подобное «на посмотреть»
Задание 3. Ресурсы сервера
Цель: уметь за минуту ответить на вопрос «что с сервером»
Шаги:
top # живая картина процессов, выход — клавиша q
htop # то же, но нагляднее (устанавливается отдельно)
free -h # сколько оперативной памяти занято и свободно
df -h / # сколько места на диске в корневом разделе
du -sh ~/* # что именно занимает место в домашнем каталоге
uptime # сколько работает сервер и load average
ss -tulpn # какие порты слушаются и какими процессами
Ответь письменно: что означают колонки %CPU, %MEM, RES в top? Что такое load average и когда его значение считается плохим?
Типичные ошибки:
- Путать
free -hколонкиfreeиavailable: смотреть надо наavailable— часть памяти занята кэшем, но при необходимости будет отдана программам dfпоказывает место на разделе,du— сколько занимают конкретные файлы. Еслиdfговорит «диска нет», аduне находит крупных файлов — скорее всего, удалённый файл всё ещё держит запущенный процесс
Задание 4. Установка программ
Цель: пользоваться пакетным менеджером apt
Шаги:
sudo apt update # обновить список доступных пакетов
sudo apt upgrade -y # обновить установленные программы
sudo apt install -y git htop curl nano jq # установить нужные нам программы
Проверь каждую:
git --version
htop --version
curl --version
nano --version
jq --version
curl -s https://api.github.com/repos/kubernetes/kubernetes | jq .stargazers_count
Ожидаемый вывод: последняя команда скачивает данные из интернета в формате JSON и печатает одно число — количество звёзд у репозитория Kubernetes. Так связка curl + jq используется в реальной работе постоянно
Типичные ошибки:
apt installсразу после установки системы часто падает сUnable to locate package— забылиapt updateapt updateобновляет список пакетов,apt upgrade— сами пакеты. Это разные вещи
Задание 5. Первый bash-скрипт
Цель: написать скрипт, который проверяет и доустанавливает нужные программы
Шаги: создай файл ~/bin/setup.sh:
#!/usr/bin/env bash
set -euo pipefail
# Программы, без которых нам дальше не обойтись
PACKAGES=(curl git jq)
for pkg in "${PACKAGES[@]}"; do
# command -v ищет программу в PATH; вывод отправляем в никуда, нас интересует только код возврата
if command -v "${pkg}" >/dev/null 2>&1; then
echo "✓ ${pkg} уже установлен"
else
echo "→ ставлю ${pkg}"
sudo apt install -y "${pkg}"
fi
done
echo "Готово"
Сделай исполняемым только для себя и запусти:
mkdir -p ~/bin
chmod 700 ~/bin/setup.sh # 7 владельцу (rwx), 0 группе, 0 остальным
~/bin/setup.sh
ls -l ~/bin/setup.sh # убедись, что права выглядят как -rwx------
Ожидаемый вывод: три строки с галочками (программы уже стоят после задания 4) и Готово
Типичные ошибки:
Permission deniedпри запуске — забылchmod +xbad interpreter: No such file or directory— файл сохранён с виндовыми переносами строк. Лечитсяsed -i 's/\r$//' setup.sh- Забытые кавычки вокруг
"${pkg}"— до поры работает, но ломается на значениях с пробелами
Задание 6. Запуск по расписанию через cron
Цель: научиться выполнять задачу автоматически, без человека
Шаги: создай ~/bin/timestamp.sh:
#!/usr/bin/env bash
set -euo pipefail
date '+%Y-%m-%d %H:%M:%S' >> "${HOME}/current_time.txt"
chmod +x ~/bin/timestamp.sh
crontab -e # откроется редактор списка задач
Добавь строку (подставь своё имя пользователя):
* * * * * /home/твоё_имя/bin/timestamp.sh
Подожди три минуты и проверь:
cat ~/current_time.txt
Ожидаемый вывод: файл растёт на одну строку в минуту
Типичные ошибки:
- Относительный путь в crontab не работает — cron запускает задачу из другого каталога и с урезанным
PATH. Всегда указывай полный путь и к скрипту, и к файлам внутри него >вместо>>перезапишет файл вместо дописывания- Если задача не выполняется, смотри
grep CRON /var/log/syslog
Задание 7. Изучаем фоновые сервисы
Цель: понять, как в системе живут фоновые процессы
Шаги:
systemctl list-units --type=service # список всех сервисов
systemctl status ssh # состояние конкретного (может называться sshd)
sudo apt install -y openssh-server # установить SSH-сервер
sudo systemctl restart ssh
sudo systemctl enable ssh
ss -tulpn | grep :22 # убедиться, что порт 22 слушается
journalctl -u ssh -n 20 # последние 20 строк логов сервиса
Ответь письменно: выбери любой сервис из списка и разберись, что он делает. Что такое SSH, какую роль играют клиент и сервер?
Типичные ошибки:
- В разных дистрибутивах сервис зовётся
sshилиsshd— еслиUnit not found, попробуй второе имя systemctl restartбезsudoспросит пароль или откажет — управление сервисами требует прав root
Задание 8. Сквозной проект: запускаем сервис «Заметки»
Цель: запустить первую версию приложения, которое мы будем вести через весь курс, и заставить его подниматься автоматически
Шаги:
-
Создай каталог проекта и файл приложения
~/notes/app.py:#!/usr/bin/env python3 """Сервис «Заметки» — сквозной проект курса DevOps.""" import os from http.server import BaseHTTPRequestHandler, HTTPServer # Настройки берём из переменных окружения — так принято у всех сервисов, # это позволит потом менять их не трогая код (пригодится в темах 4, 5 и 9) NOTES_FILE = os.environ.get("NOTES_FILE", "/home/notes/notes.txt") PORT = int(os.environ.get("PORT", "8080")) class Handler(BaseHTTPRequestHandler): def do_GET(self): if self.path == "/healthz": # Эндпоинт проверки здоровья: по нему Docker и Kubernetes # будут понимать, живо ли приложение self.respond(200, "ok\n") elif self.path == "/": self.respond(200, self.read_notes()) else: self.respond(404, "Такой страницы нет\n") def read_notes(self): if not os.path.exists(NOTES_FILE): return "Заметок пока нет\n" with open(NOTES_FILE, encoding="utf-8") as f: return f.read() def respond(self, code, body): data = body.encode("utf-8") self.send_response(code) self.send_header("Content-Type", "text/plain; charset=utf-8") self.send_header("Content-Length", str(len(data))) self.end_headers() self.wfile.write(data) def log_message(self, fmt, *args): # flush=True — чтобы логи появлялись сразу, а не копились в буфере. # Без этого в контейнере (тема 4) логи будут «пропадать» print(f"{self.address_string()} {fmt % args}", flush=True) if __name__ == "__main__": print(f"«Заметки» слушают порт {PORT}", flush=True) HTTPServer(("0.0.0.0", PORT), Handler).serve_forever() -
Проверь вручную:
mkdir -p ~/notes cd ~/notes echo "Первая заметка: выучить Linux" > notes.txt NOTES_FILE=~/notes/notes.txt python3 app.pyВ другом терминале:
curl http://localhost:8080/ curl http://localhost:8080/healthz curl -i http://localhost:8080/такой-страницы-нетОстанови приложение через
Ctrl+C— это тот самыйSIGINT -
Оформи как systemd-сервис. Создай
/etc/systemd/system/notes.service:[Unit] Description=Сервис «Заметки» After=network.target [Service] # Под каким пользователем работать — не под root, у сервиса должно быть минимум прав User=твоё_имя WorkingDirectory=/home/твоё_имя/notes Environment=NOTES_FILE=/home/твоё_имя/notes/notes.txt Environment=PORT=8080 ExecStart=/usr/bin/python3 /home/твоё_имя/notes/app.py # Поднимать заново, если процесс упал Restart=always RestartSec=3 [Install] WantedBy=multi-user.target -
Запусти и проверь:
sudo systemctl daemon-reload # перечитать файлы юнитов после изменения sudo systemctl enable --now notes # включить автозапуск и запустить сейчас systemctl status notes curl http://localhost:8080/ journalctl -u notes -f # логи в реальном времени, выход Ctrl+C -
Проверь самовосстановление — убей процесс и убедись, что systemd поднял его заново:
pgrep -f app.py # узнать PID sudo kill $(pgrep -f app.py) # послать SIGTERM sleep 5 systemctl status notes # должен снова быть active (running), но с новым PID
Ожидаемый вывод: curl http://localhost:8080/ печатает текст заметки; systemctl status notes показывает active (running); после kill сервис возвращается сам
Типичные ошибки:
status=203/EXECв статусе — неверный путь вExecStart. Проверьwhich python3и подставь реальный путьAddress already in use— порт 8080 уже занят. Найди кем:ss -tulpn | grep :8080- Правки в
.serviceне действуют — забылsudo systemctl daemon-reload - Сервис работает, но заметок не видит: у пользователя из
User=нет прав на чтениеnotes.txt, проверьls -l
Оставь всё запущенным — в теме 2 мы поставим перед этим сервисом nginx и включим HTTPS
Проверь себя: тема освоена, если ты можешь
- Объяснить, что делает ядро Linux и что такое системный вызов
- Найти любой файл, посмотреть его права и изменить их через
chmod - За минуту ответить, сколько на машине свободной памяти, места на диске и какая нагрузка
- Написать скрипт с
set -euo pipefail, циклом и проверкой условия — и объяснить каждую строку - Объяснить разницу между
SIGTERMиSIGKILLи почему это важно - Создать systemd-юнит с нуля, запустить его и найти причину падения в
journalctl - Показать работающий сервис «Заметки», который поднимается после перезагрузки машины