Chef的简单学习

chef的官网是:http://www.getchef.com/chef/
同时参考:Chef Infrastructure Automation Cookbook

1.三个节点类型
Chef server:就是chef的中心服务器,保存了网络的相关信息
workstation:平时对chef的修改就是在这个机子上操作的
node:就是网络中真正干活的主机

2.基本概念
Organizations:完全独立的一个单元。是chef中最顶层的一个概念。其实就是平时实施的时候的一个project。
Environment:就类似于项目中的测试环境、生产环境
Roles:用于定义server的功能。如DB server,APP server。roles包含了这个server listen的port、安装的app等
Nodes:就是server。每个node属于一个encironment和一个organization,但是可以属于零个或多个roles,比如一个server既可以是db server,也可以是app server,或都是。每个nodes上都会安装一个chef-client,后者会的从chef server上获取配置,然后配置当前的node
Recipes:是一些用于描述资源和其状态的配置文件。可以用来安装和配置软件、管理文件、部署应用、执行其它recipes等。比如一个recipe是这样的:

package "apache2"
template "/etc/apache2/apache2.conf" do
	source "apache2.conf.erb"
	owner "root"
	group "root"
	mode "0644"
	variables(:allow_override => "All")
	notifies :reload, "service[apache2]"
end
service "apache2" do
	action [:enable,:start]
	supports :reload => true
end

chef-client会的从上往下解读这个文件,首先是package “apache2″,表明这个node上需要安装这个package,如果没有安装那么chef会自动帮你安装。然后是解读template,这个就是告诉chef要保证这个配置文件的owner、group、mode等信息,以及要保证对应的变量值也要符合要求。接下来就是service,有两个操作,:enable和start,前者就是chkconfig XXX on,后者就是service XXX start。最后的supports是表示这个service有一个reload功能,在配置文件修改后做reload操作。
Cookbook:由很多的recipes组成。包含了recipes、templates、files、custome resources等东西。
run list:node中的chef-client会的去询问server自己的policy是啥,server会的告知node类似如下的东西:

recipe[ntp::client]
recipe[users]
role[webserver]

这些东西就是run list。chef-client之后就会的去解析这些东西,然后配置node。
search:用于查找指定role的node以及发现数据的拓扑。比如我们搭建了一个organization,这个时候就可以问chef server:hi,哪个server是我们的web server。然后chef server就会告诉我们ipXXX的server是我们的web server。
knife:就是管理员创建cookbook之类的管理工具,一般来说安装了knife的主机就是我们的workstation
chef-client:其会把节点注册到chef server上,创建node对象,同步cookbook,在node上进行相关的node的操作。其和chef server的认证通过RSA密钥对来进行。
ohai:一个用于收集当前主机各种属性的工具。比如可以知道是啥发行版,网络配置,内存cpu配置等很多的信息。
chef-repo:一般是创建在workstation上。在这个repo里会保存cookbook,role等文件。这个一般需要用git来维护版本,所以这里边的东西其实就和源代码一样。

3.安装
具体的安装可以参考这篇文章

4.创建一个简单的cookbook
首先创建一个cookbook的模板,这个就类似于用eclipse建立一个web project,然后eclipse把相关的源码框架搭建好:

[root@CENSVR03 chef-repo]# knife cookbook create my_cookbook
** Creating cookbook my_cookbook
** Creating README for cookbook: my_cookbook
** Creating CHANGELOG for cookbook: my_cookbook
** Creating metadata for cookbook: my_cookbook

上传到server:

[root@CENSVR03 chef-repo]# knife cookbook upload my_cookbook
Uploading my_cookbook  [0.1.0]
Uploaded 1 cookbook.

将这个cookbook分配给某个node:

[root@CENSVR03 chef-repo]# knife node run_list add node01 recipe[my_cookbook]
node01:
  run_list: recipe[my_cookbook]

node从server获取自己需要做的操作:

[root@CENSVR02 ~]# sudo chef-client
[2014-05-12T19:22:45-07:00] WARN: 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
SSL validation of HTTPS requests is disabled. HTTPS connections are still
encrypted, but chef is not able to detect forged replies or man in the middle
attacks.

To fix this issue add an entry like this to your configuration file:

```
  # Verify all HTTPS connections (recommended)
  ssl_verify_mode :verify_peer

  # OR, Verify only connections to chef-server
  verify_api_cert true
```

To check your SSL configuration, or troubleshoot errors, you can use the
`knife ssl check` command like so:

```
  knife ssl check -c /etc/chef/client.rb
```

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 

Starting Chef Client, version 11.12.4
resolving cookbooks for run list: ["my_cookbook"]
Synchronizing Cookbooks:
  - my_cookbook
Compiling Cookbooks...
Converging 0 resources

Running handlers:
Running handlers complete

Chef Client finished, 0/0 resources updated in 3.677801242 seconds

5.cookbook的常用操作
查看版本:

[root@CENSVR03 chef-repo]# knife cookbook show iptables
iptables   0.13.2

查看cookbook的定义:

[root@CENSVR03 chef-repo]# knife cookbook show iptables 0.13.2 definitions
checksum:    45c0b77ff10d7177627694827ce47340
name:        iptables_rule.rb
path:        definitions/iptables_rule.rb
specificity: default
url:         https://CENSVR01.thuanqin.com:443/bookshelf/organization-00000000000000000000000000000000/checksum-45c0b77ff10d7177627694827ce47340?AWSAccessKeyId=1ffc88d9d9c31f1c98b92c7d8519119f9e84e795&Expires=1399949192&Signature=SYyicDTYzVY%2BbjojAXp4jG6zG6g%3D

查看cookbook中某个文件的内容:

[root@CENSVR03 chef-repo]# knife cookbook show iptables 0.13.2 definitions iptables_rule.rb
#
# Cookbook Name:: iptables
# Definition:: iptables_rule
#
# Copyright 2008-2009, Opscode, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

define :iptables_rule, :enable => true, :source => nil, :variables => {}, :cookbook => nil do
  template_source = params[:source] ? params[:source] : "#{params[:name]}.erb"
  
  template "/etc/iptables.d/#{params[:name]}" do
    source template_source
    mode 0644
    cookbook params[:cookbook] if params[:cookbook]
    variables params[:variables]
    backup false
    notifies :run, resources(:execute => "rebuild-iptables")
    if params[:enable]
      action :create
    else
      action :delete
    end
  end
end

对于chef 11用下面的命令同样能实现相关的效果:

[root@CENSVR03 chef-repo]# knife show cookbooks/iptables/definitions/*

cookbook的依赖:
这个就类似于c语言中的include。比如社区里有很多已经写好的常用的cookbook了(比如有个cookbook是安装glibc),我现在要写的cookbook需要保证glibc已经安装了,所以我的cookbook可以依赖这个glibc的cookbook。要实现这个只需要在cookbook的metadata.rb中添加类似下面的东西:

depends 'build-essential'
depends 'apache2', '>= 1.0.4'

下载公开的cookbook:

[root@CENSVR03 chef-repo]# knife cookbook site install ntp

检查某个cookbook是否符合要求:

[root@CENSVR03 chef-repo]# knife cookbook test ntp
checking ntp
Running syntax check on ntp
Validating ruby files
Validating templates

在recipe中添加log:

mma@laptop:~/chef-repo $ subl cookbooks/ntp/recipes/default.rb
Chef::Log.info('** Going to install the ntp service now...')
service node['ntp']['service'] do
supports :status => true, :restart => truetrue
action [ :enable, :start ]
end
Chef::Log.info('** ntp service installed and started successfully!')

6.node操作
删除node和对应的client:knife node delete my_nodeXXX;knife client delete my_nodeXXX

编辑某个node的定义,比如runlist啥的(注意,编辑好后最好在node上云新下chef-client):

[root@CENSVR03 chef-repo]# knife node edit node01

7.role
role就是一组node的角色,比如我有个role叫做web_server,然后可以把一些node分配给这个role,之后可以通过各种操作操作这个node。并且也可以把runlist给role,然后把role给node,这样node也就有了对应当然runlist。
导入role(注意下这个role有个run-list):

mma@laptop:~/chef-repo $ cat roles/web_servers.rb
name "web_servers"
	description "This role contains nodes, which act as web servers"
	run_list "recipe[ntp]"
	default_attributes 'ntp' => {
		'ntpdate' => {
		'disable' => true
	}
}
mma@laptop:~/chef-repo $ knife role from file web_servers.rb

然后通过编辑node,设置下面的内容把node加入role:

mma@laptop:~/chef-repo $ knife node edit server
	"run_list": [
		"role[web_servers]"
]

8.environment
用于区分开发、测试、生产这样的环境。

9.chef-client
设置chef-client每隔一段时间自动运行,这样可以避免手工去启动chef-client来从server同步信息(这里是每30分钟同步一次):

[root@CENSVR02 ~]# nohup chef-client -i 1800 &

查看在某个client上运行某个recipe会发生什么(这里的-o指的是override,就是覆盖这个node自己的runlist),但这个不一定和实际情况符合,毕竟这个不会真的去安装:

[root@CENSVR02 ~]# sudo chef-client -o recipe['ntp'] --why-run

debug模式运行:

[root@CENSVR02 ~]# chef-client -l debug

10.chef语法
10.1 使用attributes,attributes其实就是一些配置文件,在这些文件中可以有很多KV对供其它rb文件使用:
首先建立一个一个attributes的文件:

[root@CENSVR03 chef-repo]# touch cookbooks/my_cookbook/attributes/default.rb

在一种添加一条attribute:

[root@CENSVR03 chef-repo]# cat cookbooks/my_cookbook/attributes/default.rb
default['my_cookbook']['message'] = 'hello world!'

在recipe中添加相关的对attribute的引用:

[root@CENSVR03 chef-repo]# tail cookbooks/my_cookbook/recipes/default.rb 
# See the License for the specific language governing permissions and
# limitations under the License.
#
message = node['my_cookbook']['message']
Chef::Log.info("** Saying what I was told to say: #{message}")

上传这个cookbook,然后runlist中拥有这个runlist的server运行chef-client同步数据的时候就可以看到对应的输出了:

[root@CENSVR03 chef-repo]# knife cookbook upload my_cookbook
Uploading my_cookbook    [0.1.0]
Uploaded 1 cookbook.

然后客户端运行chef-client的时候就能看到log信息了。

attributes的处理顺序是default < normal < override < roles & environment
可以看到在roles或environment中定义的是最高级的,会覆盖前面的。比如roles中有下面的定义:

mma@laptop:~/chef-repo $ cat roles/german_hosts.rb
name "german_hosts"
description "This Role contains hosts, which should print out their messages in German"
run_list "recipe[my_cookbook]"
default_attributes "my_cookbook" => { "message" => "Hallo Welt!" }

这里message就会进行覆盖其它attribute文件中的定义。

10.2 template
类似于jsp文件,动态的提供一个配置文件。
一个例子:

mma@laptop:~/chef-repo $ cat cookbooks/my_cookbook/recipes/default.rb
template '/tmp/message' do
	source 'message.erb'
	variables(
		hi: 'Hallo',
		world: 'Welt',
		from: node['fqdn']
	)
end

mma@laptop:~/chef-repo $ subl cookbooks/my_cookbook/templates/default/message.erb
<%- 4.times do %>
<%= @hi %>, <%= @world %> from <%= @from %>!
<%- end %>

mma@laptop:~/chef-repo $ knife cookbook upload my_cookbook
Uploading my_cookbook [0.1.0]
Run Chef Client on your node:
user@server:~$ sudo chef-client
...TRUNCATED OUTPUT...
[2013-01-14T20:41:21+00:00] INFO: Processing template[/tmp/message] action create (my_cookbook::default line 9)
[2013-01-14T20:41:22+00:00] INFO: template[/tmp/message] updated content
...TRUNCATED OUTPUT...

user@server:~$ sudo cat /tmp/message
Hallo, Welt from vagrant.vm!
Hallo, Welt from vagrant.vm!
Hallo, Welt from vagrant.vm!
Hallo, Welt from vagrant.vm!

10.3 libraries
可以在cookbooks/my_cookbook/libraries/下写各种类。这些类可以被其它工具调用。

10.4 definitions
就类似于函数。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*