TL;DR
Не любите, когда статьи не переходят сразу к делу? Я тоже.
Поэтому, если вы спешите, вот ответ: да! Запуск кластера базы данных PostgreSQL в Kubernetes — это жизнеспособный, готовый к продакшену способ размещения нагрузок баз данных.
Но так было не всегда. Когда единственным доступным примитивом Kubernetes были StatefulSet, управление базами данных в Kubernetes было связано с трудностями. С развитием специализированных операторов Kubernetes, таких как CloudNativePG, реальные ограничения теперь заключаются в навыках и опыте инженеров, управляющих этими нагрузками.
При этом запуск PostgreSQL в Kubernetes не обязательно повысит вашу безопасность или решит проблемы отказоустойчивости. Однако он открывает значительный потенциал для автоматизации и расширяемости, которого иначе было бы гораздо труднее достичь.
Почему именно PostgreSQL?
Конечно, нагрузки баз данных не ограничиваются PostgreSQL. MySQL, MongoDB и другие технологии баз данных также предлагают зрелые операторы с полезными возможностями и интересными сценариями использования. Но в этом материале мы сосредоточимся на PostgreSQL по нескольким причинам.
Во-первых, это база данных, которую мы используем внутри Glasskube, и мы также помогаем нескольким клиентам управлять их продакшен-нагрузками PostgreSQL. К тому же PostgreSQL был признан «https://www.enterprisedb.com/blog/postgres-most-admired-database-in-stack-overflow-2023[самой уважаемой и желанной базой данных]» в опросе разработчиков Stack Overflow за 2023 год.
Вот некоторые из сильных сторон PostgreSQL
Долголетие: более 25 лет инноваций и разработки. PostgreSQL — стабильный и проверенный выбор для многих.
Открытый код и универсальность: как многоцелевая база данных, PostgreSQL подходит для широкого спектра нагрузок и сценариев использования.
Высокая доступность: поддерживает архитектуру primary-replica с одним primary и несколькими репликами только для чтения, максимизируя аптайм и доступность.
Продвинутый протокол репликации: такие возможности, как синхронная репликация (контроль на уровне транзакций) и каскадная репликация, обеспечивают согласованность данных и надёжную производительность чтения даже между кластерами Kubernetes.
Аварийное восстановление: непрерывное резервное копирование и восстановление до точки во времени (PITR) позволяют надёжно восстанавливаться из любого момента, обеспечивая высокую отказоустойчивость и операционную безопасность.
Сильное сообщество и популярность: PostgreSQL широко распространён и неизменно оценивается как одна из самых уважаемых баз данных, что делает его популярным выбором для многих команд и проектов.
PostgreSQL в Kubernetes — хорошая ли это идея?
Если бы вы пролежали в коме десятилетие и очнулись сразу после Kubernetes v1.14, вы бы удивились, обнаружив, что консенсус относительно баз данных в Kubernetes перевернулся. В Kubernetes v1.14 локальные Persistent Volume достигли общей доступности (GA), а паттерн operator/controller по-настоящему начал набирать обороты. Этот сдвиг вызвал переоценку того, место ли нагрузкам баз данных в Kubernetes. Но прежде чем разбираться, почему сейчас это может быть удачным решением, стоит понять, почему ещё недавно запуск баз данных в Kubernetes был, мягко говоря, сомнительным.
Изначально Deployment и StatefulSet были единственными примитивами Kubernetes для обработки нагрузок. От Deployment для баз данных быстро отказались, поскольку они непредсказуемо создают поды, назначают случайные сетевые идентификаторы и не могут гарантировать, что конкретная реплика останется primary. StatefulSet улучшили ситуацию за счёт индексации подов, делая масштабирование предсказуемым, назначая конкретные сетевые идентификаторы и давая возможность привязать каждую реплику к её собственному постоянному хранилищу. Это означает, что если реплика падает, новая может подключиться к тому же постоянному тому, что и её предшественница.
Однако, как выразился Viktor Farcic:
То, что StatefulSet — лучший выбор, чем Deployment, не означает, что это хороший выбор.
Для по-настоящему продакшен-нагрузок баз данных StatefulSet всё ещё не хватает критически важных возможностей баз данных, таких как:
-
Резервные копии
-
Автоматизированные failover
-
Продвижение реплик (replica promotion)
-
Наблюдаемость (observability)
И поскольку StatefulSet было недостаточно, многие решили, что Kubernetes не подходит для баз данных.
Так зачем вообще рассматривать запуск баз данных PostgreSQL в Kubernetes?
Потому что всё изменилось. StatefulSet больше не единственный инструмент в наборе. Сегодня Kubernetes широко понимается не как готовое решение «из коробки», а как высоко расширяемая платформа. Его настоящая сила — в расширяемости.
Вместо того чтобы полагаться исключительно на нативное для Kubernetes хранилище, вы можете расширить его возможности с помощью плагинов хранилища CSI. И, что самое важное, вместо StatefulSet у нас теперь есть специализированные операторы, спроектированные для управления сложными stateful-нагрузками. Эти операторы делают всё, что когда-то делали StatefulSet, но добавляют полный набор возможностей уровня базы данных, которых вы ожидаете в продакшене.
Chris Milsted из Akamai хорошо сформулировал это:
Поместив данные в Kubernetes, вы не меняете ни одну из своих проблем отказоустойчивости. Вам всё ещё приходится думать ровно о тех же проблемах, но делать это гораздо проще, и есть множество приятных автоматизаций и вещей, которые происходят либо со стороны Kubernetes, либо со стороны оператора CloudNativePG и которые сильно упрощают жизнь. Гораздо проще добиться автоматизации и заставить всё работать, не тратя на это месяцы.
Включая слой данных вашей архитектуры в кластер Kubernetes, вы получаете объединённые преимущества общих сетевых и вычислительных ресурсов наряду с нативными для Kubernetes возможностями — самовосстановлением, диверсификацией по регионам и зонам доступности и многим другим.
Gabriele Bartolini, VP of Cloud Native в EDB и уважаемая фигура в сообществе PostgreSQL, выступает за запуск PostgreSQL в Kubernetes ради следующих ключевых преимуществ:
Репликация на уровне приложения: используя нативную репликацию PostgreSQL для синхронизации данных внутри и между кластерами Kubernetes, а не полагаясь на репликацию на уровне хранилища. Этот подход, нативный для Kubernetes, идеален для поддержания устойчивости приложения и согласованности состояния.
Оптимизация зон доступности: используя зоны доступности Kubernetes, а не изолируя дата-центры в отдельные кластеры. Это обеспечивает автоматическую высокую доступность с нулевой потерей данных и очень низким Recovery Time Objective (RTO) в пределах одного региона — прямо «из коробки».
Какие есть альтернативные методы?
Запуск напрямую на виртуальной машине
Конечно, можно и так — вероятно, в те времена, когда единственной альтернативой был StatefulSet в Kubernetes, никто бы вас за это не осудил.
Использование managed-сервиса БД вне вашего кластера
Во многих случаях выбор между запуском PostgreSQL в Kubernetes и использованием полностью управляемого сервиса очень напоминает взвешивание компромиссов между SaaS и self-hosted-ПО в целом. Для многих, включая меня и нашу команду, расширяемость и настраиваемость, которые предлагает Kubernetes, в сочетании с относительной простотой использования оператора вроде CloudNativePG делают self-hosting очевидным выбором. Плюс обычно высокая стоимость управляемых сервисов только упрощает решение в пользу self-hosting в Kubernetes. Один комментарий в сабреддите /kubernetes хорошо это подметил.
Что нужно для запуска PostgreSQL в Kubernetes?
В основном есть три главных составляющих, необходимых для эффективного управления PostgreSQL в Kubernetes.
-
Экспертиза в Kubernetes: ваша команда или организация должна хорошо понимать Kubernetes, чтобы эффективно управлять окружением и устранять неполадки.
-
Экспертиза в PostgreSQL: прочное владение PostgreSQL необходимо, чтобы настраивать, оптимизировать и поддерживать базу данных в среде Kubernetes.
-
Надёжный оператор: используйте надёжный оператор для управления полным жизненным циклом кластеров PostgreSQL, обеспечивая высокую доступность и бесшовное масштабирование.
Если вы уже запускаете нагрузки приложений в Kubernetes, но ваш слой данных находится вне него, проконсультируйтесь с опытным специалистом, прежде чем пытаться сделать «lift and shift» ваших нагрузок баз данных в Kubernetes — этот процесс далеко не тривиален. Точно так же, если вы начинаете с нуля в новой среде Kubernetes, разумно получить руководство опытного специалиста, который поможет принять архитектурные решения, о которых вы не пожалеете позже.
Кстати об операторе: что такое CloudNativePG?
CloudNativePG — это оператор с открытым исходным кодом, предназначенный для управления кластерами баз данных PostgreSQL в Kubernetes. Он насыщен возможностями, которые делают его готовым к продакшену и хорошо подходящим для высокодоступных нагрузок PostgreSQL.
Некоторые из его ключевых возможностей:
-
Готовность к продакшену: создан для обработки продакшен-нагрузок.
-
Kubernetes-оператор: полностью интегрирован с Kubernetes API.
-
Автоматизированный failover: обеспечивает высокую доступность за счёт автоматического переключения на реплику при отказе primary-инстанса.
-
Полностью декларативный: делает возможным управление кластерами PostgreSQL с помощью декларативных конфигураций.
-
Открытый код: свободно доступен и поддерживается сообществом.
-
Самовосстановление: автоматически обнаруживает отказы инстансов и переразворачивает базы данных.
-
Управление кластером: выступает менеджером кластера PostgreSQL внутри Kubernetes.
-
Усиленная безопасность: поддерживает mTLS для защищённого взаимодействия.
-
Оптимизированное хранилище: управляет отдельными томами для WAL-файлов.
-
Резервное копирование и восстановление: имеет встроенные средства для резервного копирования и аварийного восстановления.
-
Rolling-обновления: минимизируют простой во время обновлений.
-
Расширенный контроллер Kubernetes: добавляет расширенную функциональность, специфичную для PostgreSQL.
-
Нативные экспортёры Prometheus: обеспечивают лёгкую интеграцию с инструментами мониторинга.
-
Прямое управление PVC: использует PersistentVolumeClaim (PVC) напрямую для привязки многих типов целевых хранилищ.
-
Репликация на уровне приложения: обрабатывает репликацию данных на уровне приложения для согласованности.
-
Плагин kubectl: предлагает удобное управление через Kubernetes CLI.
Какое хранилище использовать?
В Kubernetes есть два основных типа доступа к хранилищу:
Сетевое хранилище: обычно доступно через сетевые файловые системы (NFS), плагины Container Storage Interface (CSI) или аналогичные опции с сетевым подключением. Это распространённый вариант в Kubernetes, но он может создавать проблемы с пропускной способностью и задержками, особенно в разделяемых средах, где несколько приложений конкурируют за ресурсы I/O.
Локальное хранилище: начиная с Kubernetes v1.14, локальное хранилище может быть напрямую подключено к ноде, в том числе в bare-metal-конфигурациях. Локальное хранилище идеально для высоконагруженных по транзакциям или очень больших баз данных (VLDB). Оно обеспечивает архитектуру shared-nothing, давая более высокую и предсказуемую производительность, что особенно полезно для нагрузок, требующих быстрого и стабильного времени доступа.
Использование локального хранилища, подключённого к хосту, на котором работает база данных PostgreSQL, — в целом лучший и наиболее рекомендуемый способ для продакшен-нагрузок. CloudNativePG очень гибок и позволяет использовать различные типы хранилища, подключённые через PersistentVolumeClaim (PVC), как для активных нагрузок, так и для резервных копий.
Ответ на вопрос, вынесенный в заголовок этого материала, — уверенное «да». Быстрый рост нагрузок баз данных на Kubernetes во многом обязан работе таких сообществ, как Data on Kubernetes Community. Благодаря экспертам, вкладу open source и сообществам этот вопрос решается однозначно положительно.