Chef CentOS v11: различия между версиями

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску
 
(не показано 59 промежуточных версий этого же участника)
Строка 1: Строка 1:
  +
[[Категория:Linux]]
  +
[[Категория:Chef]]
  +
[[Категория:Autodeploy]]
  +
[[Категория:Ruby]]
  +
 
=Chef сервер под CentOS 6.3=
 
=Chef сервер под CentOS 6.3=
 
<B>Все очень призрачно...</B>
 
<B>Все очень призрачно...</B>
Строка 11: Строка 16:
 
Я брал здесь:
 
Я брал здесь:
 
<PRE>
 
<PRE>
rpm -Uvh 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/
Строка 19: Строка 25:
 
<BR>
 
<BR>
 
Немного забегая вперед, вот мой вывод:
 
Немного забегая вперед, вот мой вывод:
  +
{{Root|<nowiki>#initctl list
<PRE>
 
initctl list
 
 
rc stop/waiting
 
rc stop/waiting
 
lxc-sysinit stop/waiting
 
lxc-sysinit stop/waiting
Строка 41: Строка 46:
 
rcS-sulogin stop/waiting
 
rcS-sulogin stop/waiting
 
serial stop/waiting
 
serial stop/waiting
</PRE>
+
</nowiki>}}
 
 
 
   
 
==Конфигурация==
 
==Конфигурация==
   
 
Запускаю:
 
Запускаю:
  +
{{Root|<nowiki>#chef-server-ctl reconfigure
<PRE>
 
  +
</nowiki>}}
chef-server-ctl reconfigure
 
  +
</PRE>
 
  +
{{Note|"Зависание":
У меня на стадии запуска RabbitMQ произошло зависание. Я ре-стартовал контейнер и запустил заново конфигурацию - все прошло успешно. (Рестартовать контейнер это БЫСТРО и удобно - гарантировано убьются все процессы которые хотя бы в теории могут взаимодействовать с chef-server)
 
  +
У меня на стадии запуска RabbitMQ произошло зависание. Я ре-стартовал контейнер и запустил заново конфигурацию - все прошло успешно. (Рестартовать контейнер это БЫСТРО и удобно - гарантировано убьются все процессы которые хотя бы в теории могут взаимодействовать с chef-server)}}
   
 
После завершения длительного процесса у меня запущен весь комплекс сервисов:
 
После завершения длительного процесса у меня запущен весь комплекс сервисов:
  +
{{Root|<nowiki># ps -auxfw
<PRE>
 
  +
<skipped>
 
root 699 0.0 0.0 4136 444 ? Ss 13:47 0:00 runsvdir -P /opt/chef-server/service log: ....................................................................................................................................
 
root 699 0.0 0.0 4136 444 ? Ss 13:47 0:00 runsvdir -P /opt/chef-server/service log: ....................................................................................................................................
 
root 700 0.0 0.0 3984 248 ? Ss 13:47 0:00 \_ runsv rabbitmq
 
root 700 0.0 0.0 3984 248 ? Ss 13:47 0:00 \_ runsv rabbitmq
Строка 119: Строка 123:
 
496 1576 0.0 0.0 78244 1332 ? S 13:49 0:00 \_ nginx: cache manager process
 
496 1576 0.0 0.0 78244 1332 ? S 13:49 0:00 \_ nginx: cache manager process
 
496 719 0.0 0.0 10876 252 ? S 13:47 0:00 /opt/chef-server/embedded/lib/erlang/erts-5.9.2/bin/epmd -daemon
 
496 719 0.0 0.0 10876 252 ? S 13:47 0:00 /opt/chef-server/embedded/lib/erlang/erts-5.9.2/bin/epmd -daemon
  +
</nowiki>}}
   
</PRE>
 
 
 
 
 
 
==Базовое тестирование==
 
==Базовое тестирование==
  +
{{Root|<nowiki>
<PRE>
 
 
chef-server-ctl test
 
chef-server-ctl test
</PRE>
+
</nowiki>}}
  +
 
Достаточно длительный процесс (по крайне мере на ограниченных ресурсах контейнера)<BR>
 
Достаточно длительный процесс (по крайне мере на ограниченных ресурсах контейнера)<BR>
 
У меня возникли некоторые проблемы (пока я не выявил сказалось ли это на работоспособности сервера)
 
