О чем эта статья? Ознакомление с возможностями SaltStack по созданию конфигураций зависимых друг от друга сервисов; от сервисов, расположенных на других или всех других подчиненных системах и т. д. Проще говоря, рассмотрим, как каждая подчиненная система может получать данные от других подобных систем в момент создания и распространения своих конфигураций.
Это третья статья из серии о SaltStack, читайте первую Здесь , второй - здесь .
Задача: развернуть кластер какого-либо сервиса так, чтобы конфигурации узлов содержали ссылки на все остальные узлы этого кластера.
Самая тривиальная задача для автоматизации — сделать множество узлов с заранее описанной конфигурацией сервисов, разместить эти конфигурации и получить прибыль.
Подобные стандартные случаи описаны во многих руководствах, в том числе и в SaltStack, поэтому мы не будем на них останавливаться.
Все это нормально до тех пор, пока этим узлам не нужно знать о состоянии и параметрах других узлов, включенных в процесс автоматизации.
Рассмотрим самый простой вариант описанной задачи — записать в файл /etc/hosts на каждом узле адреса и имена всех остальных узлов кластера.
Как решить эту проблему с помощью SaltStack? Самое простое, что приходит в голову — записать имена и адреса всех узлов в файл столба и связать его со всеми состояниями всех узлов: столб/кластер-nodes.sls
столб/топ.cluster-nodes: node1: name: node1.domain.com ip: 10.0.0.1 node2: name: node2.domain.com ip: 10.0.0.2 node3: name: node3.domain.com ip: 10.0.0.3 .
nodeN: name: nodeN.domain.com ip: 10.0.0.N
sls base:
'*':
- cluster-nodes
Давайте создадим состояние для добавления этих данных в /etc/hosts. Для этого мы будем использовать соль.
states.host .
штаты/cluster-nodes.sls {% for node in salt['pillar.get']('cluster-nodes', []) %}
cluster-node-{{node['name']}}:
host.present:
- ip: {{node['ip']}}
- names:
- {{node['name']}}
- {{node['name'].
split('.
')[0]}}
{% endfor %}
После применения состояния мы получим на всех узлах что-то подобное: /etc/хосты : 127.0.0.1 localhost
10.0.0.1 node1.domain.com node1
10.0.0.2 node2.domain.com node2
10.0.0.3 node3.domain.com node3
.
10.0.0.N nodeN.domain.com nodeN
Казалось бы, цель достигнута — со всех хостов видны другие.
Такое решение хоть и не изящное, потому что.
вам придется вносить правки в файл Pillar при добавлении новых узлов в кластер, но оно имеет право на существование в тех случаях, когда известны имена и адреса всех узлов.
и исправлено.
Что делать, если каждый узел получает свой адрес, например, по DHCP? Или созданием узлов занимается какой-нибудь поставщик IaaS, например Amazon EC2, GoGrid или Google Grid? Заранее не задаются адреса и имена узлов, а за фиксированные адреса также придется доплачивать.
(Лирическое отступление — в ближайшее время напишу статью о том, как создать свою инфраструктуру в EC2 с помощью SaltStack) .
В принципе, после установки миньона на узел информацию о его имени и адресе можно получить с помощью соль .
Например, вы можете получить эти данные о миньоне следующим образом: #salt-call grains.item fqdn fqdn_ip4
local:
----------
fqdn:
ip-10-6-0-150.ec2.internal
fqdn_ip4:
- 10.6.0.150
Или в описании состояния: {% set host_name = salt['grains.get']('fqdn') %}
{% set host_ip = salt['grains.get']('fqdn_ip4') %}
Все бы ничего, но есть одно существенное Но : все это доступно мастеру и недоступно отдельным миньонам.
То есть в момент генерации конфигурации на каждом из миньонов не видны данные самого миньона, что-то от мастера и абсолютно ничего о других миньонах.
Вот тут и возникает вопрос — как получить данные от других миньонов при генерации конфигурации для конкретного миньона? Ответ прост: для этого можно использовать соляная шахта .
В документации написано не так много, но достаточно, чтобы понять общую цель этого сервиса.
Как он работает? Мастер кэширует определенный набор данных от каждого из миньонов через определенные промежутки времени и предоставляет доступ к этим кэшированным данным всем миньонам.
Как это реализовать? 1. Установить mine_functions — описание функций получения и кэширования отдельных данных от миньонов.
Их можно определить, используя прямое описание в /etc/salt/minion для каждого из миньонов или включив файл Pillar с описанием этих функций на мастере для каждого из миньонов.
2. Либо ждем некоторое время (mine_interval секунды - можно указать в конфигурации миньонов), либо принудительно обновляем вручную с помощью соль '*' mine.update 3. Используйте функцию mine.get для получения необходимых данных от мастера при настройке текущего миньона.
Давайте рассмотрим, как решить проблему с хостами, используя описанные шаги.
Так:
1. Создайте запись в файле Pillar и подключите ее ко всем миньонам: столб/minefuncs.sls mine_functions:
grains.item: [fqdn, fqdn_ip4]
столб/топ.
sls base:
'*':
- minefuncs
2. Ускоряем сбор данных с миньонов.
3. Создайте государство для /etc/хосты : {% for node, fqdn_data in salt['mine.get']('*', 'grains.item', expr_form='glob').
items() %} cluster-node-{{fqdn_data['fqdn']}}: host.present: - names: - {{fqdn_data['fqdn'].
split('.
')[0]}}
- {{fqdn_data['fqdn']}}
- ip: {{fqdn_data['fqdn_ip4'][0]}}
{% endfor %}
В результате мы получим автоматически сгенерированный файл хостов, содержащий имена и адреса всех миньонов.
Если есть необходимость изолировать определенный набор миньонов, к которым будет применено состояние (например, у одних нод в кластере одна роль, у других — другая, и вам нужно изолировать только ноды с определенными ролями), вы можете используйте следующие рекомендации: 1. Для всех миньонов определяем пользовательское зерно (это несложно и описано в стандартной документации), например: зернышки:роли:имя_узла и зерна:роли:data_node. 2. Сделайте образец в мой.
получить для указанных ролей.
Например вот так: {% for node, fqdn_data in salt['mine.get']('roles:data_node', 'grains.item', expr_form='grain').
items() %} cluster-node-{{fqdn_data['fqdn']}}: host.present: - names: - {{fqdn_data['fqdn'].
split('.
')[0]}} - {{fqdn_data['fqdn']}} - ip: {{fqdn_data['fqdn_ip4'][0]}} {% endfor %} {% for node, fqdn_data in salt['mine.get']('* and not G@roles:data_node', 'grains.item', expr_form='compound').
items() %} cluster-node-{{fqdn_data['fqdn']}}: host.present: - names: - {{fqdn_data['fqdn'].
split('.
')[0]}}
- {{fqdn_data['fqdn']}}
- ip: {{fqdn_data['fqdn_ip4'][0]}}
{% endfor %}
В этих случаях стоит обратить внимание на expr_form и описание выражения для образца.
Это, по сути, решение описанной выше проблемы — чтобы можно было получать данные конфигурации от миньонов.
Используя описанные приемы, также можно передавать различные данные между миньонами в процессе генерации их конфигураций.
Надеюсь, статья будет полезна всем, кто использует SaltStack в достаточно нетривиальных конфигурациях.
Спасибо за чтение.
Теги: #Salt #saltstack #jinja #pillar #python #salt-mine #python
-
Электрическое Освещение
19 Oct, 24 -
Несколько Ссылок Про Iphone
19 Oct, 24 -
Поколение Следующее
19 Oct, 24 -
Видеть Пароль В Поле Ввода Пароля — Плохо
19 Oct, 24