企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 使用Chef ### 以Chef Server管理模式为例 我们刚才创建的cookbook的名字叫: apache-tutorial-1。它的目的就是要在指定的node上面安装apache,并且启动服务。 ### 1 编写recipe 让我们编写第一个recipe。试想一下,如果手工来安装apache,需要下面三步动作。 - 安装Apache - 启动Apache并且把它添加到开机启动 - 配置home page 现在我们用recipe实现,打开cookbooks/apache-tutorial-1/recipes/default.rb文件,输入以下Ruby代码: ~~~ package 'apache2' do action :install end service 'apache2' do action [ :enable, :start ] end cookbook_file '/var/www/index.html' do source 'index.html' mode '0644' end ~~~ 我来解释下上面的代码: 在Chef中,package是一种资源类型,它告诉chef-client运行时候的「包」的名字,以及执行的动作,这段代码里,是告诉chef-client,要安装papache2. package在执行的时候,会自动的调用底层的provider来匹配相应的服务器平台。 service会告诉chef-client启动哪个服务。会调用底层的ohai组件来收集相关平台信息,从而正确启动相应的服务。这段代码里,是告诉chef-client,想要启动apache2. cookbook_file会告诉chef-client来拷贝index.html文件到/var/www/index.html中,并且设置文件权限为0644. 这只是个简单的recipe,让我们继续。 把下面html代码添加到cookbook/apache-tutorial-1/files/default/index.html中: ~~~ <html> <body> <h1>Hello, world!</h1> </body> </html> ~~~ ### 2 上传Cookbook 我们写完了这个cookbook,就可以把它上传到我们之前搭建的Chef Server上面(非chef-solo模式)。在chef-repo目录中执行下面命令: ~~~ $ knife cookbook upload apache-tutorial-1 ~~~ 然后打开我们的Chef Server Webui: [https://192.168.33.11/cookbooks](https://192.168.33.11/cookbooks) 就可以看到我们上传的Cookbook了,如图: ![cookbook](https://box.kancloud.cn/2015-08-23_55d9d7adb50b6.png) ### 3 设置Run list 还是在Chef Server Webui上面,点击:[https://192.168.33.11/nodes](https://192.168.33.11/nodes) 选择你要安装的node, 点击编辑(edit),如图: ![node-edit](https://box.kancloud.cn/2015-08-23_55d9d7adc7d1f.png) 在编辑界面,如图把apache-tutorial-1移动到右边,点击保存。 ![run_list](https://box.kancloud.cn/2015-08-23_55d9d7addd061.png) ~~~ 说明: Run list就是一个运行列表,包含了所有需要安装的role,以及按依赖顺序把recipe排列。 ~~~ ### 执行cookbook配置node cookbook设置完毕,我们就执行下面命令来配置node: ~~~ $ knife ssh 192.168.33.12 'sudo chef-client' -m -x vagrant -P vagrant ~~~ 这个命令会在ip为192.168.33.12的node上面执行sudo chef-client命令来配置节点。当然,你也可以登陆到那台虚拟机上面手工执行sudo chef-client命令。 命令执行成功之后,你登陆到192.168.33.12那台虚拟机上面,就会看到apatch2已经正常运行了。 ![apache-run](https://box.kancloud.cn/2015-08-23_55d9d7adf25d9.png) ### 以OpsCode Chef为例 过程和自建Chef Server类似,可以自行练习。 ### 以Chef Solo管理模式为例 当你对上面Chef Server模式有了一定了解,那么Chef Solo理解起来也不吃力了。 Chef Solo因为没有Server,所以我们直接在node机器上来执行。 我们继续拿上面用过的node2为例子。 **注意: 以下操作都在node2虚拟机上面** ~~~ $ mkdir -p /etc/chef/coobooks/nginx/recipes ~~~ 必须要在/etc/chef目录下面。 ~~~ cd /etc/chef/coobooks/nginx/recipes sudo touch default.rb sudo vi default.rb ~~~ 写入下面Ruby代码: ~~~ package 'nginx' ~~~ 然后回到/etc/chef 目录,创建node.json文件,然后编辑run list: ~~~ { "run_list": ["recipe[nginx]"] } ~~~ 然后在/etc/chef目录下,建立solo.rb文件: ~~~ cookbook_path File.expand_path("../cookbooks", __FILE__) json_attribs File.expand_path("../node.json", __FILE__) ~~~ 用来指定cookbooks和node.json的位置。 然后我们执行命令: ~~~ $ sudo chef-solo solo.rb ~~~ 安装成功。 ![Chef Solo](https://box.kancloud.cn/2015-08-23_55d9d7ae10a5c.png) *chef solo* ### 启动服务 我们需要在nginx被安装完之后,可以自动启动。 再次打开 /etc/chef/cookbooks/nginx/recipes/default.rb修改代码为下面几行: ~~~ package 'nginx' service 'nginx' do supports [:status, :restart, :reload] action :start end ~~~ 我们在chef server那节里介绍过service这个资源的含义。supports,用来告诉Chef,支持status、restart、reload这三个命令。最后用action来告诉Chef,当前动作是start。 然后在/etc/chef下执行: ~~~ $ sudo chef-solo solo.rb ~~~ 就能看到nginx被正常启动了。 很酷。 ### 增加用户 用户,是我们经常使用的,Chef也提供了User资源,来帮助你管理这些Chef使用者的用户。 比如,我们可以在/etc/chef/cookbooks下面再创建一个名为user的recipes, ~~~ $ sudo mkdir /etc/chef/cookbooks/user/recipes $ cd /etc/chef/cookbooks/user/recipes $ sudo touch default.rb ~~~ 在default.rb中输入下面代码: ~~~ user 'blackanger' do password "$1$3YbJDvy2$JD2o6dEFjGvayRgmZWU030" gid "admin" home "/home/blackanger" supports manage_home: true end ~~~ 说明: password,告诉Chef,此为用户的密码,是经过openssl加密的,使用此命令来加密:[openssl passwd -1 "passwd"]。 gid,告诉Chef,要把这个用户加到admin组里面,home,是指定用户的home目录, supports,指定管理其home的权限。 然后再打开/etc/chef/node.json, 加入recipes['user']: ~~~ { "run_list": ["recipe[nginx]", "recipe[user]"] } ~~~ 执行命令: ~~~ $ sudo chef-solo solo.rb ~~~ 我们就可以看到执行结果了: ![add_user](https://box.kancloud.cn/2015-08-23_55d9d7ae2a433.png) *add user* ### 设定node.json 我们虽然创建好了用户,但是仔细想想,这种方式不太好,假如我们配置多台机器呢? user recipes里写的太死,代码无法重用了。 好在,我们Chef还可以允许我们把这种用户信息写到node.json里。 打开/etc/chef/node.json: ~~~ { "run_list": ["recipe[nginx]", "recipe[user]"], "user": { "name": "blackanger", "password": "$1$3YbJDvy2$JD2o6dEFjGvayRgmZWU030" } } ~~~ 然后回到user recipes的default.rb文件中修改为: ~~~ user node[:user][:name] do password node[:user][:password] gid "admin" home "/home/#{node[:user][:name]}" supports manage_home: true end ~~~ 然后执行: ~~~ $ sudo chef-solo solo.rb ~~~ 成功!是不是很酷啊! ### 使用template 回到刚才nginx的例子, 我们还需要给nginx设置一个配置文件,这个时候,就要用到template资源了。 ~~~ $ sudo mkdir /etc/chef/cookbooks/nginx/templates/default $ sudo touch /etc/chef/cookbooks/nginx/templates/default/nginx.conf.erb ~~~ 注意,我们创建了一个nginx.conf.erb文件, 如果对Rails有了解的朋友,应该指定,erb是一个模板引擎,它可以支持你在这种模板里面变量运算、替换等操作。 打开nginx.conf.erb,输入下面代码: ~~~ server { server_name 192.168.33.12; root /home/<%= node[:user][:name] %>/demo; } ~~~ 注意:上面形如 <% ... %> 这样格式的代码,就是erb的语法,可以把需要替换的变量放到里面。 然后我们在回到nginx的recipe中告诉Chef应该使用这个template: 打开:/etc/chef/cookbooks/nginx/recipes/default.rb, 添加下面代码: ~~~ template "/etc/nginx/sites-enabled/nginx.conf" do source 'nginx.conf.erb' notifies :restart, 'service[nginx]', :immediately end ~~~ 说明:"/etc/nginx/sites-enabled/nginx.conf" 是告诉Chef,template文件要保存的路径。 source告诉Chef去哪找这个template, notifies是一个callback,告诉Chef要马上重启nginx服务。 然后我们分别使用directory和file资源来添加一个html文件,写法同上,下面给出完成的nginx recipe: ~~~ package 'nginx' service 'nginx' do supports [:status, :restart, :reload] action :start end directory "/home/#{node[:user][:name]}/demo" do owner node[:user][:name] end file "/home/#{node[:user][:name]}/demo/index.html" do owner node[:user][:name] content "<h1>Hello blackanger!</h1>" end template "/etc/nginx/sites-enabled/nginx.conf" do source 'nginx.conf.erb' notifies :restart, 'service[nginx]', :immediately end ~~~ 然后执行我们的老命令: sudo chef-solo solo.rb, 愿望达成: ![nginx_recipe](https://box.kancloud.cn/2015-08-23_55d9d7ae385f9.png) *run nginx recipe* 验证: ~~~ $ curl http://127.0.0.1 <h1>Hello blackanger!</h1> ~~~ 至此,我们就学会了使用chef-solo来安装「一台」机器。如果你想安装多台, 那么继续按照上面的步骤,安装chef-solo,然后复制cookbooks,一台一台的执行命令。 这样是不是还是很麻烦呢? 那当然了! 辛亏我们还有knife,这个超级助手。 ### chef-solo with knife Knife是一套强大的命令行Chef管理工具。我们可以使用knife来帮助我们简化麻烦的工作,让我们不需要通过Chef Server就可以直接和需要配置的服务器交互。 因为我们使用的chef-solo方式,所以我们先安装一个gem: ~~~ $ gem install knife-solo ~~~ 安装好之后执行命令: ~~~ $ knife solo init knife-solo-demo ~~~ 就会帮助我们生成一个solo目录: ![knife-solo-dir](https://box.kancloud.cn/2015-08-23_55d9d7ae57fd6.png) 注意: 在使用这个命令之前,要确保你的Ruby环境是否唯一,否则可能会出现找不到knife子命令solo的错误。 这个目录中,.chef/文件夹下面包含一个knife.rb文件。这个文件在我们讲过的Chef Server模式下也是一样存在的,具体的配置文档可以去[官网](http://docs.getchef.com/config_rb_knife.html)查看。这里生成的knife.rb文件中包含下面代码: ~~~ cookbook_path ["cookbooks", "site-cookbooks"] node_path "nodes" role_path "roles" environment_path "environments" data_bag_path "data_bags" #encrypted_data_bag_secret "data_bag_key" knife[:berkshelf_path] = "cookbooks" ~~~ 这里cookbook_path是相对于仓库根目录的路径,指定了角色中使用的Cookbook信息node_path和role_path分别定义了节点和角色的存储位置,都是相对于根目录的路径。这里有个berkshelf_path, berkshelf是一个第三方cookbook管理工具,我们的cookbooks目录,就是存放这些第三方cookbook,而site-cookbooks是用来存放我们自己编写的cookbook的地方。 然后我们使用命令: ~~~ $ knife solo bootstrap vagrant@192.168.33.11 ~~~ 就可以在另一台vagrant机器(192.168.33.11)上配置chef-solo。它会帮我们安装chef-client, 创建node,创建cookbooks。 knife solo bootstrap实际上执行了两个命令: - knife solo prepare 这个命令主要是初始化服务器,安装chef,配置node,上传cookbook - knife solo cook 这个命令主要是上传cookbook,并且执行指令 chef-solo. 有了这个工具,就方便很多了。