- PVSM.RU - https://www.pvsm.ru -
Kubernetes стал для нас той технологией, которая в полной мере позволяет соответствовать строгим требованиям к отказоустойчивости, масштабируемости и качественному обслуживанию проекта. Несмотря на то, что сегодня K8s больше распространен [1] в крупных организациях и проектах, мы научились применять его и в небольших приложениях. Снижение себестоимости обслуживания стало возможным для нас благодаря унификации и обобщению всех компонентов, которые встречаются практически у каждого клиента. Эта статья — взгляд на полученный опыт со стороны бизнес-потребностей и их технической реализации, которая позволяет нам предлагать клиентам качественное решение за разумные деньги.
Начну с общих слов о том, как мы вообще к этому пришли, а обзор технических деталей по предлагаемой инфраструктуре читайте ниже.
Около 10 официальных лет «Флант» занимается системным администрированием GNU/Linux и бесчисленного множества сопутствующих технологий и программного обеспечения. Все это время мы улучшали свои рабочие процессы, часто сравнивая компанию с заводом, который переходит от ручного труда (необходимости «вручную» заходить на сервер при возникновении множества однообразных проблем) к потоковому производству (типовым конфигурациям, централизованному управлению, автоматическому деплою и т.п.). Даже несмотря на то, что многие обслуживаемые нами проекты сильно отличаются (в стеке применяемых технологий, требованиях к производительности и масштабированию…), у них есть фундамент, который подлежит систематизации. Этот факт позволяет превратить качественное обслуживание в типовое, обеспечивая клиента дополнительными преимуществами за разумные деньги.
Взращивая внутри компании лучшие практики на основе опыта работы с разными проектами, обобщая и по возможности «программируя» их, мы распространяем эти результаты на другие имеющиеся инсталляции. Раньше ключевым инструментом для этого служила система управления конфигурациями (мы предпочитали Chef). Постепенно внедряя в инфраструктуру Docker-контейнеры, мы пошли на логичный шаг по интеграции их настройки с возможностями Chef (реализовали это в рамках своего инструмента dapp [2])…
Но с появлением Kubernetes многое изменилось. Теперь мы описываем конфигурации в Kubernetes и получаем (предлагаем клиентам) инфраструктуру, которая:
Такой подход к инфраструктуре — результат наших продолжительных поисков оптимального решения, бесчисленных проб и ошибок, по-настоящему многогранного опыта обслуживания ИТ-систем. Это наше текущее видение разумной «нормы» для проектов разных масштабов.
Частое ощущение, которое после этого возникает у владельцев бизнеса: «Ну, звучит классно, но это какой-то rocket science, и он не для нас, потому что слишком сложен и дорог». Однако наш опыт показывает, что этот «rocket science» идеально подходит даже для тех, кто думает, что ещё «не на том уровне»:
О том, что мы понимаем под небольшим проектом и какие у него потребности, написано в следующем абзаце, с которого и начинается рассказ об устройстве типовой инфраструктуры.
Рассматриваемая в статье архитектура уже реализована во множестве проектов различной направленности: это СМИ, интернет-магазины, онлайн-игры, социальные сети, блокчейн-платформы и т.п.
Что такое небольшой проект, на который она рассчитана? Критерии не являются очень строгими, но обозначают основные тенденции и требования:
Если очень кратко описать архитектуру в целом, то можно сказать, что это «отказоустойчивое и масштабируемое облако Docker-контейнеров, которое находится под управлением Kubernetes». И вот что в неё входит…
Здесь и далее я возьму в качестве примера типовой интернет-магазин. Представим себе, что есть 3 сервера, на которых развернут кластер Kubernetes. Kubernetes — это главная составляющая архитектуры, это компонент, который занимается оркестровкой Docker-контейнеров и их управлением. Он отвечает за надежную, отказоустойчивую и масштабируемую работу контейнеров, внутри которых работает приложение клиента. Т.е. по сути это облако из контейнеров, работающее на трех серверах. Если один из серверов, на которых работает облако, выходит из строя, то Kubernetes автоматически перекидывает упавшие контейнеры (работавшие на упавшем сервер) на оставшиеся два сервера — это происходит очень быстро, в течение нескольких секунд.
Наша цель — падение одного сервера или даже двух серверов в облаке должно быть незаметным событием. Это достигается за счет того, что каждый компонент как минимум однократно продублирован и внутри облака экземпляры одного компонента расположены на разных серверах. При этом резервный компонент готов мгновенно принять нагрузку на себя. Если приложение поддерживает, то возможен вариант, когда все экземпляры компонента работают одновременно, а не в режиме «главный-резерв». Также есть возможность по нажатию кнопки «отмасштабироваться» и получить еще один-два-три и более дополнительных экземпляров этого компонента.
Представим себе, что интернет-магазин написан на PHP и у него есть следующие компоненты*:
* В действительности же не так важно, интернет-магазин это или сайт СМИ, и даже сами компоненты могут быть совсем иными, но суть останется прежней.
Как вы уже могли догадаться, часть нашей работы состоит в том, чтобы упаковать приложение (в данном случае — интернет-магазин) в Docker-контейнеры, а затем запустить эти контейнеры в облаке Kubernetes. Помимо самого приложения (PHP-бэкенда) в облаке работают и остальные компоненты: memcached, RabbitMQ и т.п.
Примечание: Мы до сих пор не устанавливаем РСУБД в production внутрь облака Kubernetes по некоторым технологическим причинам. Однако начали делать первые такие инсталляции для маленьких проектов и приложений не в production (dev-контуры и т.п.).
Все проекты зачастую имеют примерно одинаковый стек компонентов, а различия скорее заключаются в языках программирования и базах данных. Kubernetes дал нам хорошую возможность реализовать типовую конфигурацию каждого из этих компонентов, которая подойдет любому проекту. При этом такой типовой компонент сам по себе отказоустойчив, легко масштабируется, а также ставится в любой кластер Kubernetes в течение 5 минут. Для примера рассмотрю каждый из компонентов отдельно.
СУБД выделены в отдельную сущность, так как они в большинстве случаев находятся за пределами Kubernetes и обычно представляют собой 2 или 3 сервера, которые работают в режиме master-slave (MySQL, PostgreSQL, ...) или master-master (Percona XtraDB), с автоматическим или ручным failover на случай аварийной ситуации.
Бэкенд представляет собой код приложения, упакованный в Docker-контейнер. В этом контейнере установлены необходимые приложению библиотеки и софт (например, PHP 7). Тот же самый контейнер используется для запуска консьюмеров и cron-задач. В Kubernetes мы запускаем несколько экземпляров бэкенда, один крон и несколько консьюмеров.
С memcached у нас исторически сложилось два варианта реализации, которые применяются в различных ситуациях:
Мы используем штатный кластер RabbitMQ из трех и более узлов с автоматическим failover’ом на уровне Kubernetes.
В основе этого компонента мы используем штатный кластер Redis Sentinel, имеющий некоторую обвязку, которая избавляет приложение от необходимости реализации протокола sentinel.
Аналогичным образом у нас в арсенале есть такие готовые и протестированные компоненты, как minio, sphinxsearch, elasticsearch и многие другие. Практически любой софт может быть установлен внутри Kubernetes — главное, подходить к этому процессу с умом.
Каждый проект имеет также следующие служебные компоненты Kubernetes:
Как правило, проекты, которые к нам приходят, изначально имеют проблемы с архитектурой — в первую очередь, с масштабированием из-за хранения файлов или промежуточных данных на диске, локального хранения сессий и многих других причин. Самая большая и сложная часть работы заключается в том, чтобы помочь разработчикам переделать приложение так, чтобы оно стало stateless.
Если совсем «на пальцах», то это значит, что каждый компонент приложения не хранит промежуточных данных, либо эти данные мало важны и их можно безболезненно потерять. Это нужно для того, чтобы можно было запустить несколько бэкендов и при внезапном отказе одного из них ничего бы не сломалось, никакие загруженные пользователями файлы бы не удалились и т.д.
Самые частые причины, которые мешают сделать приложение stateless, — это:
Ответ на возникающие опасения касательного такого stateless-будущего (да, действительно придётся потратить ресурсы разработчиков на изменения в приложении для этого) заключается в том, что оно всё равно неизбежно (для приложений, которым нужно масштабирование) и что приближаться к нему можно поэтапно.
Наконец, возникает логичный вопрос, как же происходит деплой кода приложения в такую инфраструктуру. Устроено это следующим образом:
В Kubernetes есть пространства имен (namespaces). Их можно представить себе как отдельные изолированные контуры или окружения, которые запускаются в одном кластере. То есть у нас появляется возможность сделать отдельный контур для staging, для master-ветки… или вообще на каждую ветку делать свой отдельный контур. Контур представляет собой полную копию production: там стоят все те же самые компоненты (MySQL, бэкенды, Redis, RabbitMQ и т.д.). Это достигается за счет того, что вся конфигурация инфраструктуры (конфигурация всех компонентов) описана в специальных YAML-файлах и лежит в репозитории, то есть мы получаем возможность быстро и полностью воссоздать production-среду в любом другом namespace.
* С примером нашего пайплайна в GitLab CI и техническими подробностями его реализации можно ознакомиться в этой статье [5].
Самая типовая инсталляция — это 3 сервера-гипервизора, имеющие примерно такую конфигурацию: E5-1650v4, 128G RAM, 2×500 ГБ SSD. Серверы объединены между собой локальной сетью. Ресурсы каждого сервера разделены с помощью виртуальных машин (Linux KVM + QEMU) на такие части:
Мы бэкапим все, что требуется в проекте: базы данных, upload-файлы и т.п. Никаких простоев при бэкапе не возникает (для СУБД данные снимаются со slave-сервера и т.п.). План бэкапа и его ежемесячного тестирования согласуется с клиентом — за это отвечает персональный менеджер проекта.
Это уже не всегда технические вопросы, но они важны для понимания полной картины:
Мы верим, что современные инфраструктурные решения категории cloud native могут работать во благо уже сейчас и для всех, а стоимость их применения не должна быть сопоставима с ценой космического корабля. Можно провести аналогию с мобильной связью: если раньше сотовая связь была доступна только избранным, то сегодня это обыденность и данность, а цена за связь невелика.
Пройдя путь от «ручного» администрирования «всего на Linux» до современной инфраструктуры на базе Kubernetes, мы стремимся к тому, чтобы сервис, который мы считаем разумной «нормой», был доступным для клиентов с любым бюджетом. Поэтому предлагаем выделенную команду специалистов для внедрения/обслуживания такой инфраструктуры по принципам DevOps (в тесном взаимодействии с разработчиками) с круглосуточной поддержкой и гарантиями по SLA в рамках бюджета на уровне зарплаты системного администратора/DevOps-инженера, нанятого в штат.
Многие технические аспекты вкратце рассмотренной здесь инфраструктуры (и связанных с ней лучших практик) подлежат значительной детализации, но это история для отдельных статей: и если некоторые из них уже опубликованы в нашем блоге, то запросы на новые — приветствуются в комментариях. Будем рады и вопросам не по технологиям, а процессам, используемым нами в работе и/или предлагаемым клиентам в рамках обслуживания.
Читайте также в нашем блоге:
Автор: jambo
Источник [12]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/analiz-i-proektirovanie-sistem/267840
Ссылки в тексте:
[1] больше распространен: https://habrahabr.ru/company/flant/blog/340270/
[2] dapp: https://habrahabr.ru/company/flant/blog/333682/
[3] Mcrouter: https://github.com/facebook/mcrouter
[4] этом анонсе: https://habrahabr.ru/company/flant/blog/341386/
[5] этой статье: https://habrahabr.ru/company/flant/blog/332712/
[6] Наш опыт с Kubernetes в небольших проектах: https://habrahabr.ru/company/flant/blog/331188/
[7] №1: 4200 подов и TessMaster у eBay: https://habrahabr.ru/company/flant/blog/334140/
[8] №2: Concur и SAP: https://habrahabr.ru/company/flant/blog/334770/
[9] №3: GitHub: https://habrahabr.ru/company/flant/blog/335814/
[10] №4: SoundCloud (авторы Prometheus): https://habrahabr.ru/company/flant/blog/339724/
[11] Зачем нужен Kubernetes и почему он больше, чем PaaS?: https://habrahabr.ru/company/flant/blog/327338/
[12] Источник: https://habrahabr.ru/post/341760/
Нажмите здесь для печати.