У меня возникли некоторые проблемы (пока я не выявил сказалось ли это на работоспособности сервера)
Строка 167: Строка 168:
 
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
 
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
 
</PRE>
 
</PRE>
Если я понимаю правильно - ответ содержит 7 результатов вместо ожидаемых 6
+
Если я понимаю правильно - ответ содержит 7 результатов вместо ожидаемых 6 но в json ниже я не могу найти ни 6 ни 7 атрибутов. Тут есть неясность.
   
 
<PRE>
 
<PRE>
Строка 196: Строка 197:
   
 
==настройка knife==
 
==настройка knife==
  +
Для работы с 10-м шефом использовался "нож", в 11 он тоже присутствует
  +
Подкладываю в ~/.chef файлы ключей:
   
  +
{{Root|<nowiki>
scp root@chef-server:/etc/chef-server/admin.pem .
 
  +
mkdir /root/.chef/
scp root@chef-server:/etc/chef-server/chef-validator.pem .
 
  +
cp /etc/chef-server/chef-validator.pem ~/.chef/
  +
cp /etc/chef-server/admin.pem ~/.chef/</nowiki>}}
   
  +
Запускаем <B>knife configure -i</B>
Use knife configure -i to create an initial ~/.chef/knife.rb and new administrative API user for yourself. Use the FQDN of your newly installed Chef Server, with HTTPS. The validation key needs to be copied over from the Chef Server from /etc/chef-server/chef-validator.pem to ~/.chef to use it for automatically bootstrapping nodes with knife bootstrap.
 
   
  +
{{Root|<nowiki>#knife configure -i
1
 
  +
Overwrite /root/.chef/knife.rb? (Y/N)
  +
I have no idea what to do with
  +
Just say Y or N, please.
  +
Overwrite /root/.chef/knife.rb? (Y/N) Y
  +
Please enter the chef server URL: [http://localhost:4000] https://172.31.0.2:443
  +
Please enter a name for the new user: [root]
  +
Please enter the existing admin name: [admin]
  +
Please enter the location of the existing admin's private key: [/etc/chef/admin.pem] ~/.chef/admin.pem
  +
Please enter the validation clientname: [chef-validator]
  +
Please enter the location of the validation key: [/etc/chef/validation.pem] ~/.chef/chef-validator.pem
  +
Please enter the path to a chef repository (or leave blank):
  +
Creating initial API user...
  +
Please enter a password for the new user:
  +
Created user[root]
  +
Configuration file written to /root/.chef/knife.rb</nowiki>}}
   
  +
Обратить внимание - у меня при указании localhost вместо https://172.31.0.2:443 не работал бутстрап
 
   
  +
Нод пока нет, но все равно проверяю ...
% knife configure -i
 
  +
{{Root|<nowiki>#knife node list</nowiki>}}
 
The .chef/knife.rb file should look something like this:
 
 
 
   
  +
Конфиг .chef/knife.rb выглядит где-то так:
  +
<PRE>
 
log_level :info
 
log_level :info
 
log_location STDOUT
 
log_location STDOUT
node_name 'jtimberman'
+
node_name 'root'
client_key '/home/jtimberman/.chef/jtimberman.pem'
+
client_key '/root/.chef/root.pem'
 
validation_client_name 'chef-validator'
 
validation_client_name 'chef-validator'
validation_key '/home/jtimberman/.chef/chef-validator.pem'
+
validation_key '/root/.chef/chef-validator.pem'
chef_server_url 'https://chef-server.example.com'
+
chef_server_url 'https://localhost:443'
syntax_check_cache_path '/home/jtimberman/.chef/syntax_check_cache'
+
syntax_check_cache_path '/root/.chef/syntax_check_cache'
  +
</PRE>
   
  +
{{Root|<nowiki>#knife client list
Your Chef Server is now ready to use. Test connectivity as your user with knife:
 
 
 
% knife client list
 
 
chef-validator
 
chef-validator
chef-webui
+
chef-webui</nowiki>}}
  +
% knife user list
 
  +
{{Root|<nowiki>#knife user list
 
admin
 
admin
  +
root</nowiki>}}
jtimberman
 
   
  +
==chef-server-ctl==
In previous versions of Open Source Chef Server, users were API clients. In Chef 11, users are separate entities on the Server.
 
  +
Управлять сервером теперь тоже по новому. Вобщем, хелп понятный - особо расписывать нечего. chef-server]# chef-server-ctl status
  +
  +
{{Root|#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
  +
Звучит смешно но это так )
  +
<PRE>
  +
#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
  +
</PRE>
  +
  +
После чего на клиенте можно запускать
  +
<PRE>
  +
# 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
  +
</PRE>
  +
==Важно==
  +
Везде используются FQDN потому без записей в в DNS или /etc/hosts не обойтись.
  +
<PRE>
  +
Например когда у меня hostname сервера резолвился в 127.0.0.1 то именно этот адрес передавался в запросах и клиенты пробовали получить с него данные.
  +
Ничего, конечно же, не работало.
  +
  +
Лечить так:<BR>
  +
Было:
  +
<PRE>
  +
127.0.0.1 localhost centos-chefserver
  +
172.31.0.2 centos-chefserver
  +
</PRE>
  +
Нужно:
  +
<PRE>
  +
127.0.0.1 localhost
  +
172.31.0.2 centos-chefserver
  +
</PRE>
  +
И потом
  +
<PRE>
  +
chef-server-ctl reconfigure
  +
</PRE>
  +
  +
=Поваренные книги и рецепты, роли и вообще конфигурация сервера=
  +
==cookbook==
  +
Создать поваренную книгу:
  +
<PRE>
  +
#knife cookbook create demo
  +
** Creating cookbook demo
  +
** Creating README for cookbook: demo
  +
** Creating CHANGELOG for cookbook: demo
  +
** Creating metadata for cookbook: demo
  +
</PRE>
  +
<PRE>
  +
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
  +
</PRE>
  +
  +
<PRE>
  +
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
  +
  +
  +
  +
</PRE>
  +
  +
<PRE>
  +
# knife cookbook upload demo
  +
Uploading demo [0.1.0]
  +
Uploaded 1 cookbook.
  +
</PRE>
  +
  +
==role==
  +
<PRE>
  +
EDITOR=mcedit knife role create demo_role
  +
</PRE>
  +
<PRE>
  +
{
  +
"name": "demo_role",
  +
"description": "",
  +
"json_class": "Chef::Role",
  +
"default_attributes": {
  +
},
  +
"override_attributes": {
  +
},
  +
"chef_type": "role",
  +
"run_list": [
  +
  +
],
  +
"env_run_lists": {
  +
}
  +
}
  +
</PRE>
  +
Добавить наш кукбук:
  +
<PRE>
  +
{
  +
"name": "demo_role",
  +
"description": "",
  +
"json_class": "Chef::Role",
  +
"default_attributes": {
  +
},
  +
"override_attributes": {
  +
},
  +
"chef_type": "role",
  +
"run_list": [
  +
"recipe[demo]"
  +
],
  +
"env_run_lists": {
  +
}
  +
}
  +
</PRE>
  +
  +
==run_list==
  +
<PRE>
  +
knife node run_list 172.31.0.5 add role[demo_role]
  +
172.31.0.5:
  +
run_list: role[demo_role]
  +
</PRE>
  +
  +
Если есть роль но нет рецептов, это не ошибка
  +
<PRE>
  +
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
  +
</PRE>
  +
  +
  +
После добавления нашего рецепта к роли:
  +
  +
<PRE>
  +
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
  +
</PRE>
  +
Проверяем:
  +
<PRE>
  +
# 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
  +
</PRE>
  +
  +
=Особенности - то чего нет в puppet=
  +
==Поиск==
  +
<PRE>
  +
knife search node "role:demo_role"
  +
</PRE>
  +
<PRE>
  +
knife node show 172.31.0.5 -Fj
  +
{
  +
"name": "172.31.0.5",
  +
"chef_environment": "_default",
  +
"run_list": [
  +
"role[demo_role]"
  +
],
  +
"normal": {
  +
"tags": [
  +
  +
]
  +
}
  +
}
  +
</PRE>
  +
  +
==Переменные (например состояние ноды)==
  +
===рецепт===
  +
приведем рецепт к такому виду:
  +
<PRE>
  +
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
  +
</PRE>
  +
  +
Запустим его:
  +
<PRE>
  +
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
  +
</PRE>
  +
И теперь мы можем наблюдать переменную в св-вах ноды.
  +
<PRE>
  +
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"
  +
}
  +
}
  +
}
  +
