2.1 Linux основы для DevOps

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: #

  1. Никогда не используйте * в sudo правилах
  2. Всегда указывайте полные абсолютные пути
  3. Тестируйте права на проникновение (../../../)
  4. Используйте wrapper’ы для сложной логики
  5. Регулярно аудируйте файл sudoers
  6. Логируйте все 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

Проверка: Скрипты должны выполняться без ошибок и показывать цветную статистику системы.

📊 Проверочный тест #

После выполнения всех заданий ответьте на вопросы:

  1. Какая команда показывает использование диска в человекочитаемом формате?
  2. Как найти все файлы больше 10MB в каталоге /var?
  3. Какой командой можно посмотреть активные сетевые соединения?
  4. Как запустить процесс в фоне и отключить от терминала?
  5. Какая команда покажет последние 20 строк файла и будет следить за изменениями?

Ответы:

  1. df -h
  2. find /var -size +10M -type f
  3. ss -tuln или netstat -tuln
  4. nohup command &
  5. 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                # отключить для продакшена

⚠️ Частые ошибки: #

  1. Забыли systemctl daemon-reload после изменения юнита
  2. Не перезагрузили сервис после изменения лимитов
  3. Установили слишком низкие лимиты для высоконагруженных приложений
  4. Не мониторят реальное потребление ресурсов

📋 Checklist проверки лимитов: #

  • Проверил лимиты в /etc/security/limits.conf
  • Добавил лимиты в systemd unit файл
  • Выполнил systemctl daemon-reload
  • Перезапустил сервис
  • Проверил реальные лимиты через /proc/PID/limits
  • Настроил мониторинг использования ресурсов

Помните: Не пытайтесь выучить все команды сразу. Изучайте по мере необходимости и постоянно практикуйтесь. Командная строка станет вашим лучшим другом в DevOps!


Следующий раздел: 2.2 Git и системы контроля версий