Когда-нибудь в твоей стране запретят IaC и ты вспомнишь про мои бэкапы…© Джейсон Стетхем Не так давно мы в компании столкнулись с маленькой проблемкой - RabbitMQ (далее просто кроль и тп) на дев кластере упал, мы его оживили, а за definitions.json для восстановления юзеров, очередей и тд. пришлось бегать к разработчику, который по чистой случайности эти файлики часто снимал. Это был первый звоночек. Вторым звоночком стал DR (Disaster Recovery) - сценарий/упражнение по экстренному поднятию нашего продукта в облаке в случае взрыва и уничтожения нашего физического дата центра. Тут надобность в бэкапах нашего кролика стала очевидной и мы занялись решением этой проблемы Кратко о том, какие способы управления конфигурацией (создание пользователей, очередей и тд) RabbitMQ имеют место быть: Руками, мануально: Не наш выбор, конечно же (если только редко и на тестовой среде) Из приложения: Наши некоторые приложения имеют права на создание и работу с очередями Ansible : Очень хороший вариант, есть возможность автоматизировать некоторые моменты, восстанавливать конфигурацию. IaC.  StatefulSet в k8s topology operator k8s : Больше Кубера богам Кубера Рассматривая наш случай, на тестовой среде у нас кролик находится в кластере k8s как StatefulSet. Для тестов достаточно -  поднимается, убивается быстро - все довольны.  Кролики же на стейджинге и проде установлены на машинах и конфигурируются Ansible, что позволяет отслеживать актуальные настройки в коде, быстро применять их простой командой и имеется возможность отката, ибо хранится ансибл в git репозитории. Возможности конфигурирования разобрали и, обрисовав конкретно наш случай, который вполне себе production ready, приступим к решению проблемы бэкапов. Начнем с хранилища. Наша железка конечно же не вариант - мы уже условились, что это задача к DR, следовательно, железка сгорела, запишите в бух учёт. Куда же класть json? В облако. Почему? Мы можем супер-мега-быстро поднять нужные для этого объекты в облаке с помощью старого доброго Terraform Облако тех же Google-давно проверенная на высоких нагрузках и распределенная система, вероятность сгорания в ней наших конфигов "крайне мала!" До облака можно наладить простой доступ для загрузки и выгрузки бэкапов (в нашем случае Cloud SDK и его официальные докер-образа например) Разобравшись с местом хранения настроек кролика  можем приступить к приготовлениям всего нужного окружения и инструментов под наш бэкап  Нам нужен бакет и доступ к нему (сервис-аккаунт). Terraform позволяет поднять такое в три файла (для красоты, можно впихивать и в один) и деплоить/убивать одной командой в терминале. Выбор инструмента очевиден, давайте без лишних слов всё готовить: Хранилка готова, но в нее же и доступ нужен нам. Идем дальше и создаем сервис аккаунт с нужными правами И переменная с проектом, чисто для красоты и возможного использования внутри ваших иных Terraform модулей и тп: Для проверки инициализируем стейт и запускаем plan, который выведет нам то, что собирается сделать на основе этого кода: Вывод консоли должен создавать три объекта: bucket, SA и IAM Member (Пример вывода есть в прикрепленном в конце репозитории). Если сходится - запускаем адскую машину IaC и деплоим объекты: Готово - вы очаровательны! Хранилище готово, доступ имеем, что дальше? Нужен исполнитель бэкапа, для которого мы всю эту красоту и поднимали. Какие требования к нему мы выдвигаем: Должен быть изолирован от окружения хоста, его зависимостей и тд , для снижения вероятности вмешивания в работу и подделку данных и тд.  Минималистичный и заточенный под ограниченное количество нужных нам действий Должен хранить историю своих итераций (бэкап будет происходить ежедневно) и быть под нашим мониторингом и алертами Решение должно быть универсальным и легко адаптируемым к разным средам и разным кластерам RabbitMQ М Список не так уж и огромен, но в то же время, довольно действенно сокращает нам количество вариантов. Человек знающий в этот момент начинает потихоньку понимать к чему я веду и тихо ненавидит очередного любителя известного всем инструмента. Кого же мы выберем на роль этого важного винтика системы, прикрывающего нас от потери настроек кроля?... Благими намерениями вымощена дорога в Kubernetes © Жак Фреско Почему же мы опять затаскиваем наши решения в K8s : Чтобы всех раздражать  Контейнеры/поды, которыми управляет K8s, изолированы Можно выбрать образ только с нужными инструментами и не нагружать их зависимостями нашу инфру CronJob в кубере оставляет трейсы в виде логов подов, что может помочь в дебаге возможных ошибок и ко всему этому - объекты кубернетес спокойно мониторятся и могут быть дополнены алертами, приходящими нам прямиком в Slack В моем случае наш продукт преимущественно в кластерах, включая CronJob’ы и не хочется усложнять систему чем то еще После того, как мы определились с нашим бэкапером, нужно понять, что ему потребуется для выполнения всех работ Нам нужен доступ в бакет , чтобы кидать туда бэкапы , и доступ к RabbitMQ: В случае доступа к бакету мы уже условились использовать SA, то есть в наш под нужно прокинуть token для логина через gcloud. Это мы сделаем через Volume и VolumeMounts секрета, в который из Vault прилетает этот самый токен  Для доступа в RabbitMQ мы не будем мудрить и создадим пользователей в наших кластерах с нужными для скачивания конфигурации правами.  Примечание: в примере использован наш экземпляр бэкапера, поэтому юзера два – для кролика внутренних сервисов и кролика клиентов С доступом разобрались (не забываем, конечно, что файрвол должен пускать кластер кубера на хосты кролика). Теперь нам нужны инструменты для бэкапа. Всё будет максимально просто – curl для получения definitions.json кроликов, gcloud для авторизации в GCP и gsutil для копирования бэкапа в наш бакет, где он будет лежать на случай DR или пришествия Ктулху. На глаза сразу попадается образ от Google – cloud-sdk. Но не спешите брать именно его! После запуска и пула я увидел страшную цифру - 3 ГБ! Это явно не похоже на утилиту для чисто бэкапа. Можно подумать и собрать образ самому, но для быстрого решения мы немного покопали и заметили тот же официальный образ, но на базе Alpine. Результат явно лучше - 900 МБ. Остановимся на этом, но при желание образ можно собрать самому.  Алгоритм кроны выглядит так: Устанавливаем set –e, чтобы ошибки роняли крону и не кидали в бакет старые файлы или некий мусор. Curl’ом достаем definitions.json с хостов и сохраняем в локальные файлы. Логинимся в проект с помощью gcloud.  Кидаем бэкап файлы в bucket с помощью gsutil. На этом моменте можем приступать уже к написанию самого yaml’ика, части которого я показывал выше: Энкод в base64 обусловлен тем, что хост кролика через curl принимает авторизацию только так. И этот пунктик был особенно болезненым, потому что секреты в кубере изначально также хранятся в base64 и вышла ситуация, когда хост кролика кодил одним образом, кубер другим, а я на локальной машине дебажил это третьим. Следите за руками!  Наш логин пароль прилетает из секрета кубера, который в закодированном виде выглядит вот так: Загружаясь в под он декодируется, получаем наши исходные логин пароль пользователя кролика: А теперь нам надо отправить его в кролик для авторизации в задикодированном виде, под base64. Вводим заветную команду и…. Что?!!! Это явно не похоже на оригинальный код из секрета и тот же токен авторизации из запроса загрузки. Может мы что-то не понимаем? Давайте раскодируем полученный код: Это точно не наш пароль. Что же делать? В нашем случае эта строчка всё починила, но отличие кодировок в отличие от параметров и тех же кавычек, которые также влияют на декодирование  и кодирование, может в начале запутать и сломать авторизацию P.S В обычном ручном энкодинге/декодинге это проблема чинится простыми кавычками, но в случае нашего бэкапера мы оперируем переменными окружения и секретами, так что имеем что имеем. Кроме этого нужно было иметь в виду то, что оперировать файлами надо в папке вроде /tmp/, иначе под падал с ошибкой из-за отсутствия прав на другие директории (security всё же). Деплоим нашу cronJob  в кластер и вуаля! – Mission complete, Boss ! Наши файлики лежат в бакете, имеют версии, и в случае падения кролей мы просто деплоим заново  их и импортим туда эти файлы (что при желании можно также делать автоматом). Кролики в безопасности, все счастливы. Не одним IaC едины, бэкапьте всё что можно, когда-нибудь это вам поможет, а коллеги будут смотреть на вас как на боженьку инфраструктуры. Надеюсь, если вы прочитали статью до конца, то она оказалась для вас полезна или как минимум интересна. Всем добра и автоматизации! P.S Мы используем Helm для деплоя в кубер, но шаблоны самописные, так что в статье используется raw yaml, сгенерированный helm template. P.P.S Моя первая статья на этом ресурсе и первая статья в принципе, буду рад любому адекватному фидбеку А вот ссылка на гит с исходниками и небольшим readme по разворачиванию  DevOps Engineer