</PRE>
  +
  +
  +
  +
Для чего это нужно? Например для вот таких конструкций:
  +
<PRE>
  +
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
  +
</PRE>
  +
"если перемення установлен действие А, если нет Б". Забавно?)
  +
  +
  +
==Боевой пример - "кластер"==
  +
Задача - установить 3 ноды, на ноде 1 <B>СТРОГО ПОСЛЕ ЗАВЕРШЕНИЯ УСТАНОВКЕ НА ВСЕХ НОДАХ</B> сделать набор post-install шагов.
  +
  +
===Определить параметры кластера===
  +
Это живой пример, потому определяю параметры так как я это делал на живом кластеер
  +
  +
===Рецепт===
  +
/var/chef/cookbooks/demo/attributes/default.rb - файл с пре-определнными атрибутами. У нас всего один атрибут - ip address мастер-ноды
  +
  +
<PRE>
  +
set[:demo][:master_node] = "172.31.0.5"
  +
</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
   
  +
В результате исполнения этого кода мы можем точно знать - на какой стадии установки у нас находится кластер и предпринимать действия на основе этого знанеия.
The chef-server-ctl command is used on the Chef Server system for management. It has built-in help (-h) that will display the various sub-commands.
 

Текущая версия на 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
Немного забегая вперед, вот мой вывод:

