Chef 意为 "厨房",我们要做 "菜",自然需要有 "菜谱"。事实上在 Chef 中分发到各服务器节点的不是 "菜",而是 "菜谱",服务器自己 "做菜",自己管理自己。
Cookbook 规定了在 Chef 中执行的操作顺序,决定了应用的构建步骤。可以从市场中寻找一个 cookbook,市场地址: https://supermarket.chef.io/cookbooks/ 使用如下命令:
- knife cookbook site install nginx
它会进行版本控制,在提交历史中留下创建记录。
如果不适用版本控制,则可以使用如下命令(不推荐):
- knife cookbook site download nginx
在老的版本中,使用 knife 来与 Chef Server 进行交互,创建一个 cookbook 的命令是这样的:
- knife cookbook create first_cookbook
而在新版本中,创建的命令变为:
- chef generate app first_cookbook
在 repo 的 cookbook 目录下新建时,输入如下命令:
- chef generate first_cookbook
执行命令后,可以看到创建的目录:
- .
- ├── Berksfile
- ├── chefignore
- ├── LICENSE
- ├── metadata.rb
- ├── README.md
- ├── recipes
- │ └── default.rb
- ├── spec
- │ ├── spec_helper.rb
- │ └── unit
- │ └── recipes
- │ └── default_spec.rb
- └── test
- └── smoke
- └── default
- └── default_test.rb
在新版本 Chef 中,不会自动生成所有目录,一个 cookbook 内可能包含的目录及作用参见文档: https://docs.chef.io/cookbooks.html
接下来,我们创建一个部署 nginx 的 cookbook,在这里以 tengine 为例:
首先,修改 recipes 目录下的以 .rb 结尾的文件,该文件记录了节点自身进行操作的步骤。
- package 'pcre-devel' do
- action :install
- end
- package 'openssl' do
- action :install
- end
- package 'openssl-devel' do
- action :install
- end
上述脚本安装了可能缺少的依赖包,这里 Chef 可以帮我们抹除平台差异,例如在 Ubuntu 平台使用 apt 和在 CentOS 使用 yum 的差异。
也可以一步安装多个依赖包:
- package %w(pcre-devel openssl openssl-devel)
- action :install
- end
这里可能产生的问题是,在不同的平台包名可能不同,对不同环境下依赖包的版本不同。当然,Chef 会考虑到这一点,这里不详细展开,可以参阅文档: https://docs.chef.io/resource_package.html
安装完依赖后,就需要下载 tengine 源码,并进行编译操作。这一步用 shell 命令很方便,所以在 recipe 中也是可以定义一组 shell 命令的。在文件后追加如下行:
- script 'install_tengine' do
- interpreter 'bash'
- user 'root'
- cwd '/usr/local/src'
- code <<-EOH
- wget 'http://tengine.taobao.org/download/tengine-2.2.1.tar.gz'
- tar -zxvf tengine-2.2.1.tar.gz -C /usr/local/src/
- cd /usr/local/src/tengine-2.2.1/
- ./configure
- make
- make install
- chkconfig nginx on
- EOH
- end
interpreter 参数指定了要以何种 shell 去运行,user 定义执行用户,cwd 定义执行路径。
随后下载解压,进行编译安装。
可以看到我们在定义的命令中启用了 nginx 服务:
chkconfig nginx on
这里的问题在于,tengine 编译后并不会生成定义服务的文件,因而需要我们手动添加服务,即:
创建 nginx 服务文件 -> 给定权限 -> 启用服务
所以需要添加一个固定的文件,添加到节点中。在 cookbook 内,可以定义文件,文件中的内容一般是固定不变的。
在
块之前添加:
- script 'install_tengine' do
- cookbook_file "/etc/init.d/nginx" do
- source "nginx"
- mode '0755'
- owner 'root'
- group 'root'
- end
以本地文件 nginx 去添加到节点服务器的 /etc/init.d/nginx 内。其它参数顾名思义,cookbook 文件、权限、所有者及组。
新建一个 files/default 文件夹,在其中建立 nginx 文件,该文件定义了 nginx 服务,会被添加至 /etc/init.d/ 文件夹。nginx 文件的内容可以自己去定义,也可以参考如下定义(来自 http://blog.51cto.com/benpaozhe/1760999 ):
- #!/bin/bash
- #writer:gaolixu
- #chkconfig: 345 86 16
- start(){
- if [ -f /var/lock/subsys/tengine.lock ];then
- echo "Tengine is already running: [ FAILED ]"
- else
- if /usr/local/nginx/sbin/nginx ;then
- echo "Starting tengine: [ OK ]"
- touch /var/lock/subsys/tengine.lock
- else
- echo "Starting tengine: [ FAILED ]"
- fi
- fi
- }
- stop(){
- if [ -f /var/lock/subsys/tengine.lock ];then
- if /usr/local/nginx/sbin/nginx -s quit ;then
- echo "Stopping tengine: [ OK ]"
- rm -rf /var/lock/subsys/tengine.lock
- else
- echo "Stopping tengine: [ FAILED ]"
- fi
- else
- echo "Tengine not runing: [ FAILED ]"
- fi
- }
- reload(){
- if /usr/local/nginx/sbin/nginx -s reload ;then
- echo "Reload tengine: [ OK ]"
- else
- echo "Reload tengine: [ FAILED ]"
- fi
- }
- case $1 in
- "start")
- start
- ;;
- "stop")
- stop
- ;;
- "restart")
- stop
- sleep 1
- start
- ;;
- "reload")
- reload
- ;;
- "status")
- s=`pidof -s nginx`
- [ "$s" ] && echo "Tengine(nginx) pid $s running!!" || echo "Tengine(nginx) not runging!"
- ;;
- *)
- echo "usage: $0 start|stop|restart|reload|status"
- esac
现在,目录结构应该是这样的:
- .
- ├── Berksfile
- ├── chefignore
- ├── files
- │ └── default
- │ └── nginx
- ├── LICENSE
- ├── metadata.rb
- ├── README.md
- ├── recipes
- │ └── default.rb
- ├── spec
- │ ├── spec_helper.rb
- │ └── unit
- │ └── recipes
- │ └── default_spec.rb
- └── test
- └── smoke
- └── default
- └── default_test.rb
当安装完添加服务后,当然希望它启动:
- service 'nginx' do
- supports [:enable, :start, :status, :restart, :reload]
- action :start
- end
定义了 nginx 服务支持的命令和要执行的操作,对 service 的管理,参见: https://docs.chef.io/resource_service.html
同样地,使用 Chef 内置的语法来管理 service,可以消除平台差异,并且可以支持更多的逻辑判断操作,对服务的管理更加灵活。
现在就简单的完成了一个 cookbook,现在来测试一下运行结果,在 chef-repo 文件夹下运行:
- chef - client--local - mode--override - runlist first_cookbook
可以看到一堆命令输出,若有报错会中止!
命令结束后,验证:
- service nginx status
- Tengine(nginx) pid 23776 running!!
可以看到,已经成功使用 cookbook 部署运行了 nginx。
我们简单的创建了一个 nginx 的 cookbook,并且在部署后实现了服务的自动启动。但是往往在现实中会有不同的配置,简单的使用默认配置当然不能满足需求。这时,cookbook 中的 template 和 attributes 就派上用场了。下篇文章会使用模板变量结合一定的逻辑,来实现多样化的配置管理需求。
-EOF-
来源: https://www.cnblogs.com/geekrainy/p/8125979.html