课程索引难度指数:4星(5星满分5星)技术指标:5星(5星满分5星)理论指数:3星(5星满分5星)5星)适合人群:自动化运维&初中级运维共享目录1.1添加额外源11.2部署一个Node.js应用41.3运行一个Node.js应用61.4Node.js应用服务器总结。71.5问题:7接下来我们要在我们的CentOS6.x服务器上配置Nodejs,启动一个简单的nodejs实例,这个服务器的架构非常简单。要开始,首先创建一个playbook文件,我们尽量保持简单。----hosts:alltasks:定义一些运行这个playbook的主机,然后在下面列出一系列任务。1.1添加附加源在准备申请服务器时,为了保证指定的软件包可用或者是最新版本,管理员往往会先添加附加源。在下面的脚本中,我们要添加EPEL和Remi源,以便我们可以获得类似node.js的包。如果用shell脚本来处理,则如下。#导入RemiGPG密钥–请参阅:http://rpms.famillecollet.com/RPM-GPG-KEY-remiwgethttp://rpms.famillecollet.com/RPM-GPG-KEY-remi\-O/etc/pki/rpm-gpg/RPM-GPG-KEY-remirpm--import/etc/pki/rpm-gpg/RPM-GPG-KEY-remi#安装Remirepo,里面包含很多PHP扩展rpm-Uvh--quiet\http://rpms.famillecollet.com/enterprise/remi-release-6.rpm#安装EPEL源码yuminstallepel-release#安装Node.js(npm+及其依赖).yum--enablerepo=epelinstallnpm这个shell脚本用来导入EPEL和Remi的GPG密钥,然后添加此源,***安装Nodejs。这对于简单的部署来说很好,但是运行这么多命令会很笨拙,而且如果你的连接意外断开,你的脚本也会停止。如果您的脚本此时刚刚准备好完成怎么办?提示:如果要跳过指定步骤,可以跳过添加GPG密钥的步骤,在运行命令时加上--nogpgcheck即可。或者在Ansible中,在yum模块中将disable_gpg_check参数设置为yes,但最后添加GPG密钥。使用GPG,你可以知道包的作者是谁,包是否被修改过。除非您知道自己在做什么,否则不要禁用GPG检查。Ansible使事情变得更加健壮。以下使用Ansible的示例更加详细。它与上面的shell脚本具有相同的功能,但更容易理解,也更有条理。下面使用Ansible变量和其他有用的功能。按照上面的剧本,我们继续往下写。任务:-名称:ImportRemiGPGkeyrpm_key:“key={{item}}state=present”with_items:-“http://rpms.famillecollet.com/RPM-GPG-KEY-remi”-name:InstallRemirepo.command:“rpm-Uvh--force{{item.href}}creates={{item.creates}}"with_items:-href:"http://rpms.famillecollet.com/enterprise/remi-release-6.rpm"创建:"/etc/yum.repos.d/remi.repo"-name:Installepelrepoyum:name=epel-releasestate=present-name:Stopthefirewallservice:name=iptablesstate=stopped-name:InstallNodeJSandnpmyum:name=npmstate=presenablerepo=epel我们看到了我们来看看具体步骤。rpm_key是一个Ansible模块,用于从RPM数据库中添加或删除GPG密钥。我们正在从Remi的源导入密钥。由于Ansible没有rpm命令,我们使用command模块来使用rpm命令,这样我们可以做另外两件事。a)使用creatse参数告诉Ansible什么时候不运行这个命令。在这个例子中,我们告诉Ansible在成功执行命令后将创建哪些文件。当这个文件存在时,这个命令将不会运行。b)使用with_items为创建检查定义URL和文件。yum负责安装EPEL源。因为我们要用这台服务器做测试,所以我们使用service模块关闭系统防火墙,防止它干扰我们的测试。yum安装Node.js(npm,同时安装Node的包管理器),我们使用enablerepo指定在EPEL源中搜索,当然你也可以使用disablerepo指定不使用那个源(repository).因为现在安装了npm,我们使用Ansible的npm模块永远安装Node.JS工具,永远运行我们的app,设置global为yes,告诉NPM在/usr/lib/node_modules安装模块,然后所有用户就准备好了使用。我们已经有了一个Node.js应用程序服务器,让我们部署一个简单的Node.js应用程序来响应端口80上的HTTP请求1.2部署一个Node.js应用程序这一步是在我们的服务器上部署一个简单的Node.js应用程序。首先,我们通过在与上面的ymal文件相同的路径下创建一个新文件夹来创建一个简单的Node.js应用程序。然后新建一个文件,app.js,在这个文件夹下,编辑下面的文件//app.js//加载express模块??.varexpress=require('express'),app=express.createServer();//responsetothe"HelloWorld"requestis'HelloWorld'.app.get('/',function(req,res){res.send('HelloWorld!Yunzhonge');});//像真人一样监听80端口服务器app.listen(80);console.log('Expressserverstartedsuccessfully.')不要担心node.js语法和我们的案例。我们需要一个快速部署的案例,这个案例可以用Python、Perl、Java、PHP或者其他编程语言来写,但是因为Node是一门非常简单的语言,运行一个简单的轻量级环境,是测试你的服务器的一个很好的语言.因为这个小应用程序依赖于Express(Node的一个简单的HTTP框架),我们还需要通过package.json文件告诉NPM它的依赖关系,该文件位于与app.js相同的路径中。{"name":"examplenodeapp","description":"ExampleExpressNode.jsapp.","author":"yunzhonghe","dependencies":{"express":"3.x.x"},"engine":"node>=0.10.6"}然后在你的playbook中添加如下内容,将整个app复制到这个服务器上,让npm下载依赖的东西,(这里表示。)-name:EnsureNode.jsappfolderexists.file:"path={{node_apps_location}}state=directory"-name:CopyexampleNode.jsapptoserver.copy:"src=appdest={{node_apps_location}}"-name:Installappdependenciesdefinedinpackage.json.npm:"path={{node_apps_location}}/app"首先我们使用文件模块来确保我们安装的应用程序目录存在。{{node_apps_location}}变量可以在剧本顶部的vars部分中定义。当然也可以在inevntory中定义,也可以在运行ansible-playbook的时候定义。我们使用Ansible的复制模块将整个app文件夹复制到测试服务器。copy模块可以智能区分单个文件和包含文件的目录,然后在目录中递归,就像rsync或scp一样。Ansible的复制模块适用于单个文件或少量文件,但如果您要复制大量文件并嵌套多级目录,则复制模块无法胜任。在这种情况下,如果你想复制整个目录,你最好考虑使用同步模块,如果你想复制一个存档然后展开它,你最好使用unarchive模块。在第三步中,我们使用npm模块,这次除了应用程序的路径之外没有其他参数。这会告诉NPM解析package.json文件并确保所有依赖项都存在。大功告成,最后一步就是启动这个app1.3运行一个Node.jsapp我们现在使用forever来启动这个app。-名称:运行节点检查列表}}/app/app.js')==-1"在这个剧本中,我们做了两件新事。register会创建一个新变量forever_list,以便在下一个任务中使用它来确定是否运行下一个命令。寄存器用于保存命令的输出,包括标准输出和错误输出,然后赋值给一个变量名。changed_when告诉Ansible此播放何时会导致更改。在这里,foreverlist命令永远不会导致服务器更改,因为我们指定了false。第二个游戏实际上是使用forever启动应用程序。我们可以通过调用node{{node_apps_location}}/app/app.js来启动app,但是这种方式比较难控制。Forever跟踪它管理的Node应用程序,然后我们使用Forever的列表选项打印正在运行的应用程序列表。当我们第一次运行这个playbook的时候,这个list明明是空的,但是判断为空之后就会运行。如果应用程序正在运行,我们将不会启动另一个实例。为了避免这种情况,我们使用when语句,指定当app的路径不在forever列表的输出信息中时,我们启动app。1.4Node.js应用服务器总结。此时,您已经完成了剧本并安装了一个简单的Node.js应用程序,该应用程序响应端口80上的HTTP请求。要在服务器上运行此剧本,请使用以下命令,通过命令ansible-playbook传递node_apps_location变量--extra-vars="node_apps_location=/usr/local/opt/node"当服务器完成配置和部署服务器时,在浏览器中指定测试服务器的主机名来查看效果很简单,但是它是有效的。我们在一个不到50行的YMAL文件中配置了一个Nodejs应用服务器。这就是结局。非常感谢您的关注。1.5问题问题1:我在给100台服务器部署nodejsapp的时候,有20台服务器中断了,我会重新执行。流程是什么?之前安装过的软件包会重新配置是重新执行还是跳过?请回答问题:Ansible本身具有幂等特性,可以有效保证所有操作的安全性和可靠性。如果执行失败,会自动在home目录下生成对应的errorserver列表,再次通过--limit有针对性的完成剩余工作。问题二:英雄的nodejs是通过工具部署的吗?npm太复杂了。npm的配置是一次性的。或者npm各有利弊,看业务。问题三:--extra-vars=企业应用多吗?答:很多,至少在我们的工作中已经用到了。大家应该在前几期的分享中也看到这个参数应用的比较多。但是官网是一下介绍的。我还是建议大家多用。问题四:我通过ansible执行任务时,会出现任务卡很久的原因。哪些地方需要检查?答:很多朋友都遇到过这个问题,一直在问,根据个人经验建议从以下几个方面排查:确实是当前命令执行时间不长,pong检测到服务器存活,部分命令需要需要连接外网下载更新,检查网络带宽需要很长时间。无解,缩短/etc/ansible/ansible.cfg中操作的执行时间,等待最后尝试结束
