41 KiB
Лекция: Облачные технологии, современные серверные архитектуры и 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 или CRI‑O), агент 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, а специальный оператор синхронизирует его с реальным кластером.