Загрузить файлы в «/»

This commit is contained in:
2026-05-10 14:00:37 +00:00
commit d0548569b0
3 changed files with 494 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
# Лекция: Облачные технологии, современные серверные архитектуры и Kubernetes
## 1. Что такое облачные технологии и почему они изменили ИТ‑мир
Прежде чем рассказывать о современных серверах и оркестрации контейнеров, нужно понять базовую идею облачных технологий. Облачные технологии — это способ получать вычислительные ресурсы (процессоры, память, диски, сетевые услуги, готовые программы) через интернет точно тогда, когда они нужны, и платить только за фактическое использование. Раньше, чтобы запустить сайт или приложение, компания покупала собственные серверы, размещала их в своём дата‑центре, нанимала инженеров для обслуживания. Это было дорого, долго и негибко. Сегодня вместо покупки «железа» можно арендовать виртуальный сервер у облачного провайдера (например, Яндекс Облако, VK Cloud, AWS, Google Cloud или Microsoft Azure) и менять его мощность за пару минут.
Облачные технологии строятся на пяти основных принципах. Первый — самообслуживание по требованию: вы сами, без звонка менеджеру, создаёте виртуальную машину или базу данных через веб‑интерфейс или программу (API). Второй — широкий доступ к сети: работать с облаком можно с ноутбука, телефона, из любой точки мира, если есть интернет. Третий — объединение ресурсов: облачный провайдер обслуживает одновременно тысячи клиентов, и его физические серверы автоматически распределяются между ними. Для пользователя это выглядит как бесконечный запас процессоров и дисков. Четвёртый — эластичность: если ваш интернет‑магазин внезапно посетили сто тысяч человек, облако может за минуту добавить дополнительные мощности, а после снижения нагрузки — убрать их. Пятый — измеряемая услуга: счёт зависит от того, сколько процессорного времени, гигабайт памяти или места на диске вы реально израсходовали, например, каждый час или даже поминутно.
Эти принципы позволяют стартапам запускаться с почти нулевыми затратами на инфраструктуру, а крупным компаниям — уходить от управления собственными серверными комнатами. Но облака бывают разной «глубины» управления, и тут на сцену выходят три модели обслуживания: IaaS, PaaS и SaaS.
## 2. Три модели облачного обслуживания: кто чем управляет
Представьте, что вы хотите приготовить пиццу. SaaS — вы просто заказываете готовую пиццу с доставкой. PaaS — вам привозят тесто, соус, сыр и печь, а вы сами формируете начинку. IaaS — вам сдают кухню с холодильником и духовкой, а всё остальное вы покупаете и готовите сами. В облаках похожая логика.
**IaaS** — это «инфраструктура как услуга». Провайдер даёт вам виртуальные машины, виртуальные диски и виртуальные сети. Вы сами выбираете операционную систему, устанавливаете на неё веб‑сервер (например, nginx), базу данных, настраиваете брандмауэр. Провайдер отвечает только за то, чтобы физические серверы в их дата‑центре работали, а гипервизор (программа, создающая виртуальные машины) был исправен. IaaS даёт максимальную свободу, но требует навыков системного администратора. Типичный пример — виртуальная машина в Yandex Compute Cloud или AWS EC2, на которой вы вручную поднимаете всё приложение.
**PaaS** — платформа как услуга. Провайдер предоставляет уже готовую среду для разработки и запуска приложений. Вам не нужно думать об операционной системе, обновлениях, веб‑сервере или управлении базами данных. Вы просто загружаете свой код (например, на Python или JavaScript), а платформа сама его разворачивает, масштабирует и даже предоставляет готовые базы данных. Пользователь здесь управляет только своим приложением и данными. PaaS удобен для разработчиков, которые хотят быстро тестировать идеи, не отвлекаясь на серверные настройки. Примеры: Heroku (один из первых таких сервисов), Google App Engine, а также многие облачные функции — о них мы поговорим позже.
**SaaS** — программное обеспечение как услуга. Это самый высокий уровень абстракции. Провайдер даёт готовое приложение, которое работает в браузере или через тонкий клиент. Пользователь даже не знает, где установлена программа и на каких серверах она крутится. Он просто вводит логин и пароль и пользуется функциями — отправляет почту в Gmail, редактирует документы в Google Docs, ведёт продажи в Salesforce или общается в Slack. Здесь пользователь может только настроить свой профиль и права доступа, больше ничего.
Для понимания: IaaS подходит для сложных корпоративных систем, которые мигрируют из собственных дата‑центров. PaaS — для команды разработчиков, которая создаёт новое веб‑приложение и не хочет тратить время на серверы. SaaS — для обычных сотрудников, которым просто нужен электронный документооборот или CRM. Однако в реальной жизни эти модели часто смешиваются. Например, вы можете арендовать IaaS‑виртуалку, поставить на неё Docker и запустить своё приложение — получится как бы PaaS, но собранный вручную.
## 3. Виртуализация сетей: как облако изолирует клиентов
Любой облачный провайдер обязан обеспечить безопасность и изоляцию между разными пользователями. Представьте, что вы арендуете виртуальную машину, а злоумышленник, арендующий другую машину на том же физическом сервере, не должен иметь доступа к вашему трафику. Для этого применяется виртуализация сетей. Суть в том, что сетевые ресурсы — адреса, маршруты, правила доступа — отделяются от физической проводки и коммутаторов. На физических серверах и свитчах поднимается программно‑определяемая сеть (SDN), которая позволяет создавать виртуальные маршрутизаторы, файрволы и даже целые изолированные облачные сети для каждого клиента.
Самая популярная реализация — технология VPC (Virtual Private Cloud). Это ваша личная частная сеть внутри публичного облака. Вы сами задаёте диапазон IP‑адресов (например, 10.0.0.0/16), делите его на подсети, подключаете шлюз в интернет через NAT, настраиваете таблицы маршрутизации и списки доступа (security groups). Извне VPC не видна; попасть туда можно только через специальный VPN или через публичный IP‑адрес, который вы назначаете отдельным виртуальным машинам.
Более продвинутый уровень виртуализации — это оверлейные сети (overlay) с протоколами VXLAN или GRE. Они позволяют натянуть логическую сеть поверх существующей физической, даже если серверы разбросаны по разным стойкам и зданиям. Оверлейные сети активно используются в Kubernetes для соединения контейнеров на разных узлах.
Наконец, виртуализация сетей неразрывно связана с технологиями NFV (виртуализация сетевых функций). Вместо покупки физического маршрутизатора или файрвола за тысячи долларов, можно запустить виртуальную версию этого устройства на обычном сервере. Например, виртуальный маршрутизатор pfSense или виртуальный балансировщик нагрузки HAProxy. Облачные провайдеры именно так и делают: когда клиент включает «облачный маршрутизатор», он на самом деле получает виртуальную машину с программным маршрутизатором.
## 4. Как сейчас работают с серверами: от виртуалок к контейнерам
Студенты часто спрашивают: раз есть облачные технологии, значит ли это, что обычные серверы больше не нужны? Нет, просто подход изменился. Даже в облаке вы в конечном счёте используете физические серверы где‑то в дата‑центре провайдера. Но сегодня работа с серверами (своими или арендованными) проходит через несколько этапов эволюции.
Первый этап — физический сервер с одной операционной системой. Вы настраиваете ОС, ставите приложение и... возникает проблема: если нужно ещё одно такое же приложение, приходится покупать новый сервер. Ресурсы часто простаивают, а перенастроить что‑то сложно.
Второй этап — виртуализация с помощью гипервизора (VMware, KVM, VirtualBox). Один физический сервер может запустить десяток виртуальных машин (ВМ), каждая со своей ОС. Это гибко, позволяет изолировать приложения друг от друга, но каждая ВМ всё равно требует свою полноценную ОС, что тратит много оперативной памяти и места на диске. Гостьовая ОС может занимать 5–10 гигабайт и потреблять несколько гигабайт ОЗУ только на свою работу, не считая самого приложения.
Третий этап — контейнеризация. Контейнеры — это лёгкая альтернатива виртуальным машинам. Вместо того чтобы запускать целую ОС для каждого приложения, вы используете одно и то же ядро хостовой операционной системы, а приложение и его зависимости упаковываете в изолированный контейнер. На одной физической машине или виртуалке могут работать десятки или даже сотни контейнеров. Контейнеры запускаются за секунды, а не за минуты, как виртуальные машины, потому что им не надо загружать ядро. Самый популярный инструмент для контейнеризации — Docker. Он позволяет описать контейнер одной командой или файлом Dockerfile, а затем запускать на любом компьютере, где есть среда исполнения Docker.
Однако, когда контейнеров становится много (например, пятьдесят), возникает новая проблема. Кто будет следить, что контейнер работает? Куда его перезапустить, если сервер упал? Как добавить ещё контейнеров, когда нагрузка выросла? Как обновить версию приложения без остановки на несколько секунд? Здесь на помощь приходит система оркестрации контейнеров, и главный лидер в этой области — Kubernetes.
## 5. Kubernetes: подробнейший разбор самого популярного оркестратора
### 5.1 Зачем вообще нужен Kubernetes
Представьте, что вы разработали веб‑приложение и упаковали его в Docker‑контейнер. Вы запускаете один контейнер — всё работает. Потом ваш сервис становится популярным, и одного контейнера перестаёт хватать. Вы вручную запускаете пять контейнеров, впереди ставите балансировщик нагрузки (например, nginx) и всё настраиваете. Затем один из контейнеров падает из‑за ошибки в коде. Вы замечаете это через мониторинг, заходите на сервер, перезапускаете контейнер. Потом вам нужно выпустить новую версию приложения — вы останавливаете все контейнеры, запускаете новые, и в этот момент пользователи получают ошибки «503 Service Unavailable». Вы решаете добавить второй физический сервер для отказоустойчивости, но теперь нужно как‑то распределять контейнеры между двумя серверами и настраивать сеть между ними. Это становится крайне утомительно.
Kubernetes решает все эти проблемы. Это система, которая автоматически управляет контейнерами: запускает их на доступных серверах (узлах), перезапускает упавшие, увеличивает или уменьшает количество экземпляров под нагрузкой, распределяет сетевой трафик, обновляет приложения без остановки (постепенное обновление — rolling update) и даже откатывает обновление, если что‑то пошло не так. Kubernetes был создан в Google на основе их многолетнего опыта работы с контейнерами (внутренние системы Borg и Omega) и в 2015 году передан в открытое сообщество. Сейчас это стандарт де‑факто для управления контейнерными приложениями в индустрии.
### 5.2 Основные понятия и архитектура
Чтобы понять Kubernetes, нужно познакомиться с несколькими ключевыми сущностями. Мы будем описывать их связно, стараясь избегать оголтелых перечислений.
В центре всего находится **кластер Kubernetes**. Кластер — это группа физических или виртуальных машин, объединённых в одну вычислительную силу. Одна из машин (или несколько, если кластер большой) выполняет роль **master** (управляющий узел). Остальные машины называются **worker nodes** (рабочие узлы). Master-узел содержит несколько компонентов: хранилище состояния кластера (etcd), планировщик, который решает, на каком рабочем узле запустить контейнер, а также контроллеры, следящие за «желаемым состоянием» системы. Рабочие узлы, в свою очередь, содержат исполняющую среду (например, containerd или CRIO), агент kubelet, который общается с master и запускает контейнеры, и простой сетевой прокси (kube‑proxy) для маршрутизации трафика.
Самая маленькая deployable единица в Kubernetes — это не контейнер, а **pod** (под). Pod — это группа из одного или нескольких контейнеров, которые всегда запускаются на одном узле и делят между собой сеть и том хранения. Обычно под содержит один основной контейнер, но бывают вспомогательные, например, sidecar-контейнер, собирающий логи. Каждому поду выделяется уникальный IP‑адрес внутри кластера. Но поды временны: если под падает, Kubernetes создаёт новый под вместо него, и его IP‑адрес меняется. Поэтому напрямую обращаться к подам неудобно.
Для постоянной адресации и балансировки нагрузки используются **services** (сервисы). Сервис — это абстракция, которая объединяет несколько подов с одинаковой функцией (например, все поды, на которых работает веб‑сервер вашего приложения) и даёт им один статический виртуальный IP‑адрес и имя внутри кластера. Когда трафик приходит на сервис, он равномерно распределяется между его подами. Сервисы бывают нескольких типов: ClusterIP (доступен только внутри кластера), NodePort (открывает порт на каждом рабочем узле) и LoadBalancer (создаёт внешний облачный балансировщик, если кластер развёрнут в облаке). Именно через сервисы бессерверные функции и внешние клиенты взаимодействуют с вашими приложениями.
А как указать, сколько подов нужно запустить и как их обновлять? Для этого существуют **deployments** (развёртывания). Деплоймент — это описание желаемого состояния вашего приложения: какой образ контейнера использовать, сколько реплик (копий пода) должно работать, какую стратегию обновления применить (например, постепенное обновление: по одному поду заменять на новую версию). Вы создаёте деплоймент один раз, а дальше Kubernetes самостоятельно следит, чтобы количество работающих подов всегда соответствовало заданному. Если под умирает, деплоймент создаёт новый. Если вы увеличиваете количество реплик с трёх до десяти, Kubernetes запускает ещё семь подов на свободных узлах.
Деплоймент также поддерживает откат. Допустим, вы выпустили обновление версии 2.0, а оно содержит критическую ошибку. Kubernetes может автоматически вернуться к предыдущей версии 1.9 по вашей команде. Процесс отката тоже происходит постепенно, без даунтайма.
### 5.3 Сеть, хранение и конфигурация в Kubernetes
Приложениям часто нужно передавать настройки — адреса баз данных, секретные ключи, параметры окружения. Вручную прописывать их в образе контейнера — плохая практика, потому что образ становится небезопасным и не универсальным. Kubernetes предлагает **ConfigMap** для хранения несекретных настроек (текстовые файлы, пары ключ‑значение) и **Secret** для конфиденциальной информации (пароли, токены, ключи шифрования). Secret хранится в зашифрованном виде. Вы можете примонтировать ConfigMap или Secret к поду как переменные окружения или как файлы внутри контейнера. Если настройка поменялась, обычно требуется перезапустить под, чтобы подхватить изменения (но есть механизмы горячей перезагрузки, если само приложение умеет следить за файлами).
Следующая важная проблема — хранение данных, которые должны пережить перезапуск пода. По умолчанию файловая система контейнера эфемерна: как только под удаляется, все данные теряются. Для постоянного хранения используются **Persistent Volumes** (PV) и **Persistent Volume Claims** (PVC). PV — это ресурс хранилища, предоставляемый администратором кластера (например, сетевой диск от облачного провайдера, NFS‑шара или распределённое хранилище Ceph). PVC — это заявка пользователя на определённый объём памяти (скажем, 10 гигабайт). Когда вы создаёте PVC, Kubernetes автоматически связывает его с подходящим PV. После этого под может смонтировать этот PVC как локальную папку, и все данные будут сохраняться даже при удалении пода. При этом нужно учитывать, что за пределами Kubernetes данные на PV остаются — их нужно вручную чистить или настраивать политику удержания.
Для доступа к кластеру извне обычно используют **Ingress**. Ingress — это не обычная нагрузка на уровне L4 (по IP и порту), а интеллектуальный HTTP‑маршрутизатор. Он позволяет привязать к одному IP‑адресу несколько доменных имён и направлять запросы на разные сервисы внутри кластера в зависимости от пути (например, `/api` идёт на один сервис, а `/admin` — на другой). Ingress также умеет автоматически выпускать SSL‑сертификаты через Let's Encrypt и работать с балансировщиками облаков. Популярные реализации Ingress — NGINX Ingress Controller, Traefik, AWS ALB Ingress Controller.
### 5.4 Как Kubernetes обрабатывает отказы и масштабируется
Допустим, на одном из рабочих узлов закончилась память или сломалась операционная система. Kubelet на этом узле перестаёт отвечать Master. Master ждёт некоторое время (по умолчанию около 5 минут) и затем помечает узел как «недоступный». После этого все поды, которые работали на этом узле, объявляются утерянными. Деплойменты запускают новые поды на других здоровых узлах. Таким образом, приложение продолжает работать, если в кластере есть запас вычислительных мощностей. Это одна из главных причин, почему компании переходят на Kubernetes — он обеспечивает самовосстановление.
Горизонтальное масштабирование (увеличение количества подов) может происходить вручную через команду `kubectl scale` или автоматически, на основе метрик, таких как загрузка CPU или количество запросов в секунду. Для этого в Kubernetes есть **Horizontal Pod Autoscaler** (HPA). HPA периодически собирает метрики с каждого пода и вычисляет, нужно ли увеличить или уменьшить количество реплик. Например, вы задали целевое значение 70% использования CPU. Если средняя загрузка подов подскакивает до 90%, HPA добавит ещё несколько подов. Если нагрузка падает до 30%, HPA уберёт лишние поды. Процесс плавный, чтобы избежать резких скачков.
Также существует **Vertical Pod Autoscaler** (VPA), который может автоматически увеличивать или уменьшать запросы на память и CPU для уже работающих подов, но его используют реже, потому что для изменения ресурсов часто требуется перезапустить под.
### 5.5 Реальный пример: как работает развёртывание приложения в Kubernetes
Представьте, что у вас есть небольшое веб‑приложение на Python (Flask) и база данных PostgreSQL. Вы упаковали Flask‑приложение в Docker‑образ и отправили его в реестр контейнеров, например Docker Hub. Теперь вы хотите запустить это приложение в Kubernetes. Вам нужно создать несколько YAML‑файлов (или использовать инструменты вроде Helm). В одном файле вы описываете деплоймент для Flask‑подов: указываете образ, количество реплик (например, три), порт, переменные окружения для подключения к базе данных (используя Secret). Во втором файле вы описываете сервис типа ClusterIP, который будет направлять трафик на эти три пода. Затем вы создаёте отдельный деплоймент для PostgreSQL с одним подом и Persistent Volume Claim для хранения данных. Для PostgreSQL вы тоже создаёте внутренний сервис. После того как вы применили все эти файлы к кластеру (`kubectl apply -f`), Kubernetes запускает три копии вашего приложения, базу данных, выделяет ей диск. Внешний доступ к приложению вы организуете с помощью Ingress, который привязывает домен `myapp.example.com` к сервису Flask.
Если один из Flask‑подов упадёт из‑за ошибки, деплоймент почти мгновенно создаст новый, и сервис начнёт направлять трафик на него. Если через какое‑то время число пользователей вырастет, вы можете просто изменить количество реплик в команде или настроить автоматическое масштабирование. Если нужно обновить приложение до новой версии, вы меняете тег образа в деплойменте, и Kubernetes по очереди заменяет старые поды на новые — в любой момент времени работает минимум два пода, поэтому пользователи не замечают обновления.
### 5.6 Управление Kubernetes без головной боли: managed‑сервисы и инструменты
Настраивать Kubernetes с нуля (особенно его управляющие компоненты) сложно, поэтому большинство компаний используют готовые облачные решения. В Yandex Cloud это Managed Service for Kubernetes, в VK Cloud — управляемый Kubernetes, в AWS — EKS (Elastic Kubernetes Service), в Azure — AKS, в Google Cloud — GKE. Провайдер берёт на себя обслуживание master‑узлов, обновление компонентов, обеспечение безопасности. Вам остаётся только создавать рабочие узлы и разворачивать свои приложения. Это сильно упрощает жизнь: можно получить готовый кластер за 10 минут.
Для повседневной работы с кластером используется утилита командной строки `kubectl`. С её помощью вы смотрите статус подов (`kubectl get pods`), читаете логи (`kubectl logs`), подключаетесь внутрь контейнера (`kubectl exec`), применяете изменения и так далее. Для сложных приложений, состоящих из многих взаимосвязанных сервисов, применяются чарты Helm — упаковка YAML‑описаний с возможностью настройки параметров. Helm можно сравнить с менеджером пакетов для Kubernetes.
Очень важно понимать, что Kubernetes не решает все проблемы. Он не управляет базами данных на уровне (для stateful-приложений есть StatefulSet, но с базами данных всё равно нужно аккуратно работать). Он не даёт волшебного способа отладки сетевых проблем. И он требует обучения: команды, концепции, файлы YAML поначалу кажутся громоздкими. Однако опыт последних лет показывает, что для средних и крупных проектов, где важна надёжность и масштабируемость, инвестиции в Kubernetes оправданы.
## 6. Дополнения к лекции: бессерверные вычисления и гибридные облака
После подробного рассказа о контейнерах и Kubernetes нельзя не упомянуть, что в облаках существует ещё более абстрактная модель — **бессерверные вычисления** (Serverless). Её суть: вы пишете функцию (например, на Python или Node.js), загружаете её в облако, а там она выполняется только при наступлении какого‑то события (HTTP‑запрос, сообщение из очереди, загрузка файла). Вам не нужно арендовать серверы, запускать Kubernetes, управлять кластером — вы платите только за время работы вашей функции, помиллисекундно. AWS Lambda, Яндекс Cloud Functions, Google Cloud Functions — примеры таких сервисов. Serverless отлично подходит для обработки изображений, преобразования данных, ботов и других эпизодических задач. Но у него есть минус — «холодный старт» (cold start): если функция долго не вызывалась, облаку нужно загрузить среду, что может занять несколько секунд.
Также многие компании строят гибридные облачные архитектуры. Например, чувствительные данные о клиентах остаются на собственных серверах в локальной сети, а публичные расчёты или веб‑приложение выносятся в публичное облако. Между ними создаётся зашифрованный VPN‑туннель. Или же используют мультиоблачные стратегии: приложение одновременно работает в двух разных облаках, чтобы не зависеть от одного провайдера и повысить отказоустойчивость.
## 7. Тренды и будущее облачных технологий для студентов 09.02.07
Мы живём в время, когда облака и Kubernetes стали неотъемлемой частью работы любого DevOps-инженера и многих разработчиков. Вот несколько направлений, которые стоит держать в уме.
Во‑первых, стандартизация. Kubernetes выиграл войну оркестраторов (были ещё Docker Swarm, Apache Mesos, Nomad). Теперь вокруг него строится экосистема: сервисные сетки (Istio, Linkerd) для управления безопасным трафиком между микросервисами, инструменты для непрерывной доставки (Argo CD), мониторинг (Prometheus + Grafana) и многое другое. Студент, который знает Kubernetes и умеет работать с облаками, имеет огромное преимущество на рынке труда.
Во‑вторых, технологии edge computing. Это когда вычисления приближаются к пользователю: например, умные датчики на заводе или камеры на улицах обрабатывают данные не в дата‑центре, а на небольших серверах рядом. Там тоже можно запускать облегчённые версии Kubernetes (K3s, KubeEdge). Это позволяет быстрее реагировать на события и экономить интернет‑трафик.
В‑третьих, автоматизация всего и вся. Тенденция такова, что администраторы всё меньше заходят на серверы вручную. Всё описывается кодом (IaC — Infrastructure as Code): вы пишете конфигурацию вашей облачной инфраструктуры на Terraform или Pulumi, записываете её в репозиторий, и тогда любое изменение проходит через систему контроля версий и автоматические проверки. Сочетание Kubernetes, Git и автоматических пайплайнов даёт мощный подход GitOps: состояние кластера хранится в Git, а специальный оператор синхронизирует его с реальным кластером.
+138
View File
@@ -0,0 +1,138 @@
### 🧪 Практикум с Telnet: Шаг за шагом в мир протоколов
Эти упражнения идеально дополнят вашу лекцию о верхних уровнях модели OSI, предоставляя студентам бесценный опыт реального взаимодействия с серверами.
#### ⚙️ Подготовка перед началом
Для выполнения упражнений обязательно следует установить telnet-клиент. На Linux и macOS он часто доступен по умолчанию, а на Windows его можно активировать через «Включение или отключение компонентов Windows» или установить удобную альтернативу — утилиту `netcat` (`nc`). Также стоит предупредить студентов, что многие современные серверы могут не отвечать на текстовые команды из-за требований безопасности, поэтому для всех упражнений лучше использовать специальные тестовые хосты.
### A. 🎢 Путешествие глубже в мир HTTP
Эти упражнения длятся от 5 до 15 минут и направлены на углублённое понимание прикладного протокола HTTP.
#### **1. Отправка POST-запроса и анализ ответа**
* **Задача:** Студенты должны вручную отправить на сервер данные формы — например, простой логин и пароль.
* **Команды:**
```bash
telnet httpbin.org 80
```
```http
POST /post HTTP/1.1
Host: httpbin.org
Content-Type: application/x-www-form-urlencoded
Content-Length: 18
name=Ivan&city=Moscow
```
* **Объяснение:** Здесь студенты видят метод `POST` вместо `GET`, учатся правильно рассчитывать заголовок `Content-Length` (что критически важно для сервера) и наблюдают, как сервер возвращает отправленные данные обратно в теле ответа.
#### **2. Манипуляции с заголовками**
* **Задача:** С помощью команды `HEAD` получить только служебную информацию о ресурсе и изменить заголовок `User-Agent`, чтобы «выдать» себя за другой браузер или поискового робота.
* **Команды:**
```bash
telnet example.com 80
```
```http
HEAD / HTTP/1.1
Host: example.com
User-Agent: MyCustomBot/1.0
```
* **Объяснение:** Это отличный способ показать, что вся информация для сервера передаётся в открытую. Студенты увидят, что ответ на `HEAD` не содержит тела, а изменение `User-Agent` демонстрирует, как легко подделать любой HTTP-клиент.
#### **3. Исследование кодов ответа**
* **Задача:** Студенты должны намеренно вызвать разные коды ошибок, чтобы эмпирически изучить их значение.
* **Команды:**
```bash
telnet example.com 80
```
```http
GET /non-existent-page-that-404 HTTP/1.1
Host: example.com
```
* **Объяснение:** В ответ на запрос несуществующей страницы, сервер вернёт ошибку `404 Not Found`. Если студенты попробуют отправить некорректный запрос, например: `GIBBERISH / HTTP/1.1`, то сервер ответит `400 Bad Request`. Это закрепляет понимание семантики статус-кодов.
#### **4. Изучение альтернативных протоколов: работа с FTP**
* **Задача:** Подключиться к публичному FTP-серверу и вручную навигироваться по его файловой системе. Это упражнение может занять 10-15 минут.
* **Команды:**
```bash
telnet ftp.gnu.org 21
```
```text
USER anonymous
PASS guest@
LIST
CWD /gnu
PWD
QUIT
```
* **Объяснение:** FTP (`File Transfer Protocol`) — ещё один классический протокол с текстовыми командами. Это упражнение показывает главную особенность FTP: он использует два TCP-соединения — порт 21 для команд и порт 20 для данных. Студенты воочию увидят, как работают команды `USER`, `PASS`, `LIST` (список файлов) и `CWD` (смена директории).
### B. 💌 Электронная почта на ладони (SMTP и POP3)
Эти два упражнения служат «мостиком» между протоколами и занимают порядка 20–25 минут.
#### **5. Ручная отправка письма (SMTP)**
* **Задача:** Вручную, шаг за шагом, отправить настоящее электронное письмо. Для этого лучше использовать тестовый SMTP-сервер, например, `sandbox.smtp.mailtrap.io`, который бесплатно предоставляет тестовое окружение.
* **Команды:**
```bash
telnet sandbox.smtp.mailtrap.io 25
```
```text
EHLO myclient.local
MAIL FROM:<sender@example.com>
RCPT TO:<recipient@example.com>
DATA
Subject: Telnet is awesome!
Hello from the depths of the OSI model!
.
QUIT
```
* **Объяснение:** Это, пожалуй, самое яркое упражнение. Студенты не просто читают про протокол `SMTP` (`Simple Mail Transfer Protocol`), а сами выступают в роли почтового клиента. Особый акцент стоит сделать на команде `DATA` и точке в отдельной строке — это маркер конца письма.
#### **6. Забор почты из ящика (POP3)**
* **Задача:** «Забрать» только что отправленное письмо с сервера. Для этого потребуется любой публичный POP3-сервер или можно использовать тот же Mailtrap.
* **Команды:**
```bash
telnet pop3.example.com 110
```
```text
USER your_username
PASS your_password
STAT
LIST
RETR 1
DELE 1
QUIT
```
* **Объяснение:** POP3 (`Post Office Protocol`) — это «протокол почтового отделения». Команда `RETR 1` (retrieve) скачивает первое письмо, а `DELE 1` помечает его на удаление. Это идеально демонстрирует стандартную модель работы POP3, где письма забираются с сервера на локальный компьютер.
#### 💡 **Межпротокольные связи**
Завершая этот блок, самое время подчеркнуть один важный момент, который великолепно демонстрирует красоту сетевого взаимодействия: чтобы получить письмо на одном компьютере, мы используем `SMTP` (для отправки) и `POP3`/`IMAP` (для получения) — два совершенно разных протокола прикладного уровня. Они работают независимо друг от друга, и каждый решает свою задачу, опираясь на один и тот же транспортный протокол `TCP`. Это нагляднейший пример того, как уровни модели OSI (в данном случае прикладной) взаимодействуют и разделяют ответственность.
### C. 🚀 Автоматизация и Вызов для Продвинутых
Это упражнение повышенной сложности на 15–20 минут для самых сильных студентов.
#### **7. Автоматизация с Netcat и сравнение с HTTPS**
* **Задача:** С помощью скрипта написать простейший веб-сервер на `netcat`, а затем сравнить трафик `HTTP` и `HTTPS` (порт 443) в `Wireshark`.
* **Пример скрипта сервера (server.sh):**
```bash
#!/bin/bash
while true; do
echo -e "HTTP/1.1 200 OK\n\n Hello, you reached my custom server!" | nc -l -p 8080 -q 1
done
```
Надеюсь, этот набор инструментов и идей поможет сделать вашу лекцию по-настоящему увлекательной и запоминающейся. Если захотите обсудить детали или адаптировать упражнения под конкретную аудиторию, я всегда рядом.
+244
View File
@@ -0,0 +1,244 @@
# Лекция: Прямой и обратный прокси. Балансировка нагрузки
## Прямой прокси
Представьте, что вы планируете проверить своё здоровье в многопрофильном медицинском центре, который регулярно посещаете. Но по какой‑то причине вы не желаете напрямую взаимодействовать с персоналом медучреждения. У вас есть личный помощник, который от вашего имени решает подобного рода задачи. По этой же причине медицинский персонал никогда не взаимодействует с вами напрямую, только с вашим помощником. В этом сценарии вас можно ассоциировать с ноутбуком, через который ищет информацию в интернете, а ваш личный помощник — это прокси‑сервер, который действует как посредник между вашей частной сетью, к которой подключён ноутбук, и общедоступным интернетом, куда отправляются ваши запросы. Прокси‑сервер защищает ноутбук, фильтруя трафик и блокируя вредоносные веб‑сайты и скрипты, прежде чем ответ будет перенаправлен обратно.
Представим другой сценарий. В вашей компании работает много сотрудников и все они ходят в интернет. К примеру, один сотрудник из отдела маркетинга посещает какой‑то сомнительный веб‑ресурс, возможно вредоносный, и нажимает на ссылку, чтобы загрузить новый инструмент для презентаций. С этого сайта злоумышленники в качестве ответа отправляют на его компьютер вместе с загружаемым дистрибутивом ещё и вирус. Когда вредоносный контент проникнет во внутреннюю сеть через компьютер этого сотрудника, он может нанести реальный вред всей компании.
Поэтому для защиты внутренней сети вы можете настроить весь интернет‑трафик всех компьютеров сотрудников так, что он будет проходить через прокси‑сервер, который станет «привратником» внутренней сети вашей организации. Вы можете внести в «чёрный список» любые веб‑сайты, которые должны быть недоступными для посещения сотрудниками компании. Он действует как щит между вашей частной сетью и общедоступным интернетом. А также он может регистрировать пользовательскую активность, чтобы показать, какие сайты посещают сотрудники.
Прокси‑сервер имеет ещё одну важную функцию, которая заключается в кешировании ответов. Например, сотрудник компании открыл какое‑то видео на сайте и решил его посмотреть, тогда прокси сохранит его локально. И если другие сотрудники тоже захотят посмотреть это же видео, прокси отдаст кешированную копию вместо того, чтобы снова скачивать её. Таким образом он сэкономит пропускную способность и уменьшит лишний трафик, поступающий через интернет.
Такой вид прокси называется **прямым прокси‑сервером (forward proxy)**.
## Обратный прокси
Вернёмся к нашей аналогии с многопрофильным медицинским центром. Ваш личный помощник записал вас на проверку здоровья и вы приходите в клинику в назначенное время. Теперь вместо того, чтобы самостоятельно в огромном здании искать нужный кабинет, вы подходите к стойке регистрации. Администратор вас регистрирует, затем приглашает следовать за ним и приводит в нужный кабинет. В этой ситуации администратор — это тоже прокси, но на этот раз на принимающей запрос стороне. Сидит он в клинике в окружении всевозможных кабинетов (в нашем случае серверов) и управляет пациентами (входящими запросами), распределяя их по нужным врачам, этажам и кабинетам, проверяя загруженность и имея обзор всего внутреннего потока.
Этот прокси, находящийся на серверной стороне и обрабатывающий входящие клиентские запросы, называется **обратным прокси‑сервером (реверсивным, reverse proxy)**. А равномерное распределение пациентов в клинике — это балансировка нагрузки, которая может быть одной из ключевых функций обратного прокси‑сервера.
Обратные прокси решают большинство задач прямых прокси. Например, они действуют как щит. К примеру, когда у вас стоят сотни серверов и все они имеют доступ к конфиденциальным данным или коду, очень опасно предоставлять им прямой доступ в интернет. Поэтому вы просто помещаете один или несколько прокси‑серверов в качестве точек входа и настраиваете для них все меры безопасности. Обратные прокси будут сканировать запросы от внешних клиентов, шифровать трафик, проверять на наличие основных угроз или любых попыток взлома ваших систем, кешировать ответы и вести журнал событий.
## Балансировщик нагрузки
Балансировка нагрузки — это лишь одна из множества функций обратного прокси‑сервера. Но многие из вас могут просить: «А что насчёт облачного балансировщика? Зачем нам нужны обратные прокси, когда у нас есть облачный балансировщик, является ли он заменой обратному прокси?» На практике в компаниях с обширными внутренними сетями лучше использовать оба решения. Облачный балансировщик нагрузки находится вне вашего контура и играет роль входной точки в вашу частную сеть, в то время как обратные прокси‑серверы будут маршрутизировать трафик внутри вашей сети. А балансировщик будет распределять нагрузку на обратные прокси‑серверы. Это улучшит защиту и масштабируемость вашей инфраструктуры.
Вы, возможно, спросите: «А зачем мне дважды балансировать нагрузку на разных уровнях? Зачем мне нужно вешать это на внутренний прокси, если у меня уже есть балансировщик снаружи?» Обратный прокси‑сервер выполняет более «мелкодисперсную», так сказать, балансировку нагрузки на **прикладном (седьмом) уровне** модели OSI, которая позволит реализовать гораздо более интеллектуальную маршрутизацию к веб‑серверам. В то время как облачный балансировщик нагрузки распределяет трафик на основе более простых алгоритмов, чаще всего на **транспортном (четвёртом) уровне**.
На обратном прокси‑сервере вы можете настроить более сложную логику маршрутизации на основе файлов cookie, URL, заголовков запроса. Например, чтобы все запросы от одного и того же пользователя всегда приходили на один и тот же веб‑сервер, обратный прокси будет проверять все связанные данные сеансов, cookie‑файлы и пересылать клиентские запросы на соответствующие серверы. Обратный прокси‑сервер также может обрабатывать прекращение SSL и TLS, и вы можете проверять зашифрованный трафик, чтобы принимать более обоснованные решения по балансировке нагрузки. Это особенно важно при микросервисной архитектуре с десятками и сотнями сервисов. В нашем сценарии медицинского центра это было бы эквивалентно тому, как если бы администратор, например, знал некоторых постоянных пациентов и выбирал для них наиболее удобную комбинацию процедур, или они могли сами выбирать эту последовательность, или администратор предложил бы им ещё «закрытые» акции с выгодными ценами на услуги, и т. д.
Описанную схему целесообразно использовать в кластере Kubernetes с микросервисами. Там Ingress‑контроллер, который по сути является обратным прокси‑сервером для Kubernetes, обеспечивает внутреннюю маршрутизацию и безопасность. А облачный балансировщик выступает в качестве первой линии защиты, управляя внешним трафиком и частично фильтруя его, прежде чем он попадёт в кластер.
---
# Дополнение: технические аспекты и сравнение прокси
## Различия между прямым и обратным прокси
| Характеристика | Прямой прокси (Forward Proxy) | Обратный прокси (Reverse Proxy) |
|----------------|--------------------------------|----------------------------------|
| **Сторона расположения** | На стороне клиента (внутренняя сеть) | На стороне сервера (в DMZ или периметре) |
| **Кто инициирует запросы** | Клиенты (например, компьютеры сотрудников) | Внешние клиенты из интернета |
| **Основная цель** | Фильтрация исходящего трафика, анонимизация, кеширование контента | Защита внутренних серверов, балансировка нагрузки, SSL-терминация |
| **Прозрачность для клиента** | Клиент часто знает о существовании прокси (настраивает браузер или систему) | Клиент обычно не знает о прокси; он обращается как к обычному серверу |
| **Примеры ПО** | Squid, 3proxy, WinGate | Nginx, HAProxy, Apache httpd, Traefik, NPM |
## Дополнительные возможности прокси-серверов
- **Аутентификация и авторизация**: Прямой прокси может требовать логин/пароль перед доступом в интернет. Обратный прокси может проверять JWT-токены или сертификаты клиентов.
- **Логирование и аудит**: Оба типа прокси сохраняют детальные логи запросов (URL, время, IP-адрес, размер ответа), что необходимо для расследования инцидентов.
- **Ограничение скорости (rate limiting)**: Защита от DDoS-атак и злоупотреблений.
- **Транскодирование и модификация контента**: Прокси может сжимать изображения, переписывать HTML или добавлять заголовки безопасности (HSTS, CSP).
---
# Практическая работа: Настройка Nginx Proxy Manager (NPM) в Docker Desktop
## Цель работы
Настроить обратный прокси-сервер на базе Nginx Proxy Manager (NPM) в среде Docker Desktop. Создать прокси для локального веб-приложения, настроить автоматическое получение SSL-сертификата Let's Encrypt и убедиться в работе балансировки нагрузки (на простом примере).
## Необходимое программное обеспечение
- **Docker Desktop** (Windows/macOS/Linux) среда для запуска контейнеров.
- **Любой веб-браузер** (для проверки).
- **Два простых веб-сервера** для демонстрации балансировки – можно использовать стандартные образы `httpd` или `nginx` с разными index.html.
## Шаг 1. Установка Docker Desktop
1. Скачайте Docker Desktop с официального сайта: [https://www.docker.com/products/docker-desktop/](https://www.docker.com/products/docker-desktop/).
2. Установите, следуя инструкциям (на Windows потребуется включить WSL2 или Hyper-V).
3. После установки запустите Docker Desktop и убедитесь, что в терминале команда `docker --version` выполняется успешно.
## Шаг 2. Подготовка тестовых веб-серверов (для балансировки)
Создадим два контейнера, которые будут имитировать бэкенд-серверы. Запустите в терминале:
```bash
# Сервер 1 (на порту 8081)
docker run -d --name web1 -p 8081:80 nginx:alpine
docker exec web1 sh -c 'echo "Hello from Server 1" > /usr/share/nginx/html/index.html'
# Сервер 2 (на порту 8082)
docker run -d --name web2 -p 8082:80 nginx:alpine
docker exec web2 sh -c 'echo "Hello from Server 2" > /usr/share/nginx/html/index.html'
```
Проверьте, что каждый сервер отвечает: откройте в браузере `http://localhost:8081` и `http://localhost:8082`.
## Шаг 3. Установка Nginx Proxy Manager (NPM) через Docker Compose
Создайте директорию для проекта, например `npm-demo`, и внутри создайте файл `docker-compose.yml`:
```yaml
version: '3.8'
services:
npm:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80' # HTTP для прокси и получения сертификатов
- '443:443' # HTTPS для прокси
- '81:81' # Веб-интерфейс управления NPM
environment:
DB_SQLITE_FILE: "/data/database.sqlite"
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
```
Запустите контейнер:
```bash
docker-compose up -d
```
Дождитесь загрузки образа и запуска контейнера.
## Шаг 4. Первоначальная настройка NPM
1. Откройте браузер и перейдите по адресу: `http://localhost:81`.
2. Вход по умолчанию:
- **Email**: `admin@example.com`
- **Password**: `changeme`
3. Система сразу попросит сменить пароль и указать свои email/имя пользователя. Сделайте это.
4. Вы попадёте в панель управления NPM.
## Шаг 5. Настройка обратного прокси для одного сервера (прямой прокси-эффект для исходящих?)
> Примечание: NPM – это прежде всего обратный прокси. Для прямого прокси обычно используют Squid. Но в данной практике мы сосредоточимся на reverse proxy, который является продолжением лекции.
Допустим, мы хотим, чтобы внешний запрос по адресу `http://localhost` (или домену, если вы используете реальный) направлялся на `http://web1:80` внутри сети Docker.
### 5.1. Добавление Proxy Host
В интерфейсе NPM:
- Перейдите в раздел **Proxy Hosts**.
- Нажмите **Add Proxy Host**.
- Заполните поля:
- **Domain Names**: `localhost` (или `test.local`, если настроите локальный DNS или файл hosts).
- **Forward Hostname / IP**: `web1` (имя контейнера, так как NPM и web1 в одной сети Docker по умолчанию – сеть `npm-demo_default`). Если web1 запущен на хосте, укажите `host.docker.internal` (Windows/Mac) или IP-адрес.
- **Forward Port**: `80`.
- Остальное оставьте по умолчанию. Нажмите **Save**.
Теперь при обращении к `http://localhost` (через порт 80) NPM перенаправит запрос на web1.
### 5.2. Настройка SSL (если есть реальный домен)
Если у вас есть домен, делегированный на IP вашего компьютера (например, `proxy-test.example.com`), можно получить бесплатный сертификат Let's Encrypt:
- В том же окне редактирования Proxy Host перейдите на вкладку **SSL**.
- Включите **Force SSL** (перенаправление HTTP → HTTPS).
- Выберите **Request a new SSL Certificate**.
- Укажите email, согласитесь с условиями.
- Нажмите **Save**. Сертификат будет получен автоматически.
Для локальной разработки (localhost) Let's Encrypt не выдаёт сертификаты, поэтому можно использовать самоподписанный или тестовый.
## Шаг 6. Настройка балансировки нагрузки (два сервера)
NPM не имеет встроенного round-robin балансировщика как HAProxy, но можно использовать upstream-блок через кастомную конфигурацию Nginx. Однако NPM позволяет задать **несколько backend-серверов** в поле Forward Hostname/IP с разделителями? Нет, стандартный интерфейс принимает только один адрес. Для полноценной балансировки лучше использовать конфигурацию Nginx напрямую. Тем не менее, в учебных целях можно настроить **два разных proxy host** на разные поддомены или пути.
Альтернативно, покажем балансировку через **custom location**:
1. В разделе **Proxy Hosts** выберите созданный хост `localhost`.
2. Перейдите на вкладку **Advanced**.
3. В поле "Custom Nginx Configuration" добавьте:
```nginx
upstream backend {
server web1:80;
server web2:80;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
```
**Важно**: Такая конфигурация переопределит настройки из интерфейса. Сохраните изменения. Теперь NPM будет распределять запросы между web1 и web2 по алгоритму round-robin (по умолчанию).
Проверьте: многократно обновляя страницу `http://localhost`, вы должны видеть чередование "Hello from Server 1" и "Hello from Server 2".
## Шаг 7. Настройка кеширования (демонстрация)
Nginx (и NPM) поддерживает кеширование ответов. Добавим простой кеш для статики.
В том же custom location (или в отдельном proxy host) добавьте:
```nginx
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
server {
...
location / {
proxy_cache my_cache;
proxy_cache_valid 200 302 60m;
proxy_cache_valid 404 1m;
proxy_pass http://backend;
}
}
```
Убедитесь, что директория для кеша существует в контейнере (смонтирован том). Для простоты можно опустить, так как цель – показать возможность.
## Шаг 8. Проверка логирования и фильтрации
1. В интерфейсе NPM перейдите в раздел **Access Lists**.
2. Создайте новый Access List, например `BlockBadIPs`. Добавьте правило **Deny** для IP `192.168.1.100` (фиктивный пример).
3. Привяжите этот список к вашему Proxy Host вкладка **Access List** -> выберите созданный список.
4. Проверьте: если запрос приходит с запрещённого IP, прокси вернёт 403.
Логи доступа и ошибок хранятся в контейнере NPM. Посмотреть их можно так:
```bash
docker logs npm-demo_npm_1
```
Или зайдите в файловую систему контейнера через `docker exec -it npm-demo_npm_1 sh` и посмотрите `/data/logs`.
## Шаг 9. Очистка (после практики)
```bash
docker stop web1 web2
docker rm web1 web2
# В папке с docker-compose.yml:
docker-compose down -v
```
## Результат выполнения практики
Студент должен предоставить:
- Скриншот работающего интерфейса NPM (порт 81) с добавленным Proxy Host.
- Скриншот успешного получения SSL-сертификата (если использовался домен) или подтверждение работы HTTP-прокси на `localhost`.
- Скриншот чередования ответов от двух серверов при балансировке (5-10 обновлений страницы).
- Вывод команды `docker logs` с записью о проксировании хотя бы одного запроса.