Chef CentOS v11: различия между версиями
Sirmax (обсуждение | вклад) (→рецепт) |
Sirmax (обсуждение | вклад) |
||
| (не показаны 24 промежуточные версии этого же участника) | |||
| Строка 1: | Строка 1: | ||
| + | [[Категория:Linux]] |
||
| + | [[Категория:Chef]] |
||
| + | [[Категория:Autodeploy]] |
||
| + | [[Категория:Ruby]] |
||
| + | |||
=Chef сервер под CentOS 6.3= |
=Chef сервер под CentOS 6.3= |
||
<B>Все очень призрачно...</B> |
<B>Все очень призрачно...</B> |
||
| Строка 12: | Строка 17: | ||
<PRE> |
<PRE> |
||
https://opscode-omnitruck-release.s3.amazonaws.com/el/6/x86_64/chef-server-11.0.4-1.el6.x86_64.rpm |
https://opscode-omnitruck-release.s3.amazonaws.com/el/6/x86_64/chef-server-11.0.4-1.el6.x86_64.rpm |
||
| + | https://opscode-omnitruck-release.s3.amazonaws.com/el/6/x86_64/chef-11.4.0-1.el6.x86_64.rpm |
||
</PRE> |
</PRE> |
||
Но вообще-то узнать последнюю версию можно тут: http://www.opscode.com/chef/install/ |
Но вообще-то узнать последнюю версию можно тут: http://www.opscode.com/chef/install/ |
||
| Строка 120: | Строка 126: | ||
==Базовое тестирование== |
==Базовое тестирование== |
||
| − | {{Root|<nowiki> |
+ | {{Root|<nowiki> |
| + | chef-server-ctl test |
||
| − | </PRE></nowiki>}} |
||
| + | </nowiki>}} |
||
Достаточно длительный процесс (по крайне мере на ограниченных ресурсах контейнера)<BR> |
Достаточно длительный процесс (по крайне мере на ограниченных ресурсах контейнера)<BR> |
||
| Строка 191: | Строка 198: | ||
==настройка knife== |
==настройка knife== |
||
Для работы с 10-м шефом использовался "нож", в 11 он тоже присутствует |
Для работы с 10-м шефом использовался "нож", в 11 он тоже присутствует |
||
| − | |||
Подкладываю в ~/.chef файлы ключей: |
Подкладываю в ~/.chef файлы ключей: |
||
| − | {{Root|<nowiki> |
+ | {{Root|<nowiki> |
| + | mkdir /root/.chef/ |
||
| + | cp /etc/chef-server/chef-validator.pem ~/.chef/ |
||
cp /etc/chef-server/admin.pem ~/.chef/</nowiki>}} |
cp /etc/chef-server/admin.pem ~/.chef/</nowiki>}} |
||
| Строка 558: | Строка 566: | ||
Задача - установить 3 ноды, на ноде 1 <B>СТРОГО ПОСЛЕ ЗАВЕРШЕНИЯ УСТАНОВКЕ НА ВСЕХ НОДАХ</B> сделать набор post-install шагов. |
Задача - установить 3 ноды, на ноде 1 <B>СТРОГО ПОСЛЕ ЗАВЕРШЕНИЯ УСТАНОВКЕ НА ВСЕХ НОДАХ</B> сделать набор post-install шагов. |
||
| − | ==Определить параметры кластера== |
+ | ===Определить параметры кластера=== |
Это живой пример, потому определяю параметры так как я это делал на живом кластеер |
Это живой пример, потому определяю параметры так как я это делал на живом кластеер |
||
| + | ===Рецепт=== |
||
/var/chef/cookbooks/demo/attributes/default.rb - файл с пре-определнными атрибутами. У нас всего один атрибут - ip address мастер-ноды |
/var/chef/cookbooks/demo/attributes/default.rb - файл с пре-определнными атрибутами. У нас всего один атрибут - ip address мастер-ноды |
||
| Строка 566: | Строка 575: | ||
set[:demo][:master_node] = "172.31.0.5" |
set[:demo][:master_node] = "172.31.0.5" |
||
</PRE> |
</PRE> |
||
| + | Рецепт приводим к такому виду: |
||
| + | <PRE> |
||
| + | puts "===="+node[:demo][:master_node].to_s+"===" |
||
| + | puts "===="+node[:ipaddress].to_s+"===" |
||
| + | |||
| + | |||
| + | if node[:demo][:master_node].to_s == node[:ipaddress].to_s |
||
| + | puts "Master detected" |
||
| + | |||
| + | package "ntp" do |
||
| + | action :install |
||
| + | provider Chef::Provider::Package::Yum |
||
| + | end |
||
| + | |||
| + | |||
| + | package "mc" do |
||
| + | action :install |
||
| + | provider Chef::Provider::Package::Yum |
||
| + | end |
||
| + | |||
| + | service "ntpd" do |
||
| + | supports :status => true, :restart => true, :reload => true |
||
| + | action [ :enable, :start ] |
||
| + | end |
||
| + | puts "=== Master node is installed ===" |
||
| + | node.set[:demo][:is_installed]=1 |
||
| + | node.save |
||
| + | else |
||
| + | |||
| + | package "httpd" do |
||
| + | action :install |
||
| + | provider Chef::Provider::Package::Yum |
||
| + | end |
||
| + | |||
| + | service "httpd" do |
||
| + | supports :status => true, :restart => true, :reload => true |
||
| + | action [ :enable, :start ] |
||
| + | end |
||
| + | puts "=== Slave node is installed ===" |
||
| + | node.set[:demo][:is_installed]=1 |
||
| + | node.save |
||
| + | end |
||
| + | |||
| + | </PRE> |
||
| + | Этот код следует читать примерно так |
||
| + | * Если нода - мастре - то установить один паке (ntp) и выставить переменную "установка сделана" |
||
| + | * если нода - слейв то совсем другое ПО но так же поднять флаг "установлено" |
||
| + | * выводить на экран что-то вроде дебага что бы было ясно по какой из веток двигается процесс |
||
| + | |||
| + | Проверяем: |
||
| + | ====нода 1 (мастрер)==== |
||
| + | <PRE> |
||
| + | chef-client |
||
| + | Starting Chef Client, version 11.4.0 |
||
| + | resolving cookbooks for run list: ["demo"] |
||
| + | Synchronizing Cookbooks: |
||
| + | - demo |
||
| + | Compiling Cookbooks... |
||
| + | ====172.31.0.5=== |
||
| + | ====172.31.0.5=== |
||
| + | Master detected |
||
| + | === Master node is installed === |
||
| + | Converging 3 resources |
||
| + | Recipe: demo::default |
||
| + | * package[ntp] action install (up to date) |
||
| + | * package[mc] action install (up to date) |
||
| + | * service[ntpd] action enable (up to date) |
||
| + | * service[ntpd] action start (up to date) |
||
| + | Chef Client finished, 0 resources updated |
||
| + | </PRE> |
||
| + | |||
| + | ====нода 2 (слейв)==== |
||
| + | Не забываем добавить ноде роль: |
||
| + | <PRE> |
||
| + | knife node run_list 172.31.0.3 add role[demo_role] |
||
| + | </PRE> |
||
| + | |||
| + | |||
| + | <PRE> |
||
| + | chef-client |
||
| + | Starting Chef Client, version 11.4.0 |
||
| + | resolving cookbooks for run list: ["demo"] |
||
| + | Synchronizing Cookbooks: |
||
| + | - demo |
||
| + | Compiling Cookbooks... |
||
| + | ====172.31.0.5=== |
||
| + | ====172.31.0.3=== |
||
| + | Slave node detected |
||
| + | === Slave node is installed === |
||
| + | Converging 2 resources |
||
| + | Recipe: demo::default |
||
| + | * package[httpd] action install |
||
| + | - install version 2.2.15-15.el6.centos.1 of package httpd |
||
| + | |||
| + | * service[httpd] action enable |
||
| + | - enable service service[httpd] |
||
| + | |||
| + | * service[httpd] action start |
||
| + | - start service service[httpd] |
||
| + | |||
| + | Chef Client finished, 3 resources updated |
||
| + | </PRE> |
||
| + | Как видим, поставился совсем другой набор софта! |
||
| + | <PRE> |
||
| + | ps -auxfw |
||
| + | USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND |
||
| + | <skipped> |
||
| + | root 2313 0.0 0.0 173524 3764 ? Ss 12:49 0:00 /usr/sbin/httpd |
||
| + | apache 2315 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd |
||
| + | apache 2316 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd |
||
| + | apache 2317 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd |
||
| + | apache 2318 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd |
||
| + | apache 2319 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd |
||
| + | apache 2320 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd |
||
| + | apache 2321 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd |
||
| + | apache 2322 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd |
||
| + | </PRE> |
||
| + | |||
| + | ===рабочий кусок кода для нашего примера=== |
||
| + | <PRE> |
||
| + | # Выставить флаг готовности |
||
| + | node.set[:demo][:post_install]=1 |
||
| + | node.save |
||
| + | |||
| + | puts "==nodes list==" |
||
| + | demo_nodes=search(:node, "(role:demo_role OR roles:demo_role)") |
||
| + | # |
||
| + | |||
| + | demo_nodes.each do |demo_node| |
||
| + | puts demo_node[:ipaddress].to_s+"___"+demo_node.to_s |
||
| + | |||
| + | # проверить есть ли у ноды атрибуты вообще на случай если на ней ни разу не запускался chef-client |
||
| + | if demo_node.attribute?('demo') |
||
| + | |||
| + | # если мастер: |
||
| + | if demo_node[:demo][:master_node].to_s == demo_node[:ipaddress].to_s |
||
| + | puts "is installed ( master) = "+demo_node[:demo][:is_installed].to_s |
||
| + | else |
||
| + | puts "is installed ( slave) = "+demo_node[:demo][:is_installed].to_s |
||
| + | end |
||
| + | puts "Check [:is_installed] variable:"+demo_node[:demo][:is_installed].to_s |
||
| + | if demo_node[:demo][:is_installed] != 1 |
||
| + | puts "node "+ demo_node[:ipaddress].to_s+" is not ready" |
||
| + | node.set[:demo][:post_install]=0 |
||
| + | node.save |
||
| + | end |
||
| + | else |
||
| + | # эта секция отработает если есть хотя бы одна нода которая на сервере указана как demo на самом деле не запускала клиента |
||
| + | puts "at least one node is not configured! "+demo_node[:ipaddress] |
||
| + | node.set[:demo][:post_install]=0 |
||
| + | node.save |
||
| + | end |
||
| + | end |
||
| + | |||
| + | if node[:demo][:post_install] == 1 |
||
| + | if node[:demo][:master_node].to_s == node[:ipaddress].to_s |
||
| + | puts "Do post-install for master" |
||
| + | else |
||
| + | puts "Do post-install for slave" |
||
| + | end |
||
| + | else |
||
| + | puts "not ready for post-install" |
||
| + | end |
||
| + | </PRE> |
||
| + | Логика работы такая |
||
| + | * Проверить есть ли demo_node.attribute?('demo'). его не будет если ноде прописана роль демо, но реально chef-client еще ни разу не запускался. |
||
| + | ** если атрибута нет - вывод однозначен, кластер не готов к Post-Install |
||
| + | ** если атрибут есть - дополнительные проверки |
||
| + | * для каждой ноды выполнить проверку demo_node[:demo][:is_installed] != 1. Если хотя бы одна нода не имеет атрибута is_installed==1 то установить атрибут post_install]=0 |
||
| + | |||
| + | В результате исполнения этого кода мы можем точно знать - на какой стадии установки у нас находится кластер и предпринимать действия на основе этого знанеия. |
||
Текущая версия на 16:28, 28 февраля 2013
Chef сервер под CentOS 6.3
Все очень призрачно...
За пару месяцев что я работаю с шефом произошли заметные изменения в процедуре установки. Точнее, новая процедура отличается от старой практически на 100%.
Я делаю установку внутри линукс-контейнера, потому я допускаю что есть отличия от установки на "нормальную" систему.
Скачать
Я брал здесь:
https://opscode-omnitruck-release.s3.amazonaws.com/el/6/x86_64/chef-server-11.0.4-1.el6.x86_64.rpm https://opscode-omnitruck-release.s3.amazonaws.com/el/6/x86_64/chef-11.4.0-1.el6.x86_64.rpm
Но вообще-то узнать последнюю версию можно тут: http://www.opscode.com/chef/install/
Мне не очень нравится идея комбайна - эта РПМка тянет внутри себя кучу всего, включая Postgress, RabbitMQ и т.д.
Управляется все через новый механизм initctl
Немного забегая вперед, вот мой вывод:
Конфигурация
Запускаю:
После завершения длительного процесса у меня запущен весь комплекс сервисов:
Базовое тестирование
Достаточно длительный процесс (по крайне мере на ограниченных ресурсах контейнера)
У меня возникли некоторые проблемы (пока я не выявил сказалось ли это на работоспособности сервера)
Search API endpoint
/search/environment
GET
when searching for a single environment by name
should have more than just the target of our environment search on the system
should return status code 200 and a single environment
POST
targeted toward many environments with body of {"possibly_nested"=>["default_attributes", "top", "middle", "bottom"], "the_name"=>["name"], "not_found"=>["foo", "bar", "baz", "totally_not_a_real_field"], "empty"=>[]}
should succeed, and return multiple environments (FAILED - 1)
/search/node
GET
when searching for a single node by name
should have more than just the target of our node search on the system
should return status code 200 and a single node
POST
Failures:
1) Search API endpoint /search/environment POST targeted toward many environments with body of {"possibly_nested"=>["default_attributes", "top", "middle", "bottom"], "the_name"=>["name"], "not_found"=>["foo", "bar", "baz", "totally_not_a_real_field"], "empty"=>[]} should succeed, and return multiple environments
Failure/Error: r.should look_like search_success_response
'total' should match '6', but we got '7' instead.
# ./lib/pedant/rspec/search_util.rb:99:in `block (2 levels) in performing_a_search'
# ./lib/pedant/rspec/search_util.rb:670:in `with_search_polling'
# ./lib/pedant/rspec/search_util.rb:86:in `block in performing_a_search'
Finished in 5 minutes 43.13 seconds
70 examples, 1 failure
Failed examples:
rspec ./lib/pedant/rspec/search_util.rb:85 # Search API endpoint /search/environment POST targeted toward many environments with body of {"possibly_nested"=>["default_attributes", "top", "middle", "bottom"], "the_name"=>["name"], "not_found"=>["foo", "bar", "baz", "totally_not_a_real_field"], "empty"=>[]} should succeed, and return multiple environments
Если я понимаю правильно - ответ содержит 7 результатов вместо ожидаемых 6 но в json ниже я не могу найти ни 6 ни 7 атрибутов. Тут есть неясность.
{
"possibly_nested"=>
[
"default_attributes",
"top",
"middle",
"bottom"
],
"the_name"=>
[
"name"
],
"not_found"=>
[
"foo",
"bar",
"baz",
"totally_not_a_real_field"
],
"empty"=>
[
]
}
настройка knife
Для работы с 10-м шефом использовался "нож", в 11 он тоже присутствует Подкладываю в ~/.chef файлы ключей:
Запускаем knife configure -i
Обратить внимание - у меня при указании localhost вместо https://172.31.0.2:443 не работал бутстрап
Нод пока нет, но все равно проверяю ...
Конфиг .chef/knife.rb выглядит где-то так:
log_level :info log_location STDOUT node_name 'root' client_key '/root/.chef/root.pem' validation_client_name 'chef-validator' validation_key '/root/.chef/chef-validator.pem' chef_server_url 'https://localhost:443' syntax_check_cache_path '/root/.chef/syntax_check_cache'
chef-server-ctl
Управлять сервером теперь тоже по новому. Вобщем, хелп понятный - особо расписывать нечего. chef-server]# chef-server-ctl status
run: bookshelf: (pid 1226) 9024s; run: log: (pid 1225) 9024s run: chef-expander: (pid 1162) 9030s; run: log: (pid 1161) 9030s run: chef-server-webui: (pid 1391) 9002s; run: log: (pid 1390) 9002s run: chef-solr: (pid 1136) 9031s; run: log: (pid 1135) 9031s run: erchef: (pid 1578) 8984s; run: log: (pid 1271) 9018s run: nginx: (pid 1558) 8986s; run: log: (pid 1557) 8986s run: postgresql: (pid 1036) 9042s; run: log: (pid 1035) 9042s run: rabbitmq: (pid 702) 9059s; run: log: (pid 701) 9059s
Настройка клиентов
Самый простой способ - это сделать chef bootstrap Звучит смешно но это так )
#knife bootstrap 172.31.0.5 --node-name 172.31.0.5 Bootstrapping Chef on 172.31.0.5 Failed to authenticate root - trying password auth
После чего на клиенте можно запускать
# chef-client Starting Chef Client, version 11.4.0 resolving cookbooks for run list: [] Synchronizing Cookbooks: Compiling Cookbooks... [2013-02-18T08:03:14-05:00] WARN: Node 172.31.0.5 has an empty run list. Converging 0 resources Chef Client finished, 0 resources updated
Важно
Везде используются FQDN потому без записей в в DNS или /etc/hosts не обойтись.
Например когда у меня hostname сервера резолвился в 127.0.0.1 то именно этот адрес передавался в запросах и клиенты пробовали получить с него данные. Ничего, конечно же, не работало. Лечить так:<BR> Было: <PRE> 127.0.0.1 localhost centos-chefserver 172.31.0.2 centos-chefserver
Нужно:
127.0.0.1 localhost 172.31.0.2 centos-chefserver
И потом
chef-server-ctl reconfigure
Поваренные книги и рецепты, роли и вообще конфигурация сервера
cookbook
Создать поваренную книгу:
#knife cookbook create demo ** Creating cookbook demo ** Creating README for cookbook: demo ** Creating CHANGELOG for cookbook: demo ** Creating metadata for cookbook: demo
ls -lsa /var/chef/cookbooks/demo/ total 52 4 drwxr-xr-x 10 root root 4096 Фев 18 07:58 . 4 drwxr-xr-x 4 root root 4096 Фев 18 08:05 .. 4 drwxr-xr-x 2 root root 4096 Фев 18 07:58 attributes 4 -rw-r--r-- 1 root root 406 Фев 18 07:58 CHANGELOG.md 4 drwxr-xr-x 2 root root 4096 Фев 18 07:58 definitions 4 drwxr-xr-x 3 root root 4096 Фев 18 07:58 files 4 drwxr-xr-x 2 root root 4096 Фев 18 07:58 libraries 4 -rw-r--r-- 1 root root 272 Фев 18 07:58 metadata.rb 4 drwxr-xr-x 2 root root 4096 Фев 18 07:58 providers 4 -rw-r--r-- 1 root root 1431 Фев 18 07:58 README.md 4 drwxr-xr-x 2 root root 4096 Фев 18 08:04 recipes 4 drwxr-xr-x 2 root root 4096 Фев 18 07:58 resources 4 drwxr-xr-x 3 root root 4096 Фев 18 07:58 templates
cat /var/chef/cookbooks/demo/recipes/default.rb
package "ntp" do
action :install
provider Chef::Provider::Package::Yum
end
package "mc" do
action :install
provider Chef::Provider::Package::Yum
end
service "ntpd" do
supports :status => true, :restart => true, :reload => true
action [ :enable, :start ]
end
# knife cookbook upload demo Uploading demo [0.1.0] Uploaded 1 cookbook.
role
EDITOR=mcedit knife role create demo_role
{
"name": "demo_role",
"description": "",
"json_class": "Chef::Role",
"default_attributes": {
},
"override_attributes": {
},
"chef_type": "role",
"run_list": [
],
"env_run_lists": {
}
}
Добавить наш кукбук:
{
"name": "demo_role",
"description": "",
"json_class": "Chef::Role",
"default_attributes": {
},
"override_attributes": {
},
"chef_type": "role",
"run_list": [
"recipe[demo]"
],
"env_run_lists": {
}
}
run_list
knife node run_list 172.31.0.5 add role[demo_role] 172.31.0.5: run_list: role[demo_role]
Если есть роль но нет рецептов, это не ошибка
chef-client Starting Chef Client, version 11.4.0 resolving cookbooks for run list: [] Synchronizing Cookbooks: Compiling Cookbooks... Converging 0 resources Chef Client finished, 0 resources updated
После добавления нашего рецепта к роли:
chef-client
Starting Chef Client, version 11.4.0
resolving cookbooks for run list: ["demo"]
Synchronizing Cookbooks:
- demo
Compiling Cookbooks...
Converging 3 resources
Recipe: demo::default
* package[ntp] action install
- install version 4.2.4p8-2.el6.centos of package ntp
* package[mc] action install (up to date)
* service[ntpd] action enable
- enable service service[ntpd]
* service[ntpd] action start
- start service service[ntpd]
Chef Client finished, 3 resources updated
Проверяем:
# ps -auxfw USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 116136 1628 ? Ss 07:49 0:00 /sbin/init root 8 0.0 0.0 52688 1676 ? Ss 07:49 0:00 login -- root root 209 0.0 0.0 11480 1776 console Ss+ 07:49 0:00 \_ -bash root 165 0.0 0.0 245088 1352 ? Sl 07:49 0:00 /sbin/rsyslogd -i /var/run/syslogd.pid -c 5 root 201 0.0 0.0 4108 588 tty1 Ss+ 07:49 0:00 /sbin/mingetty /dev/tty1 root 203 0.0 0.0 4108 584 tty2 Ss+ 07:49 0:00 /sbin/mingetty /dev/tty2 root 205 0.0 0.0 4108 584 tty3 Ss+ 07:49 0:00 /sbin/mingetty /dev/tty3 root 207 0.0 0.0 4108 588 tty4 Ss+ 07:49 0:00 /sbin/mingetty /dev/tty4 root 265 0.0 0.0 64120 1168 ? Ss 07:55 0:00 /usr/sbin/sshd root 875 0.0 0.0 91712 3908 ? Ss 08:22 0:00 \_ sshd: root@pts/0 root 877 0.0 0.0 108344 1896 pts/0 Ss 08:22 0:00 \_ -bash root 2102 0.0 0.0 110196 1064 pts/0 R+ 11:01 0:00 \_ ps -auxfw ntp 2099 0.0 0.0 30208 1612 ? Ss 09:15 0:00 ntpd -u ntp:ntp -p /var/run/ntpd.pid -g
Особенности - то чего нет в puppet
Поиск
knife search node "role:demo_role"
knife node show 172.31.0.5 -Fj
{
"name": "172.31.0.5",
"chef_environment": "_default",
"run_list": [
"role[demo_role]"
],
"normal": {
"tags": [
]
}
}
Переменные (например состояние ноды)
рецепт
приведем рецепт к такому виду:
package "ntp" do
action :install
provider Chef::Provider::Package::Yum
end
package "mc" do
action :install
provider Chef::Provider::Package::Yum
end
service "ntpd" do
supports :status => true, :restart => true, :reload => true
action [ :enable, :start ]
end
#puts node.to_s
node.set[:demo][:demo_variable]='text'
node.save
Запустим его:
chef-client Starting Chef Client, version 11.4.0 resolving cookbooks for run list: ["demo"] Synchronizing Cookbooks: - demo Compiling Cookbooks... Converging 3 resources Recipe: demo::default * package[ntp] action install (up to date) * package[mc] action install (up to date) * service[ntpd] action enable (up to date) * service[ntpd] action start (up to date) Chef Client finished, 0 resources updated
И теперь мы можем наблюдать переменную в св-вах ноды.
knife node show 172.31.0.5 -Fj
{
"name": "172.31.0.5",
"chef_environment": "_default",
"run_list": [
"role[demo_role]"
],
"normal": {
"tags": [
],
"demo": {
"demo_variable": "text"
}
}
}
Для чего это нужно? Например для вот таких конструкций:
puts node.to_s
#node.set[:demo][:demo_variable]='text'
#node.save
puts node[:demo][:demo_variable].to_s
if node[:demo][:demo_variable].to_s == "test"
Chef::Log.info("OK")
else
Chef::Log.info("node[:demo][:demo_variable] = "+node[:demo][:demo_variable].to_s)
end
"если перемення установлен действие А, если нет Б". Забавно?)
Боевой пример - "кластер"
Задача - установить 3 ноды, на ноде 1 СТРОГО ПОСЛЕ ЗАВЕРШЕНИЯ УСТАНОВКЕ НА ВСЕХ НОДАХ сделать набор post-install шагов.
Определить параметры кластера
Это живой пример, потому определяю параметры так как я это делал на живом кластеер
Рецепт
/var/chef/cookbooks/demo/attributes/default.rb - файл с пре-определнными атрибутами. У нас всего один атрибут - ip address мастер-ноды
set[:demo][:master_node] = "172.31.0.5"
Рецепт приводим к такому виду:
puts "===="+node[:demo][:master_node].to_s+"==="
puts "===="+node[:ipaddress].to_s+"==="
if node[:demo][:master_node].to_s == node[:ipaddress].to_s
puts "Master detected"
package "ntp" do
action :install
provider Chef::Provider::Package::Yum
end
package "mc" do
action :install
provider Chef::Provider::Package::Yum
end
service "ntpd" do
supports :status => true, :restart => true, :reload => true
action [ :enable, :start ]
end
puts "=== Master node is installed ==="
node.set[:demo][:is_installed]=1
node.save
else
package "httpd" do
action :install
provider Chef::Provider::Package::Yum
end
service "httpd" do
supports :status => true, :restart => true, :reload => true
action [ :enable, :start ]
end
puts "=== Slave node is installed ==="
node.set[:demo][:is_installed]=1
node.save
end
Этот код следует читать примерно так
- Если нода - мастре - то установить один паке (ntp) и выставить переменную "установка сделана"
- если нода - слейв то совсем другое ПО но так же поднять флаг "установлено"
- выводить на экран что-то вроде дебага что бы было ясно по какой из веток двигается процесс
Проверяем:
нода 1 (мастрер)
chef-client Starting Chef Client, version 11.4.0 resolving cookbooks for run list: ["demo"] Synchronizing Cookbooks: - demo Compiling Cookbooks... ====172.31.0.5=== ====172.31.0.5=== Master detected === Master node is installed === Converging 3 resources Recipe: demo::default * package[ntp] action install (up to date) * package[mc] action install (up to date) * service[ntpd] action enable (up to date) * service[ntpd] action start (up to date) Chef Client finished, 0 resources updated
нода 2 (слейв)
Не забываем добавить ноде роль:
knife node run_list 172.31.0.3 add role[demo_role]
chef-client
Starting Chef Client, version 11.4.0
resolving cookbooks for run list: ["demo"]
Synchronizing Cookbooks:
- demo
Compiling Cookbooks...
====172.31.0.5===
====172.31.0.3===
Slave node detected
=== Slave node is installed ===
Converging 2 resources
Recipe: demo::default
* package[httpd] action install
- install version 2.2.15-15.el6.centos.1 of package httpd
* service[httpd] action enable
- enable service service[httpd]
* service[httpd] action start
- start service service[httpd]
Chef Client finished, 3 resources updated
Как видим, поставился совсем другой набор софта!
ps -auxfw USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND <skipped> root 2313 0.0 0.0 173524 3764 ? Ss 12:49 0:00 /usr/sbin/httpd apache 2315 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd apache 2316 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd apache 2317 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd apache 2318 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd apache 2319 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd apache 2320 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd apache 2321 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd apache 2322 0.0 0.0 173524 2240 ? S 12:49 0:00 \_ /usr/sbin/httpd
рабочий кусок кода для нашего примера
# Выставить флаг готовности
node.set[:demo][:post_install]=1
node.save
puts "==nodes list=="
demo_nodes=search(:node, "(role:demo_role OR roles:demo_role)")
#
demo_nodes.each do |demo_node|
puts demo_node[:ipaddress].to_s+"___"+demo_node.to_s
# проверить есть ли у ноды атрибуты вообще на случай если на ней ни разу не запускался chef-client
if demo_node.attribute?('demo')
# если мастер:
if demo_node[:demo][:master_node].to_s == demo_node[:ipaddress].to_s
puts "is installed ( master) = "+demo_node[:demo][:is_installed].to_s
else
puts "is installed ( slave) = "+demo_node[:demo][:is_installed].to_s
end
puts "Check [:is_installed] variable:"+demo_node[:demo][:is_installed].to_s
if demo_node[:demo][:is_installed] != 1
puts "node "+ demo_node[:ipaddress].to_s+" is not ready"
node.set[:demo][:post_install]=0
node.save
end
else
# эта секция отработает если есть хотя бы одна нода которая на сервере указана как demo на самом деле не запускала клиента
puts "at least one node is not configured! "+demo_node[:ipaddress]
node.set[:demo][:post_install]=0
node.save
end
end
if node[:demo][:post_install] == 1
if node[:demo][:master_node].to_s == node[:ipaddress].to_s
puts "Do post-install for master"
else
puts "Do post-install for slave"
end
else
puts "not ready for post-install"
end
Логика работы такая
- Проверить есть ли demo_node.attribute?('demo'). его не будет если ноде прописана роль демо, но реально chef-client еще ни разу не запускался.
- если атрибута нет - вывод однозначен, кластер не готов к Post-Install
- если атрибут есть - дополнительные проверки
- для каждой ноды выполнить проверку demo_node[:demo][:is_installed] != 1. Если хотя бы одна нода не имеет атрибута is_installed==1 то установить атрибут post_install]=0
В результате исполнения этого кода мы можем точно знать - на какой стадии установки у нас находится кластер и предпринимать действия на основе этого знанеия.