ya-hochu-sozdat-proekt-pro-o/index.html

198 lines
32 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Routing Engine Juniper — Полное руководство</title>
<style>
* { margin: 0; box-sizing: border-box; }
body { font-family: -apple-system, "Segoe UI", Roboto, sans-serif; background: #0f1218; color: #f4f4f5; }
.slide { display: none; min-height: 100vh; padding: 8vh 10vw; flex-direction: column; justify-content: center; }
.slide.on { display: flex; }
.slide h1 { font-size: clamp(28px, 5vw, 48px); margin-bottom: 20px; }
.slide h2 { font-size: clamp(22px, 4vw, 36px); margin-bottom: 16px; color: #00b8cc; }
.slide li { font-size: clamp(16px, 2.4vw, 24px); line-height: 1.5; margin-bottom: 8px; list-style: none; padding-left: 24px; position: relative; }
.slide li::before { content: ""; position: absolute; left: 0; top: .55em; width: 10px; height: 10px; border-radius: 2px; background: #00b8cc; }
.num { position: fixed; bottom: 18px; right: 22px; color: #8a8a92; font-size: 14px; }
.nav { position: fixed; bottom: 14px; left: 22px; display: flex; gap: 8px; flex-wrap: wrap; max-width: 60vw; }
.nav button { border: 1px solid #333; background: #171719; color: #f4f4f5; border-radius: 8px; padding: 6px 12px; cursor: pointer; font-size: 13px; }
.nav .pptx { border-color: #00b8cc; color: #9beeff; }
.nav .prev-next { border-color: #00b8cc; }
@media print {
.nav, .num { display: none; }
.slide { display: flex; page-break-after: always; min-height: 100vh; }
}
</style>
</head>
<body>
<div id="deck"></div>
<div class="nav">
<button class="prev-next" onclick="go(-1)">← Назад</button>
<button class="prev-next" onclick="go(1)">Вперёд →</button>
<button class="pptx" onclick="downloadPptx()">📥 Скачать .pptx</button>
</div>
<div class="num" id="num"></div>
<script>
var SLIDES = [
{ title: "Routing Engine (RE) на Juniper", bullets: ["Полное практическое руководство для начинающего инженера", "От теории до пошаговых алгоритмов при авариях", "Команды → вывод → что искать → норма → проблема", "30+ слайдов с реальными примерами"] },
{ title: "1. Что такое Routing Engine?", bullets: ["RE (Routing Engine) — это «мозг» маршрутизатора", "Технически: отдельная плата с CPU, RAM, SSD/HDD", "На RE работает операционная система Junos", "RE управляет: таблицами маршрутизации, протоколами, CLI, логами, конфигурацией", "Важно: RE НЕ обрабатывает пакеты трафика — этим занимается PFE"] },
{ title: "RE vs FPC/PFE — в чём разница", bullets: ["RE (Routing Engine) = управляющая плоскость (Control Plane)", "FPC/PFE (Packet Forwarding Engine) = плоскость данных (Forwarding Plane)", "RE думает: строит таблицы, считает маршруты, отвечает на команды", "PFE делает: переключает пакеты на аппаратной скорости", "Аналогия: RE = диспетчер такси, PFE = водитель, который везёт"] },
{ title: "Control Plane vs Forwarding Plane", bullets: ["Control Plane (RE): OSPF, BGP, LACP, BFD, SNMP, SSH, CLI", "Forwarding Plane (PFE): пакеты данных, ACL на скорости, NAT, фильтры", "Почему это важно: высокая загрузка CPU на RE ≠ тормозит трафик", "Трафик идёт через PFE, RE только управляет правилами", "Проблема на RE = не сходятся протоколы, нет управления"] },
{ title: "Схема: как работает маршрутизатор", bullets: ["RE → управление и маршрутизация → FPC/PFE → передача трафика", "Протоколы на RE: OSPF, BGP, LACP, BFD, SNMP, SYSLOG", "Пакеты через PFE: входящий порт → ASIC → исходящий порт", "RE загружен на 100%? Трафик ещё идёт, но протоколы отваливаются", "RE умер? Зависит от модели: некоторые продолжают forwarding"] },
{ title: "Что будет при отказе RE", bullets: ["Если RE один (standalone): потеря управления, протоколы падают", "Трафик может идти ещё некоторое время (PFE работает)", "Если dual-RE (Master/Backup): автоматический переход на Backup", "Routing Engine Redundancy = два RE, один активный, второй ждёт", "Graceful Routing Engine Switchover (GRES) = без разрыва сессий"] },
{ title: "Master / Backup RE", bullets: ["Master RE = активный, обрабатывает всё", "Backup RE = горячий резерв, синхронизирован с Master", "При отказе Master: Backup становится Master за секунды", "Команда: show chassis routing-engine → покажет кто Master", "Настройка: redundancy group, GRES, NSR (Non-Stop Routing)"] },
{ title: "2. show chassis routing-engine — главная команда", bullets: ["Показывает: состояние RE, температуру, память, CPU, uptime", "Команда: show chassis routing-engine", "Вывод: по строкам разберём каждое поле", "Норма: Temperature < 70°C, Memory < 80%, CPU Idle > 50%", "Проблема: Alarm, Memory > 90%, CPU Idle < 10%"] },
{ title: "Пример вывода show chassis routing-engine", bullets: ["Routing Engine status:", " Temperature 45 degrees C / 113 degrees F", " Memory utilization 68 percent", " CPU utilization:", " User 5 percent", " Background 1 percent", " Kernel 8 percent", " Interrupt 0 percent", " Idle 86 percent"] },
{ title: "CPU utilization — расшифровка", bullets: ["User = процессы пользовательского уровня (rpd, mgd, snmpd)", "Kernel = системные вызовы ядра", "Interrupt = обработка прерываний от оборудования", "Idle = свободный CPU (чем больше, тем лучше)", "Сумма User + Kernel + Interrupt + Idle = 100%", "Пример: 5 + 1 + 8 + 86 = 100% → норма, CPU свободен на 86%"] },
{ title: "CPU utilization — что искать", bullets: ["Норма: Idle > 50%, User + Kernel < 40%", "Тревога: Idle < 20% более 5 минут", "Проблема: Idle < 10% постоянно — искать процесс", "Interrupt > 10% = проблема с оборудованием или драйвером", "Смотри 3 значения: 5 сек / 1 мин / 15 мин — тренд важнее момента"] },
{ title: "Почему Alarm не всегда означает проблему сейчас", bullets: ["Alarm: High CPU utilization over 90% for 5m", "Это значит: 5 минут назад CPU был > 90% в течение 5 минут", "Сейчас CPU может быть уже 30% — alarm ещё не сброшен", "Всегда проверяй текущий CPU + смотри логи", "Alarm cleared появится, когда проблема ушла"] },
{ title: "Uptime и загрузка", bullets: ["Start time = когда RE загрузился в последний раз", "Uptime = сколько работает без перезагрузки", "Last reboot reason = причина перезагрузки", "Норма: uptime растёт, reason = power cycle или reboot от админа", "Проблема: reason = Kernel panic, Watchdog timeout, Power failure"] },
{ title: "Load Average — что это", bullets: ["Load averages: 0.45, 0.38, 0.42 (1 / 5 / 15 min)", "Среднее число процессов, ждущих CPU", "Норма: < 1.0 на одно ядро (для 4 ядер норма до 4.0)", "Растёт = нагрузка увеличивается", "Падает = нагрузка снижается", "Сравнивай с CPU Idle: если Idle высокий, а Load растёт — очередь процессов"] },
{ title: "3. CPU RE — процессы", bullets: ["Команда: show system processes extensive", "Ищет топ процессов: | match PID | sort", "Пример вывода:", " PID CPU COMMAND", " 1234 25% rpd", " 5678 10% mgd", " 9012 5% snmpd", "Ищи процесс с максимальным CPU — это причина нагрузки"] },
{ title: "Основные процессы Junos — расшифровка", bullets: ["rpd = Routing Protocol Daemon (OSPF, BGP, LDP, RSVP) — главный", "mgd = Management Daemon (CLI, NETCONF, SSH) — управление", "snmpd = SNMP Daemon (опросы, трапы)", "chassisd = Chassis Daemon (оборудование, вентиляторы, питание)", "lacpd = LACP Daemon (агрегация линков)", "bfdd = BFD Daemon (быстрая диагностика соседей)"] },
{ title: "4. Memory RE — память", bullets: ["Memory utilization = процент занятой оперативной памяти", "Норма: до 80%", "Тревога: 80-90% — следить", "Проблема: > 90% — искать процесс, который ест память", "Память ≠ CPU: можно иметь CPU Idle 87% при Memory 92%"] },
{ title: "Почему 90% памяти не всегда авария", bullets: ["Junos заранее резервирует память для стабильности", "Часть памяти используется под кэш — освободится при необходимости", "Проблема: память растёт постоянно и не освобождается", "Смотри: show system memory — детально по процессам", "Ищи процесс с растущим Memory — это утечка"] },
{ title: "Команды для памяти", bullets: ["show chassis routing-engine → общая утилизация", "show system memory → детально по процессам", "show system processes extensive → PID + CPU + Memory", "Фильтр: show system memory | match rpd", "Проблема: процесс rpd ест 2GB и растёт — перезапустить или искать баг"] },
{ title: "5. Температура RE", bullets: ["Команды: show chassis environment, show chassis routing-engine", "Routing Engine OK 38 degrees C → норма", "Routing Engine CPU OK 50 degrees C → норма", "OK = температура в рабочем диапазоне", "Warning =接近 границы, Critical = перегрев"] },
{ title: "Температура — расшифровка полей", bullets: ["Routing Engine = температура платы RE", "Routing Engine CPU = температура процессора (всегда выше)", "Intake = температура на вдуве (холодный воздух)", "Exhaust = температура на выдуве (горячий воздух)", "TFEB = температура forwarding board", "PEM = температура блока питания", "Fan = скорость вентиляторов"] },
{ title: "Пример show chassis environment", bullets: ["Routing Engine OK 38 degrees C", "Routing Engine CPU OK 50 degrees C", "Intake OK 24 degrees C", "Exhaust OK 35 degrees C", "Fan Tray 0 OK Spinning at normal speed", "PEM 0 OK OK", "PEM 1 OK OK"] },
{ title: "Перегрев vs CPU — как отличить", bullets: ["Перегрев: Temperature alarm, Fan at high speed, Intake > 35°C", "CPU: CPU utilization высокий, Temperature в норме", "Проверь: show chassis environment | match Temperature", "Проверь: show chassis routing-engine | match CPU", "Перегрев → чистить фильтры, проверять вентиляторы", "CPU → искать процесс, который грузит"] },
{ title: "6. Питание и PEM", bullets: ["PEM (Power Entry Module) = блок питания", "Обычно 2 PEM: Master/Backup для резервирования", "Команды: show chassis environment, show chassis hardware", "Проблема: FPC 0 PEM 0 is not powered", "Оба PEM присутствуют, но один не запитан — проверь кабель питания"] },
{ title: "Диагностика PEM", bullets: ["show chassis hardware → статус PEM (Present/Absent)", "show chassis environment → PEM OK/Failed", "show chassis alarms → alarms по питанию", "show system alarms → системные alarms", "Пример: PEM 0 Present но not powered → кабель не подключён"] },
{ title: "7. Вентиляторы и охлаждение", bullets: ["Команда: show chassis environment | match Fan", "Fan Tray OK Spinning at normal speed → норма", "Spinning at intermediate-speed → средняя скорость (тепло)", "Spinning at high-speed → проблема, перегрев", " Fan не крутится → авария, чинить немедленно"] },
{ title: "8. Alarms RE — типы", bullets: ["show chassis alarms → alarms оборудования", "show system alarms → системные alarms", "Major = критическая авария (красный)", "Minor = предупреждение (жёлтый)", "Cleared = alarm сброшен, проблема ушла", "Всегда смотри время alarm — когда началось"] },
{ title: "Примеры alarms и что делать", bullets: ["High CPU utilization → show system processes extensive", "High Memory utilization → show system memory", "Temperature warning → show chassis environment", "PEM not powered → проверить кабель питания", "Fan failed → заменить вентилятор", "Interface down → show interfaces terse"] },
{ title: "9. Логи RE — show log messages", bullets: ["Команда: show log messages — главный системный лог", "Фильтры: | match CPU, | match rpd, | match PEM, | match power", "Последние 100 строк: show log messages | last 100", "Смотри время событий — последовательность важна", "Пример: BFD DOWN → LACP timeout → порт выпал из AE"] },
{ title: "Пример: цепочка событий в логах", bullets: ["10:15:03 BFD session to 10.0.0.1 DOWN", "10:15:05 LACP timeout on xe-0/1/1", "10:15:05 Port xe-0/1/1 removed from ae8", "10:15:10 LACP collecting distributing on xe-0/1/1", "10:15:12 BFD session to 10.0.0.1 UP", "Вывод: LACP timeout не всегда физический flap — мог быть сбой BFD"] },
{ title: "10. RE и BGP", bullets: ["BGP работает на RE — процесс rpd", "Высокая загрузка RE = BGP сессии падают", "Команды: show bgp summary, show bgp neighbor, show route", "Состояния BGP: Idle → Connect → Active → OpenSent → OpenConfirm → Established", "Established = норма, всё остальное = проблема"] },
{ title: "BGP — диагностика", bullets: ["show bgp summary → все пиры, состояние, префиксы", "Смотри: State/PfxRcd = Established или число префиксов", "Проблема: Active = не может соединиться, Idle = не стартует", "show bgp neighbor <IP> → детально по соседу", "show route protocol bgp → маршруты от BGP"] },
{ title: "11. RE и OSPF", bullets: ["OSPF работает на RE — процесс rpd", "Команды: show ospf neighbor, show ospf interface", "Соседство: Init → 2-Way → ExStart → Exchange → Loading → Full", "Full = норма", "Проблема: сосед упал — проверь Hello/Dead timers, MTU, area"] },
{ title: "OSPF — что проверять", bullets: ["show ospf neighbor → статус соседей (Full/Init/Down)", "show ospf interface → интерфейсы в OSPF", "Сосед Down → физика, L2, таймеры, area mismatch", "Сосед Full но нет маршрутов → filter, distribute-list", "RE загружен → OSPF Hello могут теряться → соседство падает"] },
{ title: "12. RE и LACP / AE", bullets: ["AE (Aggregated Ethernet) = агрегированный интерфейс (LACP)", "LACP работает на RE — процесс lacpd", "Команды: show interfaces ae8, show lacp interfaces ae8", "Порт может быть UP физически, но вне агрегата", "LACP timeout = порт временно выпал из AE"] },
{ title: "LACP timeout — пример", bullets: ["show lacp interfaces ae8:", " Port xe-0/1/1: Collecting distributing (норма)", " Port xe-0/1/2: LACP timeout (проблема)", "show interfaces xe-0/1/2 | match flap:", " Input errors: 0, Output errors: 0 (физика в порядке)", "Вывод: порт выпал из AE не по физике — проблема LACP на RE"] },
{ title: "13. Физическая vs протокольная проблема", bullets: ["Physical link DOWN → интерфейс, SFP, оптика, кабель", "LACP timeout → LACP daemon, таймауты, настройки AE", "BFD DOWN → BFD сессия, сосед, CPU RE", "BGP DOWN → BGP peer, ASN, password, filter", "CPU >90% → процессы RE", "Memory >90% → память RE", "Temperature alarm → охлаждение", "PEM alarm → питание"] },
{ title: "Таблица: что проверять", bullets: ["DOWN порта → show interfaces terse, show optics", "LACP timeout → show lacp interfaces, show lacp timeouts", "BFD DOWN → show bfd session, show log messages", "BGP DOWN → show bgp summary, show bgp neighbor", "Packet loss → ping, traceroute, show interfaces extensive", "High CPU → show system processes extensive", "High Memory → show system memory", "Temperature → show chassis environment", "PEM → show chassis hardware, show chassis alarms"] },
{ title: "14. Алгоритм: Alarm → расследование", bullets: ["1. Alarm: записать время и текст", "2. show chassis routing-engine → текущее состояние", "3. CPU нормальный? → show system processes extensive", "4. Какой процесс грузил? → сортировка по CPU", "5. show log messages → когда началось", "6. Заключение: процесс X, причина Y, действие Z"] },
{ title: "Алгоритм: Physical Port Down", bullets: ["1. show interfaces terse → статус порта", "2. show interfaces <port> extensive → ошибки, оптика", "3. show optics <port> → уровень сигнала (dBm)", "4. show log messages | match <port> → flaps", "5. Вывод: физика (SFP/кабель) или сосед выключил порт"] },
{ title: "Алгоритм: LACP Timeout", bullets: ["1. show lacp interfaces <ae> → какие порты в timeout", "2. show lacp timeouts <ae> → таймауты", "3. show interfaces <port> | match flap → физические flaps", "4. show log messages | match LACP → события", "5. Вывод: проблема LACP на RE или физическая"] },
{ title: "Алгоритм: BFD Down", bullets: ["1. show bfd session → статус сессий", "2. show bfd neighbor → сосед", "3. show log messages | match BFD → когда DOWN/UP", "4. show system processes extensive | match bfdd → процесс", "5. Вывод: BFD сессия упала из-за RE или сети"] },
{ title: "Алгоритм: Packet Loss", bullets: ["1. ping <destination> → есть ли потери", "2. traceroute <destination> → где потери", "3. show interfaces extensive → ошибки на интерфейсах", "4. show route <destination> → маршрут", "5. show bgp summary / show ospf neighbor → протоколы", "6. Вывод: физика, перегрузка канала, маршрут"] },
{ title: "Алгоритм: High Memory", bullets: ["1. show chassis routing-engine → Memory utilization", "2. show system memory → топ процессов по памяти", "3. show system processes extensive → PID + Memory", "4. show log messages | match memory → OOM events", "5. Вывод: процесс X ест память — перезапустить или искать баг"] },
{ title: "Алгоритм: Temperature Alarm", bullets: ["1. show chassis environment → температуры, вентиляторы", "2. show chassis routing-engine → температура RE/CPU", "3. Проверить: фильтры, вентиляторы, температуру в помещении", "4. show log messages | match temperature → история", "5. Вывод: перегрев — чистить или менять охлаждение"] },
{ title: "15. Шпаргалка: команды наизусть (часть 1)", bullets: ["show chassis routing-engine → состояние RE (CPU, память, температура)", "show chassis environment → охлаждение, вентиляторы, PEM", "show chassis alarms → alarms оборудования", "show system alarms → системные alarms", "show chassis hardware → всё оборудование, статусы", "show system processes extensive → процессы, CPU, память", "show system memory → память по процессам"] },
{ title: "Шпаргалка: команды наизусть (часть 2)", bullets: ["show interfaces terse → все интерфейсы кратко", "show interfaces extensive → детально по интерфейсу", "show interfaces <port> | match flap → flaps порта", "show lacp interfaces <ae> → LACP статус", "show lacp timeouts <ae> → таймауты LACP", "show bgp summary → все BGP пиры", "show bgp neighbor → детально по BGP соседу", "show ospf neighbor → соседи OSPF", "show ospf interface → интерфейсы OSPF"] },
{ title: "Шпаргалка: команды наизусть (часть 3)", bullets: ["show log messages → главный лог", "show log messages | match <keyword> → поиск по логу", "show log messages | last 100 → последние 100 строк", "show route → таблица маршрутизации", "show route protocol bgp → BGP маршруты", "ping <host> → проверка доступности", "traceroute <host> → путь до хоста", "test interface <port> → тест порта"] },
{ title: "16. Сценарий 1: CPU >90%", bullets: ["Что произошло: CPU RE загружен на 90%+", "Что значит: процессы RE не успевают, протоколы могут падать", "Команды: show chassis routing-engine, show system processes extensive", "Смотреть: какой процесс в топе по CPU", "Норма: CPU Idle > 50%", "Проблема: Idle < 10% постоянно", "Дальше: show log messages | match <PID>", "Отчёт: Процесс rpd загружал CPU на 95% в 10:15. Причина: BGP flaps. Решение: стабилизировал BGP. Сейчас CPU Idle 85%"] },
{ title: "Сценарий 2: Memory 92%", bullets: ["Что произошло: память RE занята на 92%", "Что значит: может быть OOM (Out of Memory), процессы умрут", "Команды: show chassis routing-engine, show system memory", "Смотреть: какой процесс ест память", "Норма: Memory < 80%", "Проблема: > 90% и растёт", "Дальше: show log messages | match memory", "Отчёт: Memory 92%, процесс snmpd ест 1.5GB. Перезапущен. Сейчас Memory 68%"] },
{ title: "Сценарий 3: Physical Port Down", bullets: ["Что произошло: порт xe-0/1/1 DOWN", "Что значит: физический линк не поднят", "Команды: show interfaces terse, show interfaces xe-0/1/1 extensive, show optics", "Смотреть: Link status, Optical diagnostics", "Норма: Link status Up, Optical signal в пределах", "Проблема: Link Down, No light, Signal too low", "Дальше: проверить SFP, кабель, сосед", "Отчёт: Порт xe-0/1/1 DOWN. SFP показывает No light. Кабель заменён. Порт Up"] },
{ title: "Сценарий 4: LACP Timeout", bullets: ["Что произошло: порт выпал из агрегата AE", "Что значит: LACP timeout, трафик не идёт через этот порт", "Команды: show lacp interfaces ae8, show lacp timeouts ae8", "Смотреть: какие порты в timeout, Collecting distributing", "Норма: все порты Collecting distributing", "Проблема: LACP timeout, No LACP PDUs", "Дальше: show log messages | match LACP", "Отчёт: Порт xe-0/1/2 LACP timeout. Причина: таймауты LACP PDUs. Перезапуск LACP. Порт в агрегате"] },
{ title: "Сценарий 5: BFD Down", bullets: ["Что произошло: BFD сессия DOWN", "Что значит: быстрый детект сбоя соседа", "Команды: show bfd session, show bfd neighbor", "Смотреть: State (Up/Down), локальный и удалённый адрес", "Норма: State Up", "Проблема: State Down", "Дальше: show log messages | match BFD", "Отчёт: BFD сессия к 10.0.0.1 DOWN в 10:15. Причина: RE перегружен. BFD UP в 10:17.CPU стабилизирован"] },
{ title: "Сценарий 6: BGP Peer Down", bullets: ["Что произошло: BGP сосед не в Established", "Что значит: маршруты не передаются", "Команды: show bgp summary, show bgp neighbor <IP>", "Смотреть: State/PfxRcd, Last State", "Норма: Established или число префиксов", "Проблема: Active, Idle, Connect", "Дальше: show log messages | match BGP", "Отчёт: BGP peer 192.168.1.1 State Active. Причина: password mismatch. Исправлено. Established"] },
{ title: "Сценарий 7: Packet Loss", bullets: ["Что произошло: потери пакетов 10-30%", "Что значит: трафик теряется, приложения тормозят", "Команды: ping, traceroute, show interfaces extensive", "Смотреть: Input/Output errors, Drops", "Норма: 0% потерь, Input errors 0", "Проблема: потери > 1%, errors растут", "Дальше: show route, show bgp summary", "Отчёт: Packet loss 15% на xe-0/1/1. Input errors растут. SFP заменён. Потери 0%"] },
{ title: "Сценарий 8: PEM not powered", bullets: ["Что произошло: PEM 0 not powered", "Что значит: блок питания не запитан, резервирование потеряно", "Команды: show chassis hardware, show chassis environment", "Смотреть: PEM статус (Present/Absent, OK/Failed)", "Норма: PEM 0 OK, PEM 1 OK", "Проблема: PEM 0 not powered", "Дальше: проверить кабель питания", "Отчёт: PEM 0 not powered. Кабель питания не подключён. Подключён. PEM 0 OK"] },
{ title: "Сценарий 9: Temperature alarm", bullets: ["Что произошло: Temperature warning/critical", "Что значит: перегрев оборудования", "Команды: show chassis environment, show chassis routing-engine", "Смотреть: Temperature, Fan speed, Intake/Exhaust", "Норма: RE < 50°C, CPU < 70°C, Fan normal", "Проблема: Temperature warning/critical, Fan high", "Дальше: проверить фильтры, вентиляторы, помещение", "Отчёт: Temperature warning 65°C. Вентиляторы на высокой скорости. Фильтры загрязнены. Заменены. Температура 42°C"] },
{ title: "Итоги: 5 шагов при любой аварии", bullets: ["1. Записать время и текст alarm", "2. show chassis routing-engine → текущее состояние RE", "3. show log messages | last 100 → последние события", "4. show chassis environment / show system processes → причина", "5. Заключение: что, когда, почему, что сделано", "Правило: всегда сравнивай с нормой и пиши отчёт"] },
{ title: "Главное правило инженера", bullets: ["Не паниковать. Alarm ≠ авария прямо сейчас", "Смотреть вывод команд целиком, не одну строку", "Сравнивать с нормой (CPU Idle > 50%, Memory < 80%, Temp < 60°C)", "Проверять тренды (5 сек / 1 мин / 15 мин)", "Писать короткое заключение: проблема → причина → действие", "Всегда проверять: а сейчас-то что?"] }
];
var cur = 0;
function render() {
var deck = document.getElementById("deck");
deck.innerHTML = SLIDES.map(function (s, i) {
return '<section class="slide' + (i === cur ? " on" : "") + '"><h1>' + s.title + '</h1><ul>' +
s.bullets.map(function (b) { return "<li>" + b + "</li>"; }).join("") + "</ul></section>";
}).join("");
document.getElementById("num").textContent = (cur + 1) + " / " + SLIDES.length;
}
function go(d) { cur = Math.min(SLIDES.length - 1, Math.max(0, cur + d)); render(); }
document.addEventListener("keydown", function (e) {
if (e.key === "ArrowRight" || e.key === " ") go(1);
if (e.key === "ArrowLeft") go(-1);
});
function downloadPptx() {
if (typeof PptxGenJS !== 'undefined') {
createPptx();
return;
}
var script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/pptxgenjs@3.12.0/dist/pptxgen.min.js';
script.onload = function() {
createPptx();
};
document.head.appendChild(script);
}
function createPptx() {
var p = new PptxGenJS();
p.defineLayout({ name: "W", width: 13.33, height: 7.5 });
p.layout = "W";
SLIDES.forEach(function (s) {
var sl = p.addSlide();
sl.background = { color: "0F1218" };
sl.addText(s.title, { x: 0.7, y: 0.5, w: 12, h: 1.2, fontSize: 32, bold: true, color: "F4F4F5" });
sl.addText(s.bullets.map(function (b) { return { text: b, options: { bullet: true, breakLine: true } }; }),
{ x: 0.9, y: 1.8, w: 11.5, h: 5.2, fontSize: 16, color: "E4E4E7", lineSpacingMultiple: 1.3 });
});
p.writeFile({ fileName: "Juniper_RE_Complete_Guide.pptx" });
}
render();
</script>
</body>
</html>