#initctl list rc stop/waiting lxc-sysinit stop/waiting tty (/dev/tty3) start/running, process 452 tty (/dev/tty2) start/running, process 450 tty (/dev/tty1) start/running, process 448 tty (console) start/running, process 10 tty (/dev/tty4) start/running, process 454 opscode-runsvdir start/running, process 699 plymouth-shutdown stop/waiting control-alt-delete stop/waiting rcS-emergency stop/waiting kexec-disable stop/waiting quit-plymouth stop/waiting rcS stop/waiting prefdm stop/waiting init-system-dbus stop/waiting splash-manager stop/waiting start-ttys stop/waiting rcS-sulogin stop/waiting serial stop/waiting

Конфигурация

Запускаю:

#chef-server-ctl reconfigure
Note: "Зависание": У меня на стадии запуска RabbitMQ произошло зависание. Я ре-стартовал контейнер и запустил заново конфигурацию - все прошло успешно. (Рестартовать контейнер это БЫСТРО и удобно - гарантировано убьются все процессы которые хотя бы в теории могут взаимодействовать с chef-server)

После завершения длительного процесса у меня запущен весь комплекс сервисов:

# ps -auxfw <skipped> root 699 0.0 0.0 4136 444 ? Ss 13:47 0:00 runsvdir -P /opt/chef-server/service log: .................................................................................................................................... root 700 0.0 0.0 3984 248 ? Ss 13:47 0:00 \_ runsv rabbitmq root 701 0.0 0.0 4128 460 ? S 13:47 0:00 | \_ svlogd -tt /var/log/chef-server/rabbitmq 496 702 3.1 1.1 1170300 45668 ? Ssl 13:47 2:42 | \_ /opt/chef-server/embedded/lib/erlang/erts-5.9.2/bin/beam.smp -W w -K true -A30 -P 1048576 -- -root /opt/chef-server/embedded/lib/erlang -progname erl -- -home /var/op 496 812 0.0 0.0 4100 248 ? Ss 13:47 0:00 | \_ /opt/chef-server/embedded/lib/erlang/lib/os_mon-2.2.10/priv/bin/cpu_sup 496 813 0.0 0.0 10844 272 ? Ss 13:47 0:00 | \_ inet_gethost 4 496 814 0.0 0.0 12948 476 ? S 13:47 0:00 | \_ inet_gethost 4 root 1034 0.0 0.0 3984 284 ? Ss 13:48 0:00 \_ runsv postgresql root 1035 0.0 0.0 4128 476 ? S 13:48 0:00 | \_ svlogd -tt /var/log/chef-server/postgresql 495 1036 0.0 0.8 1088948 35616 ? Ss 13:48 0:00 | \_ /opt/chef-server/embedded/bin/postgres -D /var/opt/chef-server/postgresql/data 495 1059 0.0 0.2 1089444 9284 ? Ss 13:48 0:00 | \_ postgres: checkpointer process 495 1060 0.0 0.1 1089444 6864 ? Ss 13:48 0:00 | \_ postgres: writer process 495 1061 0.0 0.0 1089444 436 ? Ss 13:48 0:00 | \_ postgres: wal writer process 495 1062 0.0 0.0 1090360 1380 ? Ss 13:48 0:00 | \_ postgres: autovacuum launcher process 495 1063 0.0 0.0 26448 656 ? Ss 13:48 0:00 | \_ postgres: stats collector process 495 1954 0.0 0.1 1093524 7872 ? Ss 14:10 0:02 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(42952) idle 495 1955 0.0 0.0 1092728 3852 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(53639) idle 495 1956 0.0 0.0 1092760 3992 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(43920) idle 495 1957 0.0 0.0 1092760 4016 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(39234) idle 495 1958 0.0 0.0 1092760 3868 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(39844) idle 495 1959 0.0 0.0 1092760 3844 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(54279) idle 495 1960 0.0 0.1 1092760 5580 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(39423) idle 495 1961 0.0 0.1 1092760 5612 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(50890) idle 495 1962 0.0 0.1 1092760 5596 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(41556) idle 495 1963 0.0 0.1 1092760 5800 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(52568) idle 495 1964 0.0 0.1 1092760 5604 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(49338) idle 495 1965 0.0 0.1 1092764 5632 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(53116) idle 495 1966 0.0 0.1 1092764 5824 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(52913) idle 495 1967 0.0 0.1 1092764 5612 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(44135) idle 495 1968 0.0 0.1 1092764 5660 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(40645) idle 495 1969 0.0 0.1 1092764 5664 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(58461) idle 495 1970 0.0 0.1 1092764 5672 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(50257) idle 495 1971 0.0 0.1 1092764 5632 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(43469) idle 495 1972 0.0 0.1 1092764 5640 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(57781) idle 495 1973 0.0 0.1 1092764 5668 ? Ss 14:10 0:01 | \_ postgres: opscode_chef opscode_chef 127.0.0.1(53964) idle root 1134 0.0 0.0 3984 284 ? Ss 13:48 0:00 \_ runsv chef-solr root 1135 0.0 0.0 4128 480 ? S 13:48 0:00 | \_ svlogd -tt /var/log/chef-server/chef-solr 496 1136 0.3 2.3 2274872 94148 ? Ssl 13:48 0:17 | \_ java -Xmx989M -Xms989M -XX:NewSize=98M -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8086 -Dcom.sun.mana root 1160 0.0 0.0 3984 284 ? Ss 13:48 0:00 \_ runsv chef-expander root 1161 0.0 0.0 4128 488 ? S 13:48 0:00 | \_ svlogd -tt /var/log/chef-server/chef-expander 496 1162 0.0 0.3 108756 15880 ? Ssl 13:48 0:01 | \_ ruby /opt/chef-server/embedded/service/chef-expander/bin/chef-expander -n 2 -c /var/opt/chef-server/chef-expander/etc/expander.rb 496 1201 0.7 0.5 178892 24040 ? Sl 13:48 0:40 | \_ chef-expander worker #1 (vnodes 0-511) 496 1204 0.7 0.5 179948 23732 ? Sl 13:48 0:39 | \_ chef-expander worker #2 (vnodes 512-1023) root 1224 0.0 0.0 3984 284 ? Ss 13:48 0:00 \_ runsv bookshelf root 1225 0.0 0.0 4128 476 ? S 13:48 0:00 | \_ svlogd -tt /var/log/chef-server/bookshelf 496 1226 0.2 0.1 260896 7008 ? Ssl 13:48 0:12 | \_ /opt/chef-server/embedded/service/bookshelf/erts-5.9.2/bin/beam.smp -- -root /opt/chef-server/embedded/service/bookshelf -progname bookshelf -- -home /var/opt/chef-se root 1270 0.0 0.0 3984 248 ? Ss 13:48 0:00 \_ runsv erchef root 1271 0.0 0.0 4128 480 ? S 13:48 0:00 | \_ svlogd -tt /var/log/chef-server/erchef 496 1578 2.1 0.7 608268 29580 ? Ssl 13:49 1:48 | \_ /opt/chef-server/embedded/service/erchef/erts-5.9.2/bin/beam.smp -K true -A 5 -- -root /opt/chef-server/embedded/service/erchef -progname erchef -- -home /var/opt/che 496 1604 0.0 0.0 10844 528 ? Ss 13:49 0:00 | \_ inet_gethost 4 496 1605 0.0 0.0 12948 636 ? S 13:49 0:00 | \_ inet_gethost 4 root 1389 0.0 0.0 3984 316 ? Ss 13:48 0:00 \_ runsv chef-server-webui root 1390 0.0 0.0 4128 536 ? S 13:48 0:00 | \_ svlogd -tt /var/log/chef-server/chef-server-webui 496 1391 0.0 0.5 87148 20540 ? Ssl 13:48 0:01 | \_ unicorn master -E chefserver -c /var/opt/chef-server/chef-server-webui/etc/unicorn.rb /opt/chef-server/embedded/service/chef-server-webui/config.ru 496 1430 0.1 2.6 773356 108440 ? Sl 13:48 0:10 | \_ unicorn worker[0] -E chefserver -c /var/opt/chef-server/chef-server-webui/etc/unicorn.rb /opt/chef-server/embedded/service/chef-server-webui/config.ru 496 1432 0.1 1.3 146388 55952 ? Sl 13:48 0:05 | \_ unicorn worker[1] -E chefserver -c /var/opt/chef-server/chef-server-webui/etc/unicorn.rb /opt/chef-server/embedded/service/chef-server-webui/config.ru root 1556 0.0 0.0 3984 312 ? Ss 13:49 0:00 \_ runsv nginx root 1557 0.0 0.0 4128 312 ? S 13:49 0:00 \_ svlogd -tt /var/log/chef-server/nginx root 1558 0.0 0.0 78072 2836 ? Ss 13:49 0:00 \_ nginx: master process /opt/chef-server/embedded/sbin/nginx -c /var/opt/chef-server/nginx/etc/nginx.conf 496 1574 0.0 0.1 82500 6824 ? S 13:49 0:00 \_ nginx: worker process 496 1575 0.0 0.1 82216 5556 ? S 13:49 0:01 \_ nginx: worker process 496 1576 0.0 0.0 78244 1332 ? S 13:49 0:00 \_ nginx: cache manager process 496 719 0.0 0.0 10876 252 ? S 13:47 0:00 /opt/chef-server/embedded/lib/erlang/erts-5.9.2/bin/epmd -daemon

Базовое тестирование

chef-server-ctl test

Достаточно длительный процесс (по крайне мере на ограниченных ресурсах контейнера)
У меня возникли некоторые проблемы (пока я не выявил сказалось ли это на работоспособности сервера)

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 файлы ключей:

mkdir /root/.chef/ cp /etc/chef-server/chef-validator.pem ~/.chef/ cp /etc/chef-server/admin.pem ~/.chef/

Запускаем knife configure -i

#knife configure -i Overwrite /root/.chef/knife.rb? (Y/N) I have no idea what to do with Just say Y or N, please. Overwrite /root/.chef/knife.rb? (Y/N) Y Please enter the chef server URL: [http://localhost:4000] https://172.31.0.2:443 Please enter a name for the new user: [root] Please enter the existing admin name: [admin] Please enter the location of the existing admin's private key: [/etc/chef/admin.pem] ~/.chef/admin.pem Please enter the validation clientname: [chef-validator] Please enter the location of the validation key: [/etc/chef/validation.pem] ~/.chef/chef-validator.pem Please enter the path to a chef repository (or leave blank): Creating initial API user... Please enter a password for the new user: Created user[root] Configuration file written to /root/.chef/knife.rb

Обратить внимание - у меня при указании localhost вместо https://172.31.0.2:443 не работал бутстрап

Нод пока нет, но все равно проверяю ...

#knife node list

Конфиг .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'
#knife client list chef-validator chef-webui
#knife user list admin root

chef-server-ctl

Управлять сервером теперь тоже по новому. Вобщем, хелп понятный - особо расписывать нечего. chef-server]# chef-server-ctl status

#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

В результате исполнения этого кода мы можем точно знать - на какой стадии установки у нас находится кластер и предпринимать действия на основе этого знанеия.