Chef 自动化运维:初探 cookbook

cookbook 概述

Chef 意为“厨房”,咱们要作“菜”,天然须要有“菜谱”。事实上在 Chef 中分发到各服务器节点的不是“菜”,而是“菜谱”,服务器本身“作菜”,本身管理本身。html

Cookbook 规定了在 Chef 中执行的操做顺序,决定了应用的构建步骤。能够从市场中寻找一个 cookbook,市场地址:https://supermarket.chef.io/cookbooks/ 使用以下命令:nginx

knife cookbook site install nginx

它会进行版本控制,在提交历史中留下建立记录。shell

若是不适用版本控制,则能够使用以下命令(不推荐):bash

knife cookbook site download nginx

在老的版本中,使用 knife 来与 Chef Server 进行交互,建立一个 cookbook 的命令是这样的:服务器

knife cookbook create first_cookbook

而在新版本中,建立的命令变为:app

chef generate app first_cookbook

在 repo 的 cookbook 目录下新建时,输入以下命令:ide

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.htmlui

接下来,咱们建立一个部署 nginx 的 cookbook,在这里以 tengine 为例:版本控制

第一个 cookbook

首先,修改 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 中的 templateattributes 就派上用场了。下篇文章会使用模板变量结合必定的逻辑,来实现多样化的配置管理需求。

-EOF-

相关文章
相关标签/搜索