2.1 Linux основы для DevOps #
🐧 Почему Linux в DevOps #
Linux — это основа большинства серверов и DevOps инструментов. 96% веб-серверов работают на Linux, поэтому DevOps-инженер должен уверенно чувствовать себя в командной строке.
Почему именно Linux:
- Бесплатный и открытый
- Стабильный и безопасный
- Мощная командная строка
- Огромная экосистема инструментов
- Используется во всех облачных провайдерах
📁 Файловая система Linux #
Структура каталогов #
/ # Корневой каталог
├── bin/ # Основные команды (ls, cp, mv)
├── boot/ # Файлы загрузки системы
├── dev/ # Устройства (диски, USB)
├── etc/ # Конфигурационные файлы
├── home/ # Домашние каталоги пользователей
├── lib/ # Системные библиотеки
├── opt/ # Дополнительное ПО
├── proc/ # Виртуальная ФС (процессы)
├── root/ # Домашний каталог root
├── tmp/ # Временные файлы
├── usr/ # Пользовательские программы
├── var/ # Переменные данные (логи)
└── srv/ # Данные сервисов
Навигация по файловой системе #
# Показать текущий каталог
pwd
# Перейти в каталог
cd /home/user # абсолютный путь
cd ../documents # относительный путь
cd ~ # домашний каталог
cd - # предыдущий каталог
# Показать содержимое каталога
ls # простой список
ls -l # подробный список
ls -la # включая скрытые файлы
ls -lh # человекочитаемые размеры
# Пример вывода ls -la
drwxr-xr-x 3 user user 4096 Jan 15 10:30 documents/
-rw-r--r-- 1 user user 1024 Jan 15 09:15 config.txt
-rwxr-xr-x 1 user user 2048 Jan 14 16:20 script.sh*
Права доступа (Permissions) #
# Формат прав: rwxrwxrwx
# r = read (4), w = write (2), x = execute (1)
# Первая группа: владелец, вторая: группа, третья: остальные
# Примеры
-rw-r--r-- # 644: владелец читает/пишет, остальные только читают
-rwxr-xr-x # 755: владелец все права, остальные читают/выполняют
-rwx------ # 700: только владелец имеет все права
# Изменение прав
chmod 755 script.sh # числовой формат
chmod +x script.sh # добавить право выполнения
chmod u+w,g-r file.txt # добавить запись владельцу, убрать чтение у группы
# Изменение владельца
chown user:group file.txt # сменить владельца и группу
chown user file.txt # только владельца
chgrp group file.txt # только группу
🔧 Основные команды Linux #
Работа с файлами и каталогами #
# Создание
mkdir mydir # создать каталог
mkdir -p path/to/deep/dir # создать вложенные каталоги
touch file.txt # создать пустой файл
cp source dest # копировать файл
cp -r source_dir dest_dir # копировать каталог рекурсивно
mv old_name new_name # переименовать/переместить
rm file.txt # удалить файл
rm -rf directory/ # удалить каталог рекурсивно (осторожно!)
# Поиск файлов
find /path -name "*.txt" # найти файлы по имени
find /var/log -mtime -7 # файлы изменённые за последние 7 дней
find . -type f -size +100M # файлы больше 100MB
locate filename # быстрый поиск по индексу
# Содержимое файлов
cat file.txt # показать весь файл
less file.txt # постраничный просмотр
head -n 20 file.txt # первые 20 строк
tail -n 10 file.txt # последние 10 строк
tail -f /var/log/app.log # следить за изменениями в реальном времени
Работа с текстом #
# Поиск в файлах
grep "error" /var/log/app.log # найти строки с "error"
grep -r "TODO" /project/ # рекурсивный поиск
grep -i "warning" log.txt # игнорировать регистр
grep -v "debug" log.txt # инвертировать поиск (все кроме)
grep -n "function" script.py # показать номера строк
# Обработка текста
wc -l file.txt # подсчитать строки
sort file.txt # отсортировать строки
uniq file.txt # убрать дубликаты
cut -d',' -f1 data.csv # извлечь первый столбец из CSV
# AWK - мощный инструмент обработки текста
awk '{print $1}' file.txt # напечатать первый столбец
awk -F',' '{print $2}' data.csv # разделитель - запятая, второй столбец
awk '$3 > 100' data.txt # строки где 3-й столбец больше 100
awk '{sum += $1} END {print sum}' numbers.txt # сумма чисел в первом столбце
# Практические примеры AWK
ps aux | awk '{print $1, $2, $11}' # имя пользователя, PID, команда
df -h | awk '$5+0 > 80 {print $1, $5}' # диски заполненные больше чем на 80%
free | grep Mem | awk '{printf("%.1f%%", $3/$2 * 100)}' # использование памяти в %
# Замена текста
sed 's/old/new/g' file.txt # заменить old на new
sed -i 's/localhost/127.0.0.1/g' config # заменить в самом файле
Pipes и redirection #
# Pipes (|) - передать вывод одной команды в другую
ps aux | grep nginx # найти процессы nginx
cat /var/log/app.log | grep ERROR | wc -l # посчитать ошибки
# Перенаправление вывода
command > file.txt # записать в файл (перезаписать)
command >> file.txt # добавить в файл
command 2> error.log # перенаправить ошибки
command &> all.log # и вывод, и ошибки
# Примеры комбинаций
ls -la | grep "^d" # показать только каталоги
df -h | grep -v tmpfs # диски без временных
netstat -tulpn | grep :80 # кто слушает 80 порт
⚙️ Управление процессами #
Просмотр процессов #
# Основные команды
ps aux # все процессы
ps aux | grep nginx # найти процессы nginx
top # интерактивный монитор процессов
htop # улучшенная версия top
jobs # фоновые задачи текущей сессии
# Информация о системе
uptime # время работы и нагрузка
free -h # использование памяти
df -h # использование дисков
lscpu # информация о CPU
Управление процессами #
# Запуск в фоне
command & # запустить в фоне
nohup command & # запустить и отвязать от терминала
# Остановка процессов
kill PID # мягко остановить процесс
kill -9 PID # принудительно убить процесс
killall nginx # убить все процессы nginx
pkill -f "python app.py" # убить по части команды
# Управление задачами
Ctrl+C # прервать текущую команду
Ctrl+Z # приостановить задачу
bg # продолжить в фоне
fg # вернуть на передний план
🌐 Сетевые команды #
Диагностика сетевых подключений #
# Проверка подключения
ping google.com # проверить доступность хоста
ping -c 4 8.8.8.8 # отправить 4 пакета
# Трассировка маршрута
traceroute google.com # показать маршрут до хоста
mtr google.com # непрерывная трассировка
# DNS запросы
nslookup google.com # получить IP адрес
dig google.com # подробная DNS информация
host google.com # простой DNS lookup
Сетевые подключения и порты #
# Показать активные подключения
netstat -tulpn # все слушающие порты
netstat -an | grep :80 # кто использует порт 80
ss -tulpn # современная замена netstat
# Проверка портов
telnet localhost 22 # проверить доступность порта
nc -zv hostname 22 # проверить порт через netcat
# Скачивание файлов
wget https://example.com/file.zip # скачать файл
curl -O https://example.com/file.zip # альтернатива wget
curl -s https://api.github.com/users/octocat # API запрос
🔧 Системы инициализации #
systemd (современные дистрибутивы) #
# Управление сервисами
systemctl start nginx # запустить сервис
systemctl stop nginx # остановить сервис
systemctl restart nginx # перезапустить сервис
systemctl reload nginx # перезагрузить конфигурацию
systemctl enable nginx # включить автозапуск
systemctl disable nginx # отключить автозапуск
# Статус сервисов
systemctl status nginx # статус сервиса
systemctl is-active nginx # проверить активность
systemctl is-enabled nginx # проверить автозапуск
# Логи сервисов
journalctl -u nginx # логи сервиса nginx
journalctl -f -u nginx # следить за логами в реальном времени
journalctl --since "1 hour ago" # логи за последний час
Создание простого systemd сервиса #
# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
User=myuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/start.sh
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
# Активация сервиса
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
📝 Скриптинг в Bash #
Основы bash скриптов #
#!/bin/bash
# Переменные
NAME="DevOps Engineer"
DATE=$(date +%Y-%m-%d)
COUNT=5
echo "Hello, $NAME!"
echo "Today is $DATE"
# Условия
if [ $COUNT -gt 3 ]; then
echo "Count is greater than 3"
else
echo "Count is 3 or less"
fi
# Циклы
for i in {1..5}; do
echo "Iteration $i"
done
# Функции
backup_logs() {
local log_dir="/var/log"
local backup_dir="/backup/logs/$(date +%Y%m%d)"
mkdir -p "$backup_dir"
cp -r "$log_dir"/* "$backup_dir/"
echo "Logs backed up to $backup_dir"
}
backup_logs
💡 Best Practice: Все примеры в этом курсе показаны для демонстрации. В реальных проектах всегда оборачивайте код в функции для повторного использования, тестирования и лучшей организации кода:
#!/bin/bash
# Плохо: код прямо в скрипте
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | awk -F'%' '{print $1}')
if (( $(echo "$CPU_USAGE > 80" | bc -l) )); then
echo "High CPU: $CPU_USAGE%"
fi
# Хорошо: функция с параметрами
check_cpu_usage() {
local threshold=${1:-80} # по умолчанию 80%
local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | awk -F'%' '{print $1}')
if (( $(echo "$cpu_usage > $threshold" | bc -l) )); then
echo "WARNING: High CPU usage: $cpu_usage% (threshold: $threshold%)"
return 1
else
echo "OK: CPU usage: $cpu_usage%"
return 0
fi
}
# Использование функции
check_cpu_usage 85 # проверить с порогом 85%
check_cpu_usage # использовать порог по умолчанию (80%)
Практический пример: Скрипт мониторинга #
#!/bin/bash
# monitor.sh - простой мониторинг системы
LOG_FILE="/var/log/monitor.log"
THRESHOLD_CPU=80
THRESHOLD_MEMORY=80
THRESHOLD_DISK=90
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
check_cpu() {
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | awk -F'%' '{print $1}')
if (( $(echo "$CPU_USAGE > $THRESHOLD_CPU" | bc -l) )); then
log_message "WARNING: High CPU usage: ${CPU_USAGE}%"
# Отправить алерт
echo "High CPU usage: ${CPU_USAGE}%" | mail -s "CPU Alert" admin@company.com
fi
}
check_memory() {
MEMORY_USAGE=$(free | grep Mem | awk '{printf("%.1f", $3/$2 * 100.0)}')
if (( $(echo "$MEMORY_USAGE > $THRESHOLD_MEMORY" | bc -l) )); then
log_message "WARNING: High memory usage: ${MEMORY_USAGE}%"
fi
}
check_disk() {
df -h | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{print $5 " " $1}' | while read output;
do
usage=$(echo $output | awk '{print $1}' | cut -d'%' -f1)
partition=$(echo $output | awk '{print $2}')
if [ $usage -ge $THRESHOLD_DISK ]; then
log_message "WARNING: High disk usage on $partition: ${usage}%"
fi
done
}
# Основная логика
log_message "Starting system monitoring"
check_cpu
check_memory
check_disk
log_message "Monitoring completed"
Запуск скрипта по расписанию (cron) #
# Редактировать crontab
crontab -e
# Примеры расписания
# Каждые 5 минут
*/5 * * * * /path/to/monitor.sh
# Каждый день в 2:30
30 2 * * * /path/to/backup.sh
# Каждый понедельник в 8:00
0 8 * * 1 /path/to/weekly_report.sh
# Формат: минута час день_месяца месяц день_недели команда
🔐 Безопасность в Linux #
Управление пользователями #
# Создание пользователей
sudo adduser newuser # интерактивное создание
sudo useradd -m -s /bin/bash newuser # создать с домашней папкой
# Управление группами
sudo usermod -aG sudo newuser # добавить в группу sudo
sudo usermod -aG docker newuser # добавить в группу docker
groups username # показать группы пользователя
# Смена пользователя
su - username # переключиться на пользователя
sudo -u username command # выполнить команду от имени пользователя
⚠️ Опасность wildcard’ов в sudo правах #
🔥 КРИТИЧЕСКИ ВАЖНО: Wildcard’ы в sudo могут создать огромные дыры в безопасности!
Проблема с wildcard’ами: #
# ❌ НИКОГДА ТАК НЕ ДЕЛАЙТЕ!
# /etc/sudoers
developer ALL=(ALL) NOPASSWD: /bin/cat /opt/nginx/*.conf
# Кажется безопасным: пользователь может читать только конфиги nginx
# НО! Это позволяет:
sudo cat /opt/nginx/../../../etc/passwd
sudo cat /opt/nginx/../../../etc/shadow
sudo cat /opt/nginx/../../root/.ssh/id_rsa
Реальные примеры уязвимостей: #
Случай 1: Чтение конфигов
# Задача: дать разработчику право читать конфиги приложения
# ❌ Опасно:
developer ALL=(ALL) NOPASSWD: /bin/cat /opt/myapp/*.conf
# Атака:
sudo cat /opt/myapp/../../../etc/passwd
sudo cat /opt/myapp/../../../../../root/.ssh/id_rsa
Случай 2: Редактирование через sudoedit
# ❌ Опасно:
developer ALL=(ALL) NOPASSWD: /usr/bin/sudoedit /etc/myapp/*.conf
# Атака:
sudo sudoedit /etc/myapp/../passwd # редактируем /etc/passwd!
sudo sudoedit /etc/myapp/../sudoers # получаем root!
Случай 3: Выполнение скриптов
# ❌ Опасно:
developer ALL=(ALL) NOPASSWD: /opt/scripts/*.sh
# Атака - создаём симлинк:
ln -s /bin/bash /opt/scripts/evil.sh
sudo /opt/scripts/evil.sh # получили root shell!
✅ Безопасные альтернативы: #
1. Точные пути без wildcard’ов:
# Хорошо: конкретные файлы
developer ALL=(ALL) NOPASSWD: /bin/cat /opt/nginx/nginx.conf
developer ALL=(ALL) NOPASSWD: /bin/cat /opt/nginx/sites-available/default
developer ALL=(ALL) NOPASSWD: /usr/bin/sudoedit /etc/myapp/app.conf
2. Специальные обёртки:
# Создаём безопасный скрипт-обёртку
cat > /usr/local/bin/read-nginx-config << 'EOF'
#!/bin/bash
# Безопасное чтение конфигов nginx
ALLOWED_FILES=(
"/opt/nginx/nginx.conf"
"/opt/nginx/conf.d/default.conf"
"/opt/nginx/sites-available/app.conf"
)
if [[ " ${ALLOWED_FILES[@]} " =~ " $1 " ]]; then
cat "$1"
else
echo "Access denied: $1 not in allowed files"
exit 1
fi
EOF
chmod +x /usr/local/bin/read-nginx-config
# В sudoers:
developer ALL=(ALL) NOPASSWD: /usr/local/bin/read-nginx-config
3. Использование групп и ACL:
# Создаём группу для чтения конфигов
sudo groupadd config-readers
sudo usermod -aG config-readers developer
# Настраиваем права через ACL
sudo setfacl -R -m g:config-readers:r /opt/nginx/
sudo setfacl -R -d -m g:config-readers:r /opt/nginx/
4. Sudo aliases для безопасности:
# В /etc/sudoers добавляем alias'ы
Cmnd_Alias NGINX_CONFIGS = /bin/cat /opt/nginx/nginx.conf, \
/bin/cat /opt/nginx/conf.d/default.conf, \
/usr/bin/sudoedit /opt/nginx/nginx.conf
# Разрешаем только эти команды
developer ALL=(ALL) NOPASSWD: NGINX_CONFIGS
🛡️ Правила безопасности для sudo: #
- Никогда не используйте
*
в sudo правилах - Всегда указывайте полные абсолютные пути
- Тестируйте права на проникновение (
../../../
) - Используйте wrapper’ы для сложной логики
- Регулярно аудируйте файл sudoers
- Логируйте все sudo команды (по умолчанию в /var/log/auth.log)
📋 Checklist проверки sudo правил: #
# Проверьте текущие sudo права
sudo -l
# Найдите опасные wildcard'ы в sudoers
sudo grep -n '\*' /etc/sudoers /etc/sudoers.d/*
# Проверьте логи sudo активности
sudo tail -f /var/log/auth.log | grep sudo
# Тестируйте path traversal атаки
sudo your_command ../../../etc/passwd
SSH и удаленный доступ #
# Подключение по SSH
ssh user@hostname # базовое подключение
ssh -i ~/.ssh/private_key user@host # с приватным ключом
ssh -p 2222 user@host # нестандартный порт
# Генерация SSH ключей
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
ssh-copy-id user@hostname # скопировать публичный ключ на сервер
# SSH config файл (~/.ssh/config)
Host webserver
HostName 192.168.1.100
User devops
Port 22
IdentityFile ~/.ssh/webserver_key
# Теперь можно: ssh webserver
Базовый firewall (ufw) #
# Включить firewall
sudo ufw enable
# Основные правила
sudo ufw allow ssh # разрешить SSH
sudo ufw allow 80/tcp # разрешить HTTP
sudo ufw allow 443/tcp # разрешить HTTPS
sudo ufw deny 3306 # запретить MySQL
# Статус
sudo ufw status verbose
🎯 Практические задания для DevOps #
Задание 1: Базовые навыки #
# 1. Создайте структуру каталогов для проекта
mkdir -p ~/projects/myapp/{src,config,logs,scripts}
# 2. Создайте конфигурационный файл
cat > ~/projects/myapp/config/app.conf << EOF
server_port=8080
database_host=localhost
log_level=info
EOF
# 3. Создайте скрипт запуска приложения
cat > ~/projects/myapp/scripts/start.sh << 'EOF'
#!/bin/bash
CONFIG_FILE="../config/app.conf"
LOG_FILE="../logs/app.log"
echo "Starting application at $(date)" >> "$LOG_FILE"
echo "Using config: $CONFIG_FILE" >> "$LOG_FILE"
# Здесь был бы запуск приложения
EOF
chmod +x ~/projects/myapp/scripts/start.sh
Задание 2: Мониторинг логов #
# Создайте скрипт для анализа логов веб-сервера
cat > ~/log_analyzer.sh << 'EOF'
#!/bin/bash
LOG_FILE="/var/log/nginx/access.log"
REPORT_FILE="/tmp/daily_report.txt"
echo "Daily Web Server Report - $(date)" > "$REPORT_FILE"
echo "=================================" >> "$REPORT_FILE"
# Количество запросов
echo "Total requests: $(wc -l < "$LOG_FILE")" >> "$REPORT_FILE"
# Топ 10 IP адресов
echo -e "\nTop 10 IP addresses:" >> "$REPORT_FILE"
awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10 >> "$REPORT_FILE"
# HTTP статус коды
echo -e "\nStatus codes:" >> "$REPORT_FILE"
awk '{print $9}' "$LOG_FILE" | sort | uniq -c | sort -nr >> "$REPORT_FILE"
# Топ 10 запрашиваемых страниц
echo -e "\nTop 10 requested pages:" >> "$REPORT_FILE"
awk '{print $7}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10 >> "$REPORT_FILE"
echo "Report saved to: $REPORT_FILE"
EOF
chmod +x ~/log_analyzer.sh
Задание 3: Автоматизация backup #
# Скрипт для резервного копирования
cat > ~/backup.sh << 'EOF'
#!/bin/bash
SOURCE_DIR="/opt/myapp"
BACKUP_BASE="/backup"
DATE=$(date +"%Y%m%d_%H%M%S")
BACKUP_DIR="$BACKUP_BASE/myapp_$DATE"
# Создать каталог для backup
mkdir -p "$BACKUP_DIR"
# Архивировать приложение
tar -czf "$BACKUP_DIR/app_$DATE.tar.gz" -C "$SOURCE_DIR" .
# Backup базы данных (пример для MySQL)
# mysqldump -u backup_user -p database_name > "$BACKUP_DIR/db_$DATE.sql"
# Удалить старые backup (старше 7 дней)
find "$BACKUP_BASE" -name "myapp_*" -type d -mtime +7 -exec rm -rf {} \;
echo "Backup completed: $BACKUP_DIR"
echo "Backup size: $(du -sh "$BACKUP_DIR" | cut -f1)"
EOF
chmod +x ~/backup.sh
🛠️ Полезные инструменты для DevOps #
Мониторинг системы #
# htop - интерактивный монитор процессов
sudo apt install htop
# iotop - мониторинг дисковой активности
sudo apt install iotop
sudo iotop
# nethogs - мониторинг сетевой активности по процессам
sudo apt install nethogs
sudo nethogs
# glances - универсальный системный монитор
pip install glances
glances
Работа с JSON в командной строке #
# jq - парсер JSON
sudo apt install jq
# Примеры использования
curl -s https://api.github.com/users/octocat | jq '.name'
echo '{"name":"John","age":30}' | jq '.name'
cat config.json | jq '.database.host'
Управление пакетами #
# Ubuntu/Debian (apt)
sudo apt update # обновить списки пакетов
sudo apt upgrade # обновить установленные пакеты
sudo apt install package_name # установить пакет
sudo apt remove package_name # удалить пакет
sudo apt search keyword # поиск пакетов
# CentOS/RHEL (yum/dnf)
sudo yum update # обновить систему
sudo yum install package_name # установить пакет
sudo yum remove package_name # удалить пакет
🎯 Практические задания #
Задание 1: Освоение базовых команд (30 минут) #
# 1. Создайте структуру каталогов для проекта
mkdir -p ~/devops-practice/{logs,config,scripts,data}
# 2. Создайте файлы конфигурации
touch ~/devops-practice/config/{app.conf,db.conf,nginx.conf}
# 3. Добавьте содержимое в файлы
echo "server_name=web01" > ~/devops-practice/config/app.conf
echo "database_host=localhost" > ~/devops-practice/config/db.conf
# 4. Найдите все .conf файлы в проекте
find ~/devops-practice -name "*.conf" -type f
# 5. Создайте архив проекта
tar -czf ~/devops-project-backup.tar.gz ~/devops-practice
# 6. Проверьте размер архива
ls -lh ~/devops-project-backup.tar.gz
Проверка: У вас должен получиться архив и структура каталогов с конфигурационными файлами.
Задание 2: Мониторинг системы (20 минут) #
# 1. Создайте скрипт мониторинга системы
cat > ~/system-monitor.sh << 'EOF'
#!/bin/bash
echo "=== Системная информация ==="
echo "Дата: $(date)"
echo "Uptime: $(uptime)"
echo "Пользователи онлайн: $(who | wc -l)"
echo -e "\n=== Использование диска ==="
df -h | head -n 5
echo -e "\n=== Использование памяти ==="
free -h
echo -e "\n=== Топ 5 процессов по CPU ==="
ps aux --sort=-%cpu | head -n 6
echo -e "\n=== Сетевые соединения ==="
ss -tuln | grep LISTEN | head -n 5
EOF
# 2. Сделайте скрипт исполняемым
chmod +x ~/system-monitor.sh
# 3. Запустите скрипт
~/system-monitor.sh
# 4. Настройте cron для запуска каждые 10 минут
# (crontab -e, добавить: */10 * * * * ~/system-monitor.sh >> ~/system-monitor.log)
Проверка: Скрипт должен показывать актуальную информацию о системе.
Задание 3: Работа с процессами и сервисами (25 минут) #
# 1. Найдите процесс nginx (если установлен)
ps aux | grep nginx
# 2. Проверьте статус системных сервисов
systemctl status ssh
systemctl status cron
# 3. Создайте простой демон-сервис
sudo tee /etc/systemd/system/devops-demo.service > /dev/null << 'EOF'
[Unit]
Description=DevOps Demo Service
After=network.target
[Service]
Type=simple
User=nobody
ExecStart=/bin/bash -c 'while true; do echo "Demo service running: $(date)" >> /tmp/demo.log; sleep 60; done'
Restart=always
[Install]
WantedBy=multi-user.target
EOF
# 4. Перезагрузите systemd и запустите сервис
sudo systemctl daemon-reload
sudo systemctl start devops-demo
sudo systemctl status devops-demo
# 5. Проверьте логи сервиса
tail -f /tmp/demo.log
# 6. Остановите и отключите сервис
sudo systemctl stop devops-demo
sudo systemctl disable devops-demo
Проверка: Сервис должен создавать записи в логе каждую минуту.
Задание 4: Работа с сетью и безопасностью (20 минут) #
# 1. Проверьте открытые порты
ss -tuln
# 2. Проверьте подключения к определенному порту
ss -tuln | grep :22 # SSH порт
# 3. Проверьте маршрутизацию
ip route show
# 4. Создайте простой firewall скрипт
cat > ~/firewall-basic.sh << 'EOF'
#!/bin/bash
echo "Настройка базовых правил firewall..."
# Разрешить локальный трафик
sudo iptables -A INPUT -i lo -j ACCEPT
# Разрешить установленные соединения
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Разрешить SSH
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Разрешить HTTP/HTTPS
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Показать текущие правила
sudo iptables -L -n
EOF
chmod +x ~/firewall-basic.sh
# 5. Проверьте текущие правила iptables (не запускайте скрипт!)
sudo iptables -L -n
Проверка: Вы должны понимать, какие порты открыты и как работают базовые правила firewall.
Задание 5: Автоматизация с помощью скриптов (35 минут) #
# 1. Создайте скрипт для backup и ротации логов
cat > ~/log-manager.sh << 'EOF'
#!/bin/bash
LOG_DIR="/var/log"
BACKUP_DIR="$HOME/log-backups"
DATE=$(date +"%Y%m%d_%H%M%S")
# Создать каталог для backup если не существует
mkdir -p "$BACKUP_DIR"
# Функция для backup логов
backup_logs() {
local log_pattern="$1"
local backup_name="$2"
echo "Создание backup для: $log_pattern"
# Найти и архивировать логи
find $LOG_DIR -name "$log_pattern" -type f -size +1M | \
tar -czf "$BACKUP_DIR/${backup_name}_$DATE.tar.gz" -T -
if [ $? -eq 0 ]; then
echo "Backup создан: ${backup_name}_$DATE.tar.gz"
else
echo "Ошибка создания backup для $log_pattern"
fi
}
# Backup различных типов логов
backup_logs "*.log" "system_logs"
backup_logs "auth.log*" "auth_logs"
backup_logs "syslog*" "sys_logs"
# Удалить backup старше 7 дней
find "$BACKUP_DIR" -name "*.tar.gz" -type f -mtime +7 -delete
# Показать статистику backup
echo -e "\n=== Статистика backup ==="
echo "Всего backup файлов: $(ls -1 $BACKUP_DIR/*.tar.gz 2>/dev/null | wc -l)"
echo "Общий размер: $(du -sh $BACKUP_DIR 2>/dev/null | cut -f1)"
ls -lh "$BACKUP_DIR" | tail -n 5
EOF
# 2. Сделайте скрипт исполняемым
chmod +x ~/log-manager.sh
# 3. Создайте скрипт для проверки здоровья системы
cat > ~/health-check.sh << 'EOF'
#!/bin/bash
# Пороговые значения
CPU_THRESHOLD=80
MEMORY_THRESHOLD=85
DISK_THRESHOLD=90
# Цвета для вывода
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
# Функция проверки CPU
check_cpu() {
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | awk -F'%' '{print $1}')
cpu_usage=${cpu_usage%.*} # Убрать дробную часть
echo -n "CPU Usage: ${cpu_usage}% - "
if [ "$cpu_usage" -gt "$CPU_THRESHOLD" ]; then
echo -e "${RED}HIGH${NC}"
return 1
elif [ "$cpu_usage" -gt 50 ]; then
echo -e "${YELLOW}MEDIUM${NC}"
return 0
else
echo -e "${GREEN}OK${NC}"
return 0
fi
}
# Функция проверки памяти
check_memory() {
memory_usage=$(free | grep Mem | awk '{printf("%.0f", $3/$2 * 100)}')
echo -n "Memory Usage: ${memory_usage}% - "
if [ "$memory_usage" -gt "$MEMORY_THRESHOLD" ]; then
echo -e "${RED}HIGH${NC}"
return 1
elif [ "$memory_usage" -gt 70 ]; then
echo -e "${YELLOW}MEDIUM${NC}"
return 0
else
echo -e "${GREEN}OK${NC}"
return 0
fi
}
# Функция проверки диска
check_disk() {
disk_usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
echo -n "Disk Usage: ${disk_usage}% - "
if [ "$disk_usage" -gt "$DISK_THRESHOLD" ]; then
echo -e "${RED}HIGH${NC}"
return 1
elif [ "$disk_usage" -gt 75 ]; then
echo -e "${YELLOW}MEDIUM${NC}"
return 0
else
echo -e "${GREEN}OK${NC}"
return 0
fi
}
# Основная проверка
echo "=== Health Check $(date) ==="
check_cpu
check_memory
check_disk
# Проверка критичных сервисов
echo -e "\n=== Service Status ==="
for service in ssh cron; do
if systemctl is-active --quiet $service; then
echo -e "$service: ${GREEN}RUNNING${NC}"
else
echo -e "$service: ${RED}STOPPED${NC}"
fi
done
echo -e "\n=== Load Average ==="
uptime
EOF
chmod +x ~/health-check.sh
# 4. Запустите скрипты
~/health-check.sh
Проверка: Скрипты должны выполняться без ошибок и показывать цветную статистику системы.
📊 Проверочный тест #
После выполнения всех заданий ответьте на вопросы:
- Какая команда показывает использование диска в человекочитаемом формате?
- Как найти все файлы больше 10MB в каталоге /var?
- Какой командой можно посмотреть активные сетевые соединения?
- Как запустить процесс в фоне и отключить от терминала?
- Какая команда покажет последние 20 строк файла и будет следить за изменениями?
Ответы:
df -h
find /var -size +10M -type f
ss -tuln
илиnetstat -tuln
nohup command &
tail -f -n 20 filename
🎯 Заключение #
Linux командная строка — это основной инструмент DevOps инженера. Ключевые навыки:
✅ Навигация и управление файлами
✅ Работа с процессами и сервисами
✅ Понимание прав доступа
✅ Bash скриптинг для автоматизации
✅ Сетевая диагностика
✅ Системный мониторинг
🔢 Системные лимиты: скрытые ловушки #
🚨 Реальная проблема: Настроили лимит пользователю на 1024 открытых файла, а приложение через systemd жрет 4 миллиона дескрипторов!
Проблема с systemd юнитами #
Что происходит:
# Устанавливаем лимит пользователю
echo "myuser soft nofile 1024" >> /etc/security/limits.conf
echo "myuser hard nofile 2048" >> /etc/security/limits.conf
# Проверяем лимит под пользователем
su - myuser
ulimit -n
# Вывод: 1024 ✅
# НО приложение запускается через systemd unit!
# И лимиты пользователя НЕ ДЕЙСТВУЮТ на systemd сервисы!
Реальный пример проблемы:
# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
User=myuser
Group=myuser
ExecStart=/opt/myapp/server
# ❌ НЕТ лимитов! Systemd использует свои дефолтные
[Install]
WantedBy=multi-user.target
✅ Правильное решение #
Устанавливаем лимиты в systemd unit:
# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
User=myuser
Group=myuser
ExecStart=/opt/myapp/server
# 🔥 ВАЖНО: Явно указываем лимиты в юните!
LimitNOFILE=1024:2048 # мягкий:жесткий лимит на файлы
LimitNPROC=512:1024 # лимит на процессы
LimitMEMLOCK=64K:64K # лимит на заблокированную память
LimitCORE=0 # отключить core dumps
[Install]
WantedBy=multi-user.target
🛠️ Диагностика лимитов #
Проверяем лимиты running процесса:
# Находим PID процесса
ps aux | grep myapp
# PID: 1234
# Смотрим реальные лимиты процесса
cat /proc/1234/limits
# Name Soft Limit Hard Limit Units
# Max open files 1048576 1048576 files ← systemd default!
# Max processes unlimited unlimited processes
# Смотрим сколько файлов РЕАЛЬНО открыто
lsof -p 1234 | wc -l
# 4000000 ← вот откуда проблема!
# Или через /proc
ls -la /proc/1234/fd | wc -l
Практическая диагностика:
# Скрипт для мониторинга лимитов
#!/bin/bash
check_service_limits() {
local service_name=$1
local pid=$(systemctl show --property MainPID --value $service_name)
if [ "$pid" -eq 0 ]; then
echo "Service $service_name not running"
return 1
fi
echo "=== Service: $service_name (PID: $pid) ==="
echo "Current limits:"
grep -E "(open files|processes)" /proc/$pid/limits
echo "Current usage:"
echo "Open files: $(ls /proc/$pid/fd 2>/dev/null | wc -l)"
echo "Threads: $(ls /proc/$pid/task 2>/dev/null | wc -l)"
echo
}
# Использование
check_service_limits nginx
check_service_limits myapp
🎯 Практические рекомендации #
1. Всегда проверяйте лимиты в юнитах:
# После создания/изменения сервиса
systemctl daemon-reload
systemctl restart myapp
systemctl show myapp | grep -i limit
2. Мониторьте использование ресурсов:
# Создайте алерт на высокое использование
#!/bin/bash
SERVICE="myapp"
PID=$(systemctl show --property MainPID --value $SERVICE)
FD_COUNT=$(ls /proc/$PID/fd 2>/dev/null | wc -l)
FD_LIMIT=$(grep "Max open files" /proc/$PID/limits | awk '{print $4}')
if [ $FD_COUNT -gt $((FD_LIMIT * 80 / 100)) ]; then
echo "WARNING: $SERVICE using $FD_COUNT/$FD_LIMIT file descriptors (>80%)"
fi
3. Типичные лимиты для разных сервисов:
# Веб-сервер (nginx, apache)
LimitNOFILE=65536:65536
LimitNPROC=4096:4096
# База данных (PostgreSQL, MySQL)
LimitNOFILE=65536:65536
LimitMEMLOCK=infinity
LimitNPROC=8192:8192
# Микросервис с высокой нагрузкой
LimitNOFILE=32768:32768
LimitNPROC=2048:2048
LimitCORE=0 # отключить для продакшена
⚠️ Частые ошибки: #
- Забыли systemctl daemon-reload после изменения юнита
- Не перезагрузили сервис после изменения лимитов
- Установили слишком низкие лимиты для высоконагруженных приложений
- Не мониторят реальное потребление ресурсов
📋 Checklist проверки лимитов: #
- Проверил лимиты в /etc/security/limits.conf
- Добавил лимиты в systemd unit файл
- Выполнил
systemctl daemon-reload
- Перезапустил сервис
- Проверил реальные лимиты через /proc/PID/limits
- Настроил мониторинг использования ресурсов
Помните: Не пытайтесь выучить все команды сразу. Изучайте по мере необходимости и постоянно практикуйтесь. Командная строка станет вашим лучшим другом в DevOps!
Следующий раздел: 2.2 Git и системы контроля версий