http://www.ibm.com/developerworks/cn/cloud/library/1506_wangqf_chefforweb/index.html
“这是一个最好的时代,也是一个最坏的时代。他们都在直奔天堂,而我们都在直奔相反的方向。”
“90 后霸道总裁”的超级课程表融资千万美元、WhatsApp 被 Facebook 以 190 亿美元收购……这个时代仿佛到处都充满了机会。现在假设我们也决定放弃朝九晚五的工作,要开发出一款 Web 应用改变这个世界,顺便当上总经理、出任 CEO、赢取白富美、走向人生巅峰。七拼八凑,我们的应用做出来了。它的架构非常简单,如果非要描述的话,它的架构如图 1 所示:
图 1. 应用架构
这么简单的应用,我们上网浏览一下资料,随便租个服务器,安装一个 Web 服务器,配置一下,应用顺利上线。
幸福总是来得太快,很快我们的应用就火了。随着访问量的增大,我们需要单独的数据库服务器,一个都不够,得来俩;应用服务器也不够用了,再多添几台,上一个负载均衡;对数据库的访问又成了性能瓶颈,增加些数据库缓存吧,最终,应用的架构变成了如下的样子:
图 2. 演进的应用架构
现在问题来了,面对如此复杂的架构,怎么安装和配置这些服务呢?Chef 就是用来解决这个问题的。
第一份“菜谱”(recipe)
让我们暂且就此打住,先来看看怎么使用 Chef。首先需要在一台 Linux 机器上安装Chef Development Kit。如果您实在找不到一台 Linux 机器也没有关系,可使用一个用于教学用途的在线虚拟机,该虚拟机上已经预装了 Chef Development Kit,可以直接使用。
Recipe 是 Chef 中主要执行任务的地方,翻译成中文是“菜谱”的意思。我们的第一份“菜谱”的主要功能是使用 Chef 生成一个文本文件,其内容为:Hello Chef。让我们先新建一个 chef-repo 目录,用来存放“菜谱”,然后在该目录下创建第一个“菜谱”:hello.rb,其内容如下:
清单 1. hello.rb
file 'motd' do content 'Hello Chef’ end
在命令行中执行:chef-client --local-mode hello.rb,输出如下:
图 3. 输出
可以看到,命令执行后生成 motd 文件,该文件的内容为字符串:Hello Chef。这就是我们的第一份“菜谱”,虽然简单,但是却概括了 Chef 的基本工作原理:使用一个 Ruby 文件,即“菜谱”描述服务器应有的状态,然后执行 Chef 命令配置服务器。
您可尝试再次执行 chef-client --local-mode hello.rb,Chef 会检测到 motd 文件已经存在,且文件内容和“菜谱”中所描述的一致,因此不进行任何操作;您还可尝试手动删除 motd 文件,再次执行 chef-client --local-mode hello.rb 后,又重新生成了 motd 文件。这正是配置服务器所需要的,每次配置都能保证状态一致。
当然,我们的第一份“菜谱”只是一道开胃小菜,下面我们看看如何使用 Chef 部署一个 Web 服务器。
部署 Web 服务器
部署一个 Web 服务器比生成一个文件复杂,但道理却是相同的,让我们先来看看代码:
清单 2. webserver.rb
package 'httpd' service 'httpd' do action [:start, :enable] end file '/var/www/html/index.html' do content '<html> <body> <h1>hello world</h1> </body> </html>' end service 'iptables' do action :stop end
这段代码总共分成四部分:第一部分安装 Apache HTTP Server;第二部分启动 HTTP 服务;第三部分生成主页面;第四部分停用 iptables 服务,这一步主要是因为有些 Linux 安装后,默认只打开 22 端口,其他端口是被禁止的,停用 iptables 服务后,就可以顺利访问 80 端口了,即 HTTP 协议所使用的端口。聪明的您朋友们,您能将这四部分和代码对应起来吗?
这里要注意的是,这四部分的顺序非常重要,必须先安装 Apache HTTP Server,然后启动它,这一点也不难想象,我们手动配置服务器时不也如此吗?
将文件保存后,让我们再来运行 sudo chef-client --local-mode webserver.rb,因为脚本里包含安装软件包的操作,所以需要 root 权限,如果您不是以 root 账号登录(相信您不会真的这样做吧?),务必在命令行前加 sudo,否则,Chef 会报错。如果得到类似下面的输出,就证明服务器配置成功,打开浏览器,输入http://localhost,可以看到刚才定制的主页了吧?
图 4. 输出
然而,作为有“洁癖”的程序员,不难发现“菜谱”的第二部分好像混入了什么奇怪的东西:一段 HTML 代码。这段 HTML 代码明显和其他部分不协调,如果网页再变得复杂点,这份“菜谱”会变得很难管理。因此,我们得想点什么办法,管理“菜谱”。方法就是“烹饪手册”(cookbook)。
“烹饪手册”(cookbook)
和真实的烹饪一样,“烹饪手册”是用来组织“菜谱”的,在“烹饪手册”里,不光可以定义各种“菜谱”,也可以定义一些属性文件或模板,这些属性文件或模板可以在“菜谱”里直接引用。在实际工作中,我们往往使用的也是“烹饪手册”,而不是一个个单独的“菜谱”。
让我们在当前目录下新建一个文件夹 cookbooks,然后切换到该目录,调用 chef generate cookbook learn_chef_httpd 会自动为我们生成一个“烹饪手册”。“烹饪手册”的目录结构如下:
图 5. “烹饪手册”目录结构
其中 recipes 目录下的 default.rb 是默认的“菜谱”,让我们将其中内容替换为之前编写的“菜谱”。
现在我们要将原来“菜谱”中的 HTML 代码移到一个外部文件中,使用 chef generate template learn_chef_httpd index.html 命令生成模板文件 index.html.erb,该文件被放置在 learn_chef_httpd/templates/default 目录下。然后将该文件内容替换为之前的 HTML,修改 default.rb,引用该模板,最终的“菜谱”变成了下面这个样子:
清单 3. default.rb
package 'httpd' service 'httpd' do action [:start, :enable] end template '/var/www/html/index.html' do source 'index.html.erb' end service 'iptables' do action :stop end
在命令中执行 sudo chef-client --local-mode –runlist ‘recipe[learn_chef_httpd]’ ,打开浏览器,访问http://localhost ,如果能正常访问,那么恭喜您完成了自己的第一个“烹饪手册”!
真实环境下的 Chef
上面的例子只是为了展示如何编写“菜谱”和“烹饪手册”,真实环境下的 Chef 却不是这样工作的。在真实环境下,系统管理员在一台电脑上编写 Chef 脚本,然后使用上述方式调试,调试成功后,将脚本上传至 Chef 服务器,我们从控制台向 Chef 服务器发命令,Chef 服务器会将配置下发到各个待配置服务器,在每个服务器上运行 Chef,完成对服务器的配置。
图 6. Chef 原理
为此,我们需做三点准备:一台用于编写 Chef 脚本的电脑、一台 Chef 服务器、很多待配置的服务器。我们已经有了一台可以编写 Chef 脚本的电脑,为了方便学习,Chef 服务器可以选用Chef 官网提供的托管服务,另外需要几台待配置的服务器,记得不要在服务器上安装 Chef,当我们配置这些服务器时,Chef 会自动在上面安装所需的工具。
注册成功 Chef 的托管服务后,先创建一个组织,然后下载与之对应的 Starter Kit,解压到当前目录,该工具是用来做认证的,有了它,才可以从本地连接 Chef 服务器。现在让我们删除以前创建的“烹饪手册”,转而从 Chef 超市上下载一个现成的手册。Chef 超市是一个开发者交流“烹饪手册”的地方,因为配置服务器的很多操作都是通用的,所以人们把这些配置做成手册,放在一个地方,大家都能使用。我们编写 Chef 脚本,往往也是先上 Chef 超市去看看有没有可用的手册,如果有,直接拿过来,或者在此基础上修改一下就能用,如果没有,再考虑编写自己的手册。使用如下命令下载前面配置 Web 服务器的手册:
knife cookbook site download learn_chef_httpd
将下载后的手册解压到 cookbooks 目录,删除压缩包:
tar -zxvf learn_chef_httpd-0.1.0.tar.gz -C cookbooks rm learn_chef_httpd*.tar.gz
接下来将该手册上传至 Chef 服务器,即我们刚才注册的 Chef 托管服务:
knife cookbook upload learn_chef_httpd
打开托管服务控制台,在 Policy 选项卡下就能看见刚刚上传成功的“烹饪手册”。接下来我们要做的工作是告诉 Chef 服务器来帮我们让服务器自举,这一步会通过 SSH 登录到待配置的服务器,下载并安装 Chef,然后下载执行刚刚上传到 Chef 服务器上的“烹饪手册”。该操作只在第一次配置服务器时需要,自举成功后,以后就再不需要自举了:
knife bootstrap {{address}} --ssh-user {{user}} --ssh-password '{{password}}' \ --sudo --use-sudo-password --node-name node1 \ --run-list 'recipe[learn_chef_httpd]'
将其中的{{address}}、{{user}}、{{password}}替换为待配置服务器的真实地址、用户名和密码。打开浏览器,输入服务器地址,看看是否能访问定制的主页?
获取服务器信息
Chef 不光可以管理服务器,同时服务器将自己的信息上传至 Chef 服务器。使用如下命令查看当前组织里被管理的服务器:
knife node list
使用如下命令查看服务器信息,包括服务器的 IP 地址、机器名、操作系统等信息:
knife node show node1
有了这些信息后,我们可以重新修改模板,让其显示给定服务器的信息:
清单 4. index.html.erb
<html> <body> <h1>hello from <%= node['fqdn'] %></h1> </body> </html>
再将“烹饪手册”上传至 Chef 服务器,然后使用如下命令配置服务器:
knife ssh {{address}} 'sudo chef-client' --manual-list \ --ssh-user {{user}} --ssh-password '{{password}}'
同理,将{{address}}、{{user}}、{{password}}替换为待配置服务器的真实地址、用户名和密码。打开浏览器,输入服务器地址,看看改动是否生效?
只要一台服务器配置成功,我们便可以用同样的方法配置几十台、上百台。而且一旦配置发生变化,我们只需修改脚本,所有服务器便可以获得相同的更新,这个时候,Chef 的威力就显示出来了。
chef 还是 knife?
细心的您可能会注意到,上面的命令,一些是 chef *****,一些却是 knife *****。初次接触 Chef,很容易被这些命令搞混。这里有一个简单的规则:本地执行的命令以 chef 打头,需要远程连接到 Chef 服务器或待配置服务器的命令以 knife 打头。
最后,让我们再复习一遍本文中所使用到的命令:
- 运行“菜谱”
chef-client --local-mode hello.rb
- 使用 Chef 生成“烹饪手册”
chef generate cookbook learn_chef_httpd
- 使用 Chef 生成模板
chef generate template learn_chef_httpd index.html
- 使用 Chef 运行“烹饪手册”
chef-client --local-mode –runlist ‘recipe[learn_chef_httpd]’
- 从 Chef 超市下载“烹饪手册”
knife cookbook site download learn_chef_httpd
- 向 Chef 服务器上传“烹饪手册”
knife cookbook upload learn_chef_httpd
- 服务器自举
knife bootstrap {{address}} --ssh-user {{user}} --ssh-password '{{password}}' \ --sudo --use-sudo-password --node-name node1 \ --run-list 'recipe[learn_chef_httpd]'
- 获取当前组织下的服务器列表
knife node list
- 显示服务器信息
knife node show node1
- 使用 Chef 远程运行“烹饪手册”,配置服务器
knife ssh {{address}} 'sudo chef-client' --manual-list \ --ssh-user {{user}} --ssh-password '{{password}}'
结束语
随着云计算和 DevOps 技术的发展,有人断言系统管理员和 DBA 会面临失业,未来的云计算公司和数据库公司只会雇佣少数系统管理员和 DBA 管理他们的 IT 基础设施和数据库。虽然作者不大赞成“机器替代人工”这一观点,但提早下手,学点东西总不是坏事,所谓技多不压身嘛。
Chef 能够实现服务器配置的自动化,在 DevOps 运动中占有重要的位置。本文通过一个配置 Web 服务器的例子,一步步引导大家如何使用 Chef。希望您读完本文,能编写出自己的第一个“烹饪手册”。
参考资料
学习
- Chef 官网,访问 Chef 官网了解更多关于 Chef 的信息。
- Chef 教程,Chef 官网提供的入门教程,精练实用。
- Chef 基本概念,有关 Chef 基本概念的视频,需翻墙。
- Chef Development Kit,Chef 开发者工具。
- Chef 官网提供的托管服务,方便大家学习 Chef,也可以将自己的脚本放在上面,用来配置服务器。
- Chef 超市,在上面可以找到很多有用的脚本。
- developerWorks 云计算站点 提供了有关云计算的更新资源,包括
- 云计算 简介。
- 更新的 技术文章和教程,以及网络广播,让您的开发变得轻松,专家研讨会和录制会议 帮助您成为高效的云开发人员。
- 连接转为云计算设计的 IBM 产品下载和信息。
- 关于 社区最新话题 的活动聚合。