determination
Роль автоматизирует деплой RabbitMQ кластера в Kubernetes с поддержкой TLS, Topology Operator и настройкой ролевой модели для администрирования.
Перед запуском роли должны быть установлены:
- Python и pip
sudo apt update && sudo apt install -y python3-pip - Ansible Collections для работы с Kubernetes
ansible-galaxy collection install kubernetes.core community.kubernetes
- kubectl — для взаимодействия с Kubernetes
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" chmod +x kubectl sudo mv kubectl /usr/local/bin/ kubectl version --client
без этих зависимостей роль не сможет стартовать.
prerequisites/dependencies.yml— устанавливает и проверяет необходимые зависимостиprerequisites/k8s_checks.yml— проверяет состояние кластера Kubernetes
operator/namespace.yml— создаёт namespace для RabbitMQ Operatoroperator/deployment.yml— деплоит RabbitMQ Cluster Operator в namespace
tls/ca.yml— создаёт собственный CAtls/certificates.yml— генерирует TLS-сертификаты для узлов RabbitMQ на основе CAtls/secrets.yml— создаёт Kubernetes secrets с сертификатами
Нужен для гибкой настройки пользователей, политик и очередей RabbitMQ через CRD.
tp-operator/deploy-tp.yml— устанавливает Topology Operator
CRD, которые может добавлять/патчить TP-OP:
queues.rabbitmq.com— очередиexchanges.rabbitmq.com— обменникиbindings.rabbitmq.com— связи между очередями и обменникамиpermissions.rabbitmq.com— права пользователейtopicpermissions.rabbitmq.com— topic-based праваschemareplications.rabbitmq.com— репликация схемshovels.rabbitmq.com— шовелы (межкластерные перемещения сообщений)superstreams.rabbitmq.com— суперстримы (streaming очереди)vhosts.rabbitmq.com— виртуальные хостыoperatorpolicies.rabbitmq.com— политики оператора
В роли показана возможность добавления только пользователей и применения HA-политик для очередей.
cluster/main.yml— создаёт кластер RabbitMQ через CRDcluster/resources.yml— задаёт ресурсы (CPU/memory limits, storage)ha/affinity.yml— опционально настраивает pod anti-affinity (управляется переменными)
access/ingress.yml— настраивает ingress для доступа к RabbitMQ Management UIsecrets/secret-cr.yml— создаёт секрет для подключения приложений
secrets/user-secrets.yml— создаёт секреты с учётными данными RabbitMQ пользователейrabbitmq-users/RBAC.yml— формирует ролевую модель администрированияha/policies/policies.yml— задаёт HA-политику кластера
В роли использован оператор для деплоя, не Helm. Для администрирования добавлен Topology Operator, через него удобно управлять пользователями, очередями и политиками. Да и в целом в моём понимании удобно поддерживать кластер
!!! Обязательно создай Ansible Vault, где будут переопределенны переменные: !!!
rabbitmq_default_user: ---
rabbitmq_default_pass: ---
user_name: ---
user_password: ---по дефолту в файле /defaults/main.yml они будут такие:
rabbitmq_default_user: adminq
rabbitmq_default_pass: adminq
user_name: testme
user_password: testmeПеременная для CI/CD и внешних сервисов
rabbitmq_service_backend_credentials— имя Kubernetes Secret, который будут использовать сервисы для подключения к RabbitMQ и отправки сообщений в очереди.- Использует пользователя, заданного ранее через переменные, создаётся в неймспейсе, определённой переменной
rabbitmq_operator_namespace:
rabbitmq_service_backend_credentials: "credentionals-for-backend"- Оставил переменную, где при необходимости можно изменить права пользователя (дать больше прав/сократить), добавив или убрав теги.
user_tags:
- policymaker
- monitoringранее описывал какие у него есть CRD вот пример манифеста, добавления новой политики, оставил если надо вручную что то добавить/пропатчить. модешь использовать этот шаблон и менять абсолютно любой ресурс, не только политику как в примере (выше описывал какие есть ресурсы)
apiVersion: rabbitmq.com/v1beta1
kind: Policy
metadata:
name: ha-criticalq
namespace: rabbitmq-system
spec:
name: ha-criticalq
pattern: ".*_criticalq$" # все очереди, оканчивающиеся на _critical
applyTo: "queues"
definition:
ha-mode: all # зеркалить на все ноды
rabbitmqClusterReference:
connectionSecret:
name: {rabbitmq_namespace}-service-credentials!!!секрет создаёт на основе переменной!!!
rabbitmq_namespace
оставил пару перемен для гибкой настройки глобальной политики очередей
по дефолту они такие, меняй в зависимости от бизнес требований как хочешь:
policy_name: ha-critical
policy_pattern: ".*_critical$"
policy_definition:
ha-mode: allесть поддержка антиафинити (чтобы поды не ложились на одну ноду, будет печально если все поды на 1й ноде, и отказала VPS в облаке, кластер мёртв)
включает/выключает эта переменная:
rabbitmq_anti_affinity: falseподнял ingress-nginx
он использует rabbitmq service (который ранее поднимался) куда проксировать
вот переменные которые можешь гибко менять, в зависимости от бизнес требований
ingress_nodeport_http: 32080
ingress_nodeport_https: 32443
ingress_service_type: "NodePort" // LoadBalancer если в облаке, и надо назначить экстернал ip, но у себя тыкался только с NodePort
rabbitmq_ui_ingress_enabled: true
rabbitmq_ui_ingress_host: "192.168.49.2"
rabbitmq_ui_service_type: "ClusterIP"я лично поднимал в ВМ миникубе, тот в свою очередь (миникуб) запускается в своей ВМ некая матрёшка получается
я -> моя ВМ -> ВМ с миникубом
в ingress сделал NodePort, доступ с ВМ до ВМ с миникубом - открывалось
чтобы я с хоста попал до кластера, добавил просто socat в ВМ, которая проксирует на ВМ миникуба
как какому то бэкенду или другому сервису попать в кластер - описывал ранее, используй секрет для подключения, он ссылается на service с типо cluster ip
*rabbitmq_service_backend_credentials: "credentionals-for-backend"*
Пример плейбука:
---
- name: Deploy Production RabbitMQ Cluster
hosts: localhost
connection: local
gather_facts: false
vars_files:
- inventory.yml # понятно в целом что это
- secrets.yml # если используете vault, а я надеюсь используете
roles:
- AnsibleR-RabbitMQзапускаем так:
ansible-playbook -i inventory.yml deploy-rabbitmq.yml --ask-vault-pass
FREE
на свои предложения что именно хотим, как реализовывать, я получил ответ: *Общий ответ - ограничений нет, итоговое решение необходимо пояснить.*
конкретных функ. требований нет, поэтому постарался сделать гибкую систему (переопределение переменных почти везде), меняйте в зависимости от бизнес требований. если что то не хватает, кластер можно удобно поддерживать и добавлять что то новое (topology operator позволяет).
индемпотентность есть, если 10 раз запустить эту роль, отрабатывает и ошибки не выкидывает, спасибо атрибуту present в модуле kubernetes.core.k8s
что хотел бы ещё добавить:
бэкап очередей
писал баш скрипт и кронджобу по выкачиванию данных + деплой minio как s3, но не хватило времени довести до ума.
я подниимал реплику miniO, но отказоустойчивости там не было, просто один деплоймент, в идеале хотелось бы поднять кластерную хранилку, но уже не стал этим заниматься.
ну как будто если есть инфраструкрута для деплоя кластерного реббита, то должна быть и какая то хранилка уже существующая.
конечно мог оставить кронджобу и баш скрипт, и добавить поле для монтировки секрета подключения к какой то бд - но тут уже хотел бы узнать, а к какой бд мне подключаться, что у вас за инфра и как работать с этим секретом.
слишком много НО, поэтому отказался от идеи с бэкапированием в целом.
p.s. я забыл линтер написать и завести(