版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
简 本书的目 关于 读者 前提条 如何阅读本 第一部分的结构 第二部分的结构 服务器环境组 Ubuntu12.04 Ruby 为什么使用这些组 沿用你的组 Chef简 引 自动操 自动配置所用的工 快速上手-5分钟架设服务 组 步 下一 ChefSolo项目详 创建项 简单的Chef食 克隆Redis配 Redis配方的结 简单的节点定 Redis节 节点定义文件 简单的Chef角 新建角色定义文 默认属 json_class和 把节点定义应用到VPS 开通 在服务器上安装 修改后再应 小 Rails服务器模 示例仓 使用Berkshelf管理食 Berkshelf如何结合KnifeSolo使 开始使用 服务器基本设 常用 如果登入生产环境,显示一个文本队 Railsgem的依赖 用 用 安 安全提 安全误 基本措 强化 无值守升 自动更新时 .................................................. UFW(简易 把示例模板应用到VPS 前提条 步 检查设置是否正 安装 rbenv和 rbenv的工作机 rbenv食 设置放在哪 定 设置很重 系统 端 可用空 防止警报邮件过 使用Nginx为网页界面提供服 Monit? Upstart服 复刻我的Monit设 为什么要定制自己的Monit设置 详细步 Nginx配 在哪个阶段设置虚拟主 安 psql终端 新建数据 把用户添加到数据 列出所有数据库及其权 认证设 数据导入和导 Monit设 安 新建数据 认证设 数据导入和导 Monit设 数据库管理工 安 MongoDB终 数据导入和导 安 安 限制内存用 Monit设 安 安 Monit设 在Vagrant中测 安装 直接通过SSH登 测试Chef食 用户,sudo和root权 端口转 第一部分结 总 本书会系统性的介绍从零开始架设快速搭建多个服务使用Capistrano可靠地部使用自动化工具处理琐碎的任如果你花了很多钱把应用程序部署在Heroku上,使用本书介绍的工具,可以将其迁移到VPS上如果应用程序已经运行在VPS本,使用本书提供的模板可以让部署的过程更可靠。VPS就像部署到Heoku一样顺手,甚至有时还更简单。如果你想达到和我相同的技术水平,阅读本书吧,可以节省你很多时间。目前我在伦敦的Campus中工作,开发Web应用程序已有八年,过去几年专注Rubyon程序的开发和部署。我还是一位顾问,主要为初创公司服务,有时也会开发一些自己的项目我是一家康体初创公司的技术这家公司为英国很多家公众休闲运营商制定时间表还得到了一家国际公司的赞助,开发了一款iOS应用SpeedoFi,为游泳者提供服务。除了这些基础业务之外,我还负责提高性能,把每分钟10次请求提升到每秒10次请求,有时还会本向RubyonRails应用程序的开发者,有机会参与或完全负责基础设施的架构和部署都能够为你提供一些有用的技术。PAGE2PAGE21.0简本书的读者应该已经精通RubyonRails开发还要掌握一些基本的Unix命令行操作,详细说来,你应该能够使用SSH连接到服务在命令行中进行文件操作(cd,ls,dir,mv和rm等了解基本的Web架构。例如,服务器是什么,如何配置DNS如果熟悉Web服务器结构就更好了,例如,虚拟主机文件的存放位置,权限等本书的内容围绕示例代码展开,这份代码可以到上获取。每一章将说明示例代码的一个部分,介绍其工作方式及使用方法。从第6我会给出关键的操作命令,但不会包含简单地操作,例如cdmvyyyetc所以,阅读本书时最好结合示例代码。虽然每一章都可以独立阅读,不看完整个示例代码也能理解,但建议你花点时间浏览整个示例代码,了解每个文件的作用。阅读每一章时,请打开示例代码仓库中对应的文件,确保真的理解了再接着往下读你没必要在自己的服务器上完用这份示例代码不过还是可以作为模板来用读完本书后就能够创建符合自己需求的模板了。第一部分的结构第2章和第3章介绍本书使用的服务器环境组件,以及Chef的用法和服务器配置第4章适合那些暂时不想阅读使用手册的人,这一章介绍如何通过示例代码仓库中的配置,使用最少令架设可以正常运行的服务器。第5章通过传统的逐步方式介绍Chef的用法和工作流程。然后,通过配置一个简单的Redis服务器,介绍Chef项目的基本结构,最后再把设置部署到VPS上。第6-12章详细说明本书附带的Rails服务器模板( te介绍这个模板时,我们会涉及到以下话题安装Ruby的最佳方无需人工介入,使用Monit确保一切都运行正安全预防措使用UFW管理管理用户和公创建、填充数据库(使用你选择的工具安装Redis,以及常见的问安装第13章介绍如何在本地使用Vagrant测试Chef部署是否正确第二部分的结构第二部分,我们会介绍部署方式(而不是配置包括以下话题Capistrano和Chef各自的作创建简单、模块化的Capistrano配避免$PATH处理Virtualhost文管理SSL设置不下线部署及常见问日志分在不同的环境之间数据使用Whenever管理时钟守护作使用Sidekiq管理作读完本书,你将牢固地掌握配置服务器和部署Rails应用程序的方法多客户中最常使用的组合。这种组合方式仅为本书演示之用。如果没发现你喜欢使用的组件也不用伤心,常规的原则都是通用的如果你知道如何安装这些组件,或者能找到安装说明,可以直接阅读介绍如何使用Chef自动安装的部分。Ubuntu12.04过去四到五年,Ubuntu持续发展,已经成为服务器环境常用的Linux版本。我选择Ubuntu最拥有如此多的用户意味着,99%的情况下,你不会是第一个遇到某个问题的人,在Stack中搜索一下,就能为解决问题指明方向剩下的1%,也可以向友好、的社区寻求帮助Nginx是一个Web服务器,也是一个反向,性能极高且内存占用少Nginx的一个重要优势是它的驱动架构,即便在较高的负载下,其内存用量也是完全可以预测的。这种特性特别适合那些先在小型VPS上测试的项目,随着发展到大型的服务器上。Unicorn是Rack程序(Rails就是其中之一)的Web(HTTP)服务器如果你想更深入地了解Unicorn的内部架构,强烈推荐你阅读的这篇文章,看一下为什么从Mongrel迁移到了Unicorn。服务器收到请求时,先由Nginx处理,然后传给运行Rails程序的Unicorn,再返回响应Unicorn和Passenger各自的优势方式的不同点,请阅读EngineYard博客中的这篇文章 /2012/passenger-vs-unicornPAGE5PAGE52.0服务器环境组PostgreSQL和MySQL是传统的关系型数据库。MySQL应该是最有名的而且由于它具有tracerecord功能,是很多大型组织的选择。PostgreSQL逐渐成为使用关系型数据库的Rails程序的默认数据库部分原因是PostgreSQL是Heroku默认支持的数据库。我喜欢使用PostgreSQL,主要是因为它内建支持JSON格式,不断整合传统的关系型数据库和NoSQL数据库(例如MongoDB)的优势。MongoDB是非关系型数据库,特别适合大量非结构化数据都使用PostgeSQ,我对PostgeSQL也是最熟悉的,所以本书的示例主要针对PostgeSQ。Ruby本书覆盖了Ruy1.9.x和Ruy2.0.能够在更奇特的Ruy变种(例如JRu)中使用,但我对这些变种没什么经验,所以不会直接介绍。在生产服务器上,我喜欢用rbenv安装、管理不同的Ruby版本,主要是因为我觉得rbenv操作简单、易于理解(因此容易解决出现的问题,而rvm太复杂。我曾经在服务器上安装过rbenv和rvmrbenv的问题要比rvm少得多。这并不是贬低rvm开发环境中我就只使用rvm。Redis是一个键值对系统,速度很快,非常适用于缓存和限制API请求Redis有一些坑,比如,当达到最大内存使用限制时的诡异表现。我会在设置Redis一节中再做说明。Memcached和Redis的功能类似,但数据存在内存中(重启后Memcached保存的所有数据都会消失。Memcached适合用来缓存,而且和Redis一样,安装和都很简单。中立。还有很多好的组件组合方式,大多都可以使用本书介绍的技术。开发新项目时我会使用这些组件,然后再挑选一个合适的数据库。希望这些组件也能对你有所帮助。如果你使用的组件我没有提到,也不用担心。本书的目的是向你展示,使用Chef自动配置Rails所写Chef食谱。配置一台新服务器“最简单”的方法是,从Linode或DigitalOcean一个VPS,通过SSH登入,然后开始使用apt-get安装所需的代码包,打开Vim修改设置文件,再添加一些代码包的源用来更需要添加新东西时,再次通过SSH到的所有命令记录在文本文件或中,以备后用。这种方式主要的缺点有很难完整记录所做过的操作。最理想的情况下,文本文件也不可能记录所有令。而且只有当我们需要配置一台新服务器时才发现,其实这些命令并不能让服务器正常运行。(因此耗时令。这是一项重复且单调的工作,经常需要工程师来完成,把这些时间用来开发产品岂不更好。不具扩放性。如果只有一台服务器,让工程师输入一串命令还好,试想一下,如果有五到六台服务器,工程师会的。本节以及本书的目的,是要用自动操作代替手动操作。一般来说,在部署和管理服务器的过程中,如果一年要重复超过一到两次的耗时操作,我都会将其自动化。自动操作关注的是具体方式而不是某种特定的工具如果某项任务需要运行多个命令或者每月要多次通过SSH连接服务器,或许你应该停下来想“我能否把这些操作自动化”(stagingenvionmen,让测试新的部署环境变得更简单、更高效,因此也就减少了程序下线时间。把生产环境的数据库自动到开发环境或交付准备环境,可以让开发者在测试中使用更数据。这让开发时的测试变得更有意义,能提升工作效率,降低成本。而且自动化操作往往比你想的要简单。Chef用来自动配置,Capistrano用来自动执行部署过程以及其他与生产环境和交付准备环境之间的交互。掌握这两个工具后,你就会发现,再自动化其他任务,会达到事半功倍的效果。Chef简 Chef和ChefChef是一个自动化工具,由Opscode开发,使用RubyDSL( SpecificLanguage,领域特定语言)以一种可重复使用的格式表示配置服务器所需令。服务器的配置可以分成很多步骤,在Chef中,把各个步骤称为“角色(role。例如,可以分别为Rails程序服务器和数据库服务器编写角色定义,然后将二者运用在某个特定的服务器上。Chef经常运行在服务器集群的枢纽,统筹安排其他服务器的配置。服务器中的Chef知道其他服务器各自所扮演的角色,如果某个角色的定义有所更新,变动会自动应用到所有的服务器。管理十几台或者几百台服务器时使用这种模式太方便了如果理1-10台服务器就显得复了。幸好,还可以在单机模式下使用Chef(ChefSol。在这种模式下,我们在本地开发平台上定义服务器的各种角色和设置,然后根据需要手动应用这些设置。用单机模式成功架设了10台相关联的服务器。如果项目不断扩大也不用担心,使用ChefSolo制定的自动化配置大多数都可以在Chef中使用Knife和KnifeKnife是一个命令行工具,为本地开发环境中的Chef仓库和服务器之间提供交互接口一般情况下,服务器必须是“主(master)Chef服务器。不过KnifeSolo允许在单机模式下使用Chef,可以直接和需要配置的服务器交互。关于KnifeSolo更详细的信息可以阅读其位于 solo在Chef中,安装各组件所需令称为“配方(recipe。例如,可能有一个配方用来安装Ruby,另一个配方用来安装Rails程序常用的gem。相关功能所需的不同配方往往放在一起,组成一个“食(cookbookBerkshelf就像是配方的Bundle。我们先定义好配置需要哪些配方,例如,一个“rben”配方和一个“rails_em_dependencie”配方。就像使用bundleinstall命令获取所有的em依赖件(特定的版本)一样,我们使用Berkshelf获取配置服务器所需的Chef配方(特定的版本。快速上手5本节简单地介绍如何如何使用示例Chef仓库配置服务器。如果你喜欢先自己动手试一下,然后再作的快速参考手册。Ruby1.9.3+(版本可做适当调整安装工 geminstallknife-solo如果使用rvm,为了避免,建议你在一个全新的gemset中执行上述命令设置用先克隆示例代码仓库 git :TalkingQuickly/rails-server-tem然后需要设置用户的密码,把data_bags/users文件夹中的deploy.json.example重命名deploy.json执行下面令为部署时使用的用户生成 opensslpasswd-1"把上述命令的输出结果填入deploy.json中。然后把SSH公钥(cat∼/.ssh/id_rsa.pub)ssh_keys数组中食Berkshelf就是Chef的Bundler。执行下面令,获取所需的食谱和依赖件快速上手-5分钟架设服务 mkdir berks设置这一步在所有运行Ubuntu12.04的VPS上应该都能正常进行。我在Linode、Rackspace和DigitalOcean上测试过。如果只想做个试验,我推荐使用DigitalOcea。真正运行程序的话,才是王道,我推荐使用Linode。VPS正常运行之后,把SSH公钥过去 ssh-copy-id配置服务先在服务器上安装 knifesoloprepare上述命令会生成nodes/yourserverip.json文件。把nodes/rails_postgres_redis.json.example文件中的内容进去,再修改monit的用户名和。执行前面用过的opensslpasswd-1" intextpassword"命令为PostgreSQL生成,同样填入上然后执行 knifesolocook坐等。这个过程要花点儿时间。执行完后,就得到了一个安装好Rails、PostgreSQL和Redis的服务现在你已经架设好了一台服务器,运行着Nginx、PostgreSQL和Redis。本书的第二部分会介绍如何使用Capistrano把程序部署到这个服务器上。第一部分剩下的章节会向你介绍上述各步是如何工作的,以及如何根据需求定制配置或完全自己编写配置。本章我们会创建一个简单的Chef项目,顺便介绍对应于文件结构的Chef术语首先,我们要安装创建和管理Chef项目所需的工具新建一个文件夹用来保存Chef项目的内容,然后进入该文件夹 mkdir cd如果在本地开发环境中使用的是rvm,建议新建一个 rvmgemsetcreate再创建.rvmrc文件,以后进入这个文件夹就会自动切换到这个 rvm--rvmrc--createruby-上述命令中的ruby-version就是你使用的Ruby版本号。我一般使用Ruby1.9.3,不过使用.0应该也没问题如果不用rvm就接着往下读。你可能会看到由于em执行下面令安装Chef及相关的工具: geminstallknife-solo上述命令会安装che、knife-sol、berkshel、net-ssh(稍后会介绍为何要安装net-ssh)及其他依赖件。术配方定义安装单个组件(例如Ruby,mysql-server,Monit等)所需令5.0ChefSolo项目详食谱相关的配方集合,例如mysql”食谱中包含MySQL服务器配方和MySQL客户端配方节点要配置的服务器角色一系列配方的组合,应用到节点上时,就称为一个角色例如“PostgresServer”角色可能会包含安装postgres-server的配方,安装、设置的操作,以及安装合适的服务器工具的操作。角色在某种程度上可以视为Ruby中的“混入(mixin。角色创建的是可重用的操作,能应用到多数据包(data配方所用的元数据,保存为JSON格式文件。例如,要创建的用户列表,以及相应的公钥Chef仓库(chef一系列节点和角色定义创建仓所需的工具安装好后,就可以使用knife创建空ChefSolo项目了。执行下令1knifesoloinit应该会看到类似下面的输出1WARNING:Noknifeconfigurationfile2Creating3Creatingknife.rbin4CreatingSettingup然后进入这个新创建的my_first_chef_repo文件夹,会看到如下所示的文件结构1-2-3-4-5-6-7-8-Knife是个命令行工具,可以服务器上的Chef交互KnifeSolo添加了额外令,可以在本地开发设备上直接和要配置的服务器交互(而不用通Chef服务器中转knife.rb中包含针对我们这个仓库的Knife设置。这个文件在使用Chef服务器时更有用,并不太符合我们使用的单机模式,但却是Knife的主要设置(也是唯一的设置文件。Knife的全部设置选项可以在http: /config_rb_knife.html中查看。 食谱和节点定义的位置node_path:相对仓库 的路径,指定节点定义的位role_path:相对仓库 的路径,指定角色定义的位 的路径,指定数据包的位置cookbooks和site_cookbooks的不cookbooks文件夹用来存放使Berkshelf安装的他人编写的食谱(稍后介绍安装方法site_-cookbooks文件夹用来存放自己编写的食谱。接下来我们会详细介绍单个配方简单的Chef前面介绍过,Chef食谱由一系列针对某个代码包的配方组成。这一节我们要编写一个Chef食谱,只包含一个配方,安装并配置Redi。克隆Redis首先,把下面的仓库克隆到前一章所创项目的cookbooks文件夹中/TalkingQuickly/redis-Redis我们这个Redis食谱的metadata.rb文件内容如下:1"redis-2"Ben34"Installsredisfromrwky's56 recipe"redis-tlq","Installs8 supportssupports这行指定这个食谱支持的操作系统。这个设置很重要,因为我们这个简单的食谱只支持Ubunt,会用到一些只有Ubuntu才支持令。较复杂的食谱可能会支持多种操作系统,这时需要检测命令在特定系统中是否可用。version和recipe这两行指定配方的名称和版本号。使用Berkshelf时,这两行是关键的设置Berkshelf会查看metadata.rb文件,确认要使用的食谱中是否有名称匹配的配方,以及相应的版本还有一个选项我们没设置,但后面会经常用到,即depends。depends指定食谱要依赖的其他食谱例如,如果我们编写的食谱中要从源码编译安装RuOpscode了一个名为“build-essentia”的食谱,可以在大多数系统中安装编译工具集。如果要在食谱中指定依赖件,可以加入下面这行设置:5.1简单的Chef食depends"build-Chefdefault指定要用哪个配方,就会使用这个默认配方。cookbooks/redis-tlq/recipes/default.rb文件的内容开头如下#addthestableredisppaastheversionincluded#theUbunturepositoriesisgenerallyquiteoutofbash'addingstableredisppa'usercode<<-add-apt-repositoryapt-get从上面的代码可以看出Chef的强大之处。添加仓库使用令和直接在SSH中使用的标准s命以bash开头的代码告诉Chef,其中包含令是在bash中执行的。随后的文本会在配方执行时显后面跟着一个Ruy代码块代码块的第一行代码说明后面令应该“oot这个用户去执行。code<<-EOC的意思是,其后令以指定的用户在bash中执行,直到EOC为止。这是纯粹的Ruy句法,很多人可能不熟悉,如果你已经掌握了如何使用<<-构建多行字符串,请EOC在这里没有什么特殊意义,在Ruy<<-SOMETHING是随后的所有字符都应该被视作单个字符串字面量,直到SOMETHING为止。在这串s命令中,我们本可以使用apt-getinstallredis-server安装redis-server代码包的,不过Chef提供了一种更好的安装方式。继续看default.rb的代码,会看到:#installtheredisserverpackage'redis-上述代码的意思是,Chef首先会使用操作系统的包管理工具检查是否安装了edis-serer代码包,如果没有,那就安装。上述操作只是安装了Redis,我们还要对其进行一些自定义设置,再添加初始化用于启动、停止Redis服务器,这就轮到“模板(temte)出场了。模继续往下看default.rb的内容#Copyourcustomredisconfigurationtemte"/etc/redis/redis.conf"ownergroupmodesource这段代码的作用如下在redis/tem te/default/文件夹中寻找文件redis.conf.erb(redis是食谱的名称,后面会解析这个文件中的所有erb代码然后把文件到节点上存放位置为/etc/redis/redis.conf。在5.3节中我会介绍erb的强大作用把这个文件的拥有者设为root用户组的root,权限为关于模板文件夹的说因为模板的路径中使用default,可能让你有点困惑,会误以为这个default文件夹是对应dedault配方的,其实不然 tes文件夹中的子文件夹对应的是所安装的操作系统。如果使用的是Ubuntu12.04,上面 te代码块就会在下面的路径中按顺序寻找redis.conf.erb文件temtes/ubuntu-temtem使用default文件夹。属配方可以使用属性(attribute)进行定制。属性可以在多个地方设定,包括节点定义(参见角色定义(参见食谱默认值(如下所示一般情况下,在食谱中会为属性指定默认值,如果需要,可以覆盖默认值下面用到的node属性会在5.2节中介绍,现在你只需要知道,node中包含很多属性,以Ruby的形式存在,可以设置自定义的值在上面使用的redis.config.erb模板中,有这么一段代码<%unlessnode[:redis]&&node[:redis][:dont_bind] bind <%end在这个Redis设置文件中,首先检查节点中是否定义了redis子元素。这么做,如果节点没有redis键指定值的话,查找dont_bind键时,配方不会抛出“undefinedmethod[]fornilclass”异常除非键存在,且为真值(还记得吗,这些代码就是Ruby,所以只要不是0或者false,就代表真值,否则就执行bind这行代码。我们之所以如此谨慎,包含这行代码,是为了不让Redis接收外部的未验证连接。在没有的服务器上,这么做有很严重的安全隐患。食谱属性的默认动就可使用。属性的默认值在attributes/default.rb文件中定义。你会发现,定义属性默认值的格式和节点及这个Redis食谱只有一个属性,所以对应的默认属性文件也很简单1#2#Author::Ben3#CookbookName::redis-4#Attributes::5#67#whetheretopreventredisfrombindingto8default[:redis][:dont_bind]=在这种情况下,如果没有覆盖默认值,下面这1default[:redis][:dont_bind]=就会把默认的x应用到食谱1除非默认值被覆盖了。关于属性的说明,请阅读上的文档 不过我建议先阅读后面的章节,再看这份文档下一节,我们要介绍节点定义的作用,以及如何编写节点表示单台服务器(例如我们要配置的一台VPS)本节我们要看一下节点定义文件中有什么内容,然后新建一个节点定义文件,在这个Redis示例项目中使用。Redis节在node文件夹中新建文件example-redis-server.json,写入如下内容 "redis":"dont_bind": ["role[redis- 可以看出,这是标准的JSON对象,包含两个键。我们先来看run_list运行列在Chefrun_list运行列表中可以包含很多角色和配方,角色使用下面的格式指定配方使用下面的格式指定异常。本例中我们只会应用一个角色,即redis-server,但在实际使用中往往要用到多个角色。 pany-server的角色,定义了某公司服务器通用的属性。5.25.2简单的节点定使用属性定制配我们在5.1节,属性可以用来定制食谱的行为表现。 "redis":"dont_bind": 这部分定义了节点的“属性每个配方都可以调用这些属性定制执行的内容在这个例子中,node[:redis]['dont_bind']的默认值(false,在食谱的attributes/default.rb文件中定义,会被覆盖为新的值true。我们可以扩展这个食谱的功能,编写更细致的代码。例如,可以把redis.conf.erb文件修改成<%ifnode[:redis]<%if(interface=bind<%=interface<%else bind <%end <%else bind <%end当我们在节点定义文件中写入下面的代码后 "redis": "interface": 会和前面一样检查redis键是否存在如果存在就子键interface的值。如果定义了interface键,就把Redis绑定到指定的接口(在上例中接口地址是。否则就绑定到地址这就体现了Chef服务器的配置各异,在不同的节点上可以通过属性定制。特定节点使用的所有属性都在同一个文件中,这样就能知道单个节点的具体设置了5.25.2简单的节点定节点定义文件5.4节会详细说明节点定义文件的生成和命名简单来说,节点定义文件应该保存在nodes文件夹中,根据要连接的主机名来命名。例如,如果要执行sshroot@my_shiny_server.co.uk命令登入要配置的服务器,那么节点定义文件应该命名为my_shiny_server.co.uk.jso。这么做可以极大地方便操作,当节点定义文件数量增多时,方便管理,而且KnifeSolo会根据主机名自动选择要使用的文件。简单的Chef角色定义了一个服务器提供特定功能所需安装的组件。这里我们要定义一个简单的Redis服务器角色,会用到Redis食谱及5.1节和5.2节中的配方。下面显示的是Redis角色定义文件roles/redis-server.json中的内容(JSON格式 "name":"redis-"description":"Redis"default_attributes":"redis":"dont_bind": "json_class":"run_list":"redis-"monit_configs-tlq::redis- "chef_type": 可以看出,这些内容和前一章中的节点定义很像首先指定角色的名字(redis-server然后是一句简单的文本,描述这个角色的作用。当Chef在运行列表中见到role[redis-server]时,就会寻找名为“redis-server”的角色。寻找的范围是knife.rb中role_path对应文件夹中的所有JSON文件。默认属性的作用是,当节点定义文件中没有指定值时,属性的值是什么以前面的redis-server配方为例Redis服务器从来不会绑定到,那么在redis-文件的default_attributes键中就可以这么写简单的Chef角 "default_attributes": redis: "dont_bind": 这时,如果节点定义中没有为don't_bind键指定值,就默认为true。我强烈不推荐使用这个默认值,如果没有设置好,这么做很。这里只做演示之用。json_class和这两个键指定文件的定义类型,用来区分角色和配方,特别是当角色和配方名字相同时特别有用和节点定义一样,run_list是一个数组,包含一系列配方或其他角色。如果节点中定义了这个角色,就会执行这个列表。我们可以看到熟悉的recipe[recipe_name]句法,还有指定食谱中某个配方的句法,如下 "recipe[monit_configs-tlq::redis-这行代码的意思是,有个名为monit_configs-tlq的食谱,其中有一个配方,名为edis-sere,我们要使用的就是这个配方。如果没有使用::指定配方,就会使用默认的配方。所以,如果写成: 就等同于 现在我们已经对简单的Chef仓库有了一定了解,知道如何编写基本的角色定义和配方。接下来,我们要把节点定义应用到VPS上。把节点定义应用到VPS本节,我们要把写好的Redis食谱应用到VPS上重要提示:这个Redis设置只是为了简单的说明如何使用Che,实际使用时,在这样的系统中还要6的组件才才适合在生产环境中使用。开通先在你最爱的云服务提供商那里开通VPS我喜欢在DigitalOcean和Linode上测试。建议使Ubuntu12.04安装好系统后,把公钥过去 ssh-copy-id在服务器上安装然后进入食谱的根(my_first_chef_repo以前需要手动在服务器上安装Che,现在有了KnifeSol,就不用我们费心了。使用下面令在服务器上安装Che: knifesoloprepare上述命令的作用如下在nodes文件夹中新建文件通过SSH登入服务检测操作系统的类安装正确的Chef版接下来,在yourserverip.json文件中输入下面的内容(5.2节编写5.4把节点定义应用到VPS1{2"redis":3"dont_bind":456[7"role[redis-8]9}应用这个配方很简单,只需输入以下命令 knifesolocook这个cook命令的作用如下通过SSH登入服务把本地的配方文件到服务应用配方,并显示输出结如果通过SSH登入服务器,可以使用下面令验证是否安装了redis-server包 dpkg-lredis-如果执cat/etc/redis/redis.conf命令查看设置文件,会发现5.1节中的定义是一致的,也就 bind这行设置的出现反应了节点定义文件中的dont_bind:false起作用了到目前为止我们只是证明了Chef可以定义配置新服务器时的常规步骤,使用的是易于阅读的文件格式。Chef真正强大之处在于,能修改服务器的设置假如一开始,和前面的设置一样,dont_bind为false。但后来发现,需要和其他的服务器这Redis,也就是要允许来自外部的连接修改yourserverip.json文件,把dont_bind设为1{2"redis":3"dont_bind":456[7"role[redis-8]9}保存文件,执行下面令,把节点定义再次应用服务器上 knifesolocook从上述命令的输出中可以看到,Chef检测到init.d中的Redis没有变化,但分析时,发现有改动,然后进行了更新,并把修改前后的对比显示出来命令执行完毕后,如果通过SSH登入服务器,检查redis.conf文件,会发现bind被删除了,换成了dont_bind:true。使用Chef可以很容易的定义配置服务器所需令,以及要对文件做的修改如果对这个过程做了修改,Chef这种特性便于修改底层设施的设置,而且还可以一个蓝本,简化服务器扩放和宕机恢复。但要注意,Chef能自动检测到的变动类型有限。Chef虽然可以检测到设置文件(一切使用了模板的文件)的增删,但无法自动处理删除配方和角色。edis-sererChef不会删除设置文件。下一章开始使用本书附带的Rails设置模板这个模板由一些基本的设置组成,用到了本节介绍的原则和方法,可在生产环境中使用Rails前几章我们介绍了如何编写Chef食谱。从这一章开始我将向你展示,使用Chef进行自动操作是多么简单,通过常规的SSH方式进行的操作基本上都可以交给Chef完成,而且还可以重复使用。其实并没有什“魔法Chef只是把通常需要手动执行令揽过来可以在终端完成的操作都可以写成Chef配方,自动执行。我们可以完全掌控服务器组件的配置,同时还可以获得Heoku或其他预先定制好的系统镜像(把复杂的操作过程隐了)带来的操作便利性。除了自己编写Chef配方之外,还有很多由社区成员编写的配方可供使用。有些是主流配方,使用了PostgreSQL或Nginx等,也有的是用来安装和设置WordPress的。这些配方都是很好的资源,但我还是建议首先要自己动手,知道怎么编写配方SSH登入服务器操作了。这么做可能会带来性的,如果下次配置时使用Che,得到的结果会有所差别我们的目标是完全知道如何使用Che,至少拿到几个Chef配方应该知道如何使用,就像自己动手操作一样熟练。熟悉Che食谱的结构后,还能更高效的使用第 食谱。大多数Ruby开发者都,如果遇到问题,直接查看gem的源码要比到StackOverflow Chef也是同样地道理,出现异常,直接看食谱的代码往往都能快速解决问题本书后面的章节会基于一个示例Chef仓库,地址是 这个示例仓库中的代码定义了一个节点,用来配置Rails服务器,可以使用如下的数据库分比较复杂的,由社区成员编写。这个仓库的目的是,演示常规的Chef项目是如何运作的。很多代码借鉴了主流配方,还有一些是针对特殊操作编写的。使用Berkshelf管理食上一节我们,大多数Chef仓库中都混合了自己定制的食谱和社区成员编写的第食谱可以这么说,最终,用于不同项目的Chef仓库数量会不断变少。如果配方写得好,往往可以重复使用,近一步节省时间。几乎所有的RuyDR可重复使用的功能提出取来,制成e,或者直接使用他人开发的e。Ruby开发者在Gemfile中设置要使用哪些gem,以及各自的版本。只要执行bundleinstall命令就可以从远端的源码服务器上所需的gem,在自己的Ruby程序中使用。Bundler会生成一个名为Gemfile.lock的文件,包含所用gem,及精确的版本号。只要Gemfile.lock,我们的同伴在执行bundleinstall命令后就会安装和我们自己版本号一样的gemBerkshelf对Chef食谱的作用也是这样。在Berksfile中定义Chef仓库要使用的食谱,以及各自的版本。然后执行berksinstall命令安装这些食谱。如果食谱在metadata.rb文件的depends中定义了依赖食谱,Berkshelf会负责安装这些依赖食谱。(Berksfile.lock如果要更新食谱,可以执berksupdatecookbook_name命令,Berkshelf会尝试安装指定食谱的最Berkshelf如何结合KnifeSolo使默认情况下,Berkshelf会把食谱安装到/.berkshelf文件夹中。集成KnifeSolo的意思knifesolocook命令后,要自动把食谱到cookbooks文件夹中我们要一点,我们不应该触碰cookbooks文件夹,因为对这个的改动不是永久性的,只要执行knifesolocook命令,所有改动都不见了。所以,针对某个特定仓库的食谱应该存放在site_cookbooks文件夹中。开始使用Berksfile文件的结先克隆示例Chef仓库6.1使用Berkshelf管理食 git /TalkingQuickly/rails-server-tem然后执行cd命令,进入rails-server-tem te文件夹。你会发现,文件夹的结构和第5章的一模打开Berksfile,会看到如下内容 site2cookbook'build-essential',git: /opscode-cookbooks/build-cookbook'sudo',git: /opscode-cookbook'basic-security-tlq',git: :TalkingQuickly/basic_security-cookbook'look-and-feel-tlq',git: :TalkingQuickly/look_and_feel-cookbook'users',git: /opscode-cookbook'chef-solo-search',git: /edelight/chef-solo-第一行,site:opscode是食谱默认的源。Ruby有一gem源索引,Opscode也为食谱建立了一个最简单的食谱定义如下cookbook这行代码的意思是,Berkshelf要在Opscode的索引中寻找名为cookbook_name的食谱,然后把这个食谱和所有的依赖食谱都到本地。我们还可以使用类似Bundler的版本样式,例如cookbook'cookbook_name','~>在这个Berksfile文件中,使用最多的是这种格式cookbook'cookbook_name',git: 这和Bundler还是一样的,允许从指定的Git仓库配方。较之Opscode的索引,我更喜欢使Git仓库。这只是我的个人喜好,因为我一般都会看一下食谱的仓库,了解一下开发者我们还可以提供SHA-1提交哈希值,明确指定要使用的历史版本,例如cookbook“cookbook_name”,git: /user/repo',ref:Berkshelf和Bundler一样强大,值得花点时间阅读文档通过Berksfile安装食要想安装食谱,请在示例仓库的 中执行下面令berks前面我们,如果后续执行了knifesolocook命令,Berkshelf会自动把食谱到cookbooks文cookbooks文件夹中初始化。为此,我们要先让Berkshelf把食谱放入cookbooks文件夹。请执行下berksinstall--path现在打cookbooks文件夹,会看到类5.1节的结构,Berksfile文件中列出的食谱,以及各自的记住,对cookbooks文件夹中食谱所做的改动没有任何实际效果。每次执行knifesolocook命令后,都会刷新这个文件夹中的内容。针对特定仓库的食谱应该放到site_cookbooks文件夹中。接下来的几章会详细介绍如何设置系统的关键功能这一节我们会完成以下任务安装一些常用的包,让操作变得简单添加一个文本队列,在登入生产服务器时显安装Railsgem需要的常用依赖在本书附带的示例仓库中,服务器基本设置主要放server角色中,保存roles/server.json文件里;Rails相关的设置在roles/rails-app.json文件中。本章主要关注的是look_and_feel-tlq食谱,也会涉及到rails_gem_dependencies-tlq食谱有些包值得在所有的服务器上安装说不定什么时候就能给予很大的帮助为此我了一个简单的Chef食谱,名为look_and_feel-tl,其中default.rb文件的第一部分如下所示:#htopisaprettier(butmoreresourceintensive)#topackage4#Vimbecausewe'regoingtowanttoeditRailsconfigpackage7#Becausenoteveryonewillsendusnice.tar.gzpackage代码中的注释基本说明了各个包的作用。安装的都是管理工具,可能会在操作中用到这个文件接下来的部分更有趣7.0服务器基本设#Addabannertosshloginifwe'reintheproductionifnode[:environment]==3 sshd_config=5seds=echos=8 banner_path=seds<<echos<<"Bannertemtebanner_pathownergroupmodesourcebash'Addingvisualflagsforproductionenvironment'usercode<<-#{seds.map{|rx|"sed-i'#{rx}'#{sshd_config}"#{echos.map{|e|%Q{echo"#{e}">>#{sshd_config}}service'ssh'action上述代码首先检查节点中是否定义了如下属性"environment":如果定义了,就引入production_ssh_banner.erb模板,当通过SSH登入时显示一个条幅。在我的示例仓库中,显示的是单词“Production”的ASCII字符画。这么做的目的是减少登入生产环境而误以为是交付准备环境的几率同时多台服务器时经常会发生这种错误,尤其是使用了zsh的主机名自动补全功能。我建议你复刻一份这个配方,根据自己的需求,加入所需的工具和视觉识别文本Railsgem我还会在几乎所有的服务器上安装rails_gem_dependencies-tlq配方。这个配方很简单,就是安Railsgem经常会用到的依赖库。我的配方目前包含以下内容packagepackagepackage'libcurl3-package'libmagickwand-package如果你安装过处理和获取网页相关的e会发现这些包很眼熟这就是我的配方我会在所有需要运行Rails程序的服务器上安装。如果Rails程序需要依赖其他不常用的包,我一般会把这个配方复刻一份,放到site_cookbooks文件夹中,然后添加的包。接下来,我们要在服务器上设置默认的用户和公钥这一节我们要介绍,如何在服务器上自动添加用户和公钥我们会在roles/server.json中用到以下食谱:这两个是第食谱,处理用户管理、生成以及权限控制等常规操作users食谱中有个名为sysadmins的配方,会在sysadmins用户组中新建用户和系统的其他元素不同,用户不在节点或角色定义文件中设置,而使用数据包(databag)文件还记得吗,在第一个ChefSolo项目中就有个名为data_bags的文件夹。如果食谱中要用到大量数打开data_bags/users文件夹中的deploy.json.example文件,会看到如下内容1{2"id":3//generatethiswith:opensslpasswd-1"4"password":5//thebelowshouldcontainalistofsshpublickeyswhich6//beabletologinas7"ssh_keys":89"groups":["s":}其中"id"的值就是用户名,而且要和文件名一致"password"的值并不是用户的纯文本形式(除非使用 管理工具,否则你不应该纯文本形式的而是的哈希值,可以在本地使用下面 用 opensslpasswd-1"生成的哈希值如下 这个哈希就是要为"password"设定的值"ssh_keys"是一个数组包含可登入用户的SSH公钥在本地一般可以使用下面令获取本的公钥:cat请把上述命令的输出以字符串的形式(例如,放在两个双引号中)填入这个数组中groups是由字符串组成的数组,每个元素表示用户所在的用户组最后一行 是字符串,指向用户默认使用的 路径。这个属性可以把默认使用的Bash换Zsh或Fish用户相关的配方应该保存为.json格式文件,放在data_bags/users文件夹中。每个要创建的用户在users食谱中可以设置很多属性,这里我们只的介绍了一部分。食谱README文件中的文添加用户并安装好公钥之后,还要设置哪些用户可以使用sudo命令,以及如何使用。server.json角色文件中的以下部分是设置sudo的:"authorization":"sudo"://everyoneinthegroupsysadmingetssudo"groups"://thedeployuserspecificallygetssudo"users"://whetherauserwithsudorightshastoenter//passwordwhenusing"passwordless": 代码中的注释说明了各项的作用,不过还是要简单说明一下无需输入的sudo。不输入虽然很方便,但如果程序中有,者就能以运行程序的用户执行s命令,既然这个用户执行sudo时无需,就能以root用户执行命令,这会显著增强者的破坏力。如果想使用sudo时不输入,我建议单独创建一个用户,而不要使用运行程序的用户下一节,我们要介绍如何未的连接。这一节,我们会介绍一些基本步骤,可在所有的服务器上使用,未的连接没有万能设根据程序类型、服务器环境以及行业规则的不同,安全需求会不一样没有哪一个服务器安全设置能符合所有人的需求。这一节会介绍我对所有新服务器所做的基本设置,为服务器提供基本的安全防护。我做的设置可能并不完全适用你的程序。符合自己的要求。说到安全很多人立马想到的就是和防止现实中很多安全隐患都是由于没有用经验做法,而不是因为设置错误。具体来说,常见的安全误区有:误区一:不升级gem经常发布安全更新,升级的过程可能有。不升级可能导致致命问题,你至少要订阅一份Railsgem安全公告。如Rails发现了重大,就应该在新版发布后的几小时之内或者几天内升误区二:直接写随着程序的发展,有权获取源代码的人数增多,直接把登陆写入源码的坏处逐渐显现常见的罪魁祸首有:邮件服务错误日志服数据7.2安开发时使用的仓库中不应该含有生产环境的我们可以编写一个初始化确保源码中没有应该把所有保存在单独的设置文件中在生产环境和交付准备环境中单独在介绍使用Capistrano部署时,会说明具体做法。记住,即便现在你把直接写入源码的删掉了,还是能在版本控制系统中查到误区三:重用除了直接写 ,重用也会导致致命问题。我曾经见过直接写入源码的邮件服务器,VPS账户的登 完全一样还有些人在生产环境和交付准备环境中使用相同的,这么做主要有两个坏处能交付准备环境的人,就能生产环境。很多情况下,我们只想给交付准备环境的权限(例如让客户试用,但并不想让他生产环境。很有可能误以为身处交付准备环境,却修改了生产环境的代码。近期犯过这种错误,在生产环境输入rakedb:dro,却以为在交付准备环境中的人都知道,这对血压可不好。这一节我们主要使用的是basic-security-tlq食谱。packages=unattended- 6 packages.each{|name|packagename这段代码会安装三个安全相关的包Fail2Ban是防工具。如果某个IP连接服务次数过多,Fail2Ban就会更新的设置,该IP的后续连接。这么做可以防止者不断地使用用户名和组合Fail2Ban的默认设置可以防止SSH(在下面的内容中你会看到,根本不可能,因为我们完全禁用了SSH验证。Fail2Ban是异常强大的工具,应该在提供公开的服务上部署。可以阅读下面两份文档学习Fail2Ban的用法:https 强化默认情况下,执行sshuser@yourserpip命令后,首先会尝试使用公钥进行验证,在本地电脑中查找密钥(默认保存在∼/.ssh/id_rsa然后再检查服务器上的∼/.ssh/authorised_keys文如果没找到匹配的公钥,就会提示你输入登陆账户的架设新服务器时,我首先要做的几件事之一就是在SSH中使用登录。如果你有一台公开的服务器,可以看一下日志,会发现经常有人试图在SSH中登入。禁用这能就能完全有些人可能觉得,使用唯一的,加上fail2ban,被的风险会降到最低。糟糕的是,有时我们会创建测试账户,很简单,或者干脆使用默认,然后就忘了这个账户的存在,此时,服务器被的风险极高。我还会禁用X11Forwardin下面的代码使用sed自动修改SSH设置文件:#pathtosshsshd_config=3#changestomaketotheconfigseds='s/^#PasswordAuthenticationyes/PasswordAuthentication's/^X11Forwardingyes/X11Forwarding's/^UsePAMyes/UsePAM bash'sshhardening'usercode<<-#{seds.map{|rx|"sed-i'#{rx}'#{sshd_config}"sed是个很好用的工具,可以自动修改文件内容。刚开始使用时很难上手,但如果某天下午有空,值得花点时间学习这个非常强大的工具,熟练后可以节省很多时间。地球人都知道Sed的文档写的不好,但有个很棒的,地址是http: 但要注意,这么做可能会出现问题。如果让unattended-upgrades自动安装可用的安全更新(我就下降,更看重的是哪个。99%的情况下,我选择进行自动更新。另外1%的情况是,我需要99.999%的时间,而且知道系启用自动升级的代码如下#Setthesystemtoinstallsecurityupdatesautomaticallyeachfile'/etc/apt/apt.conf.d/10periodic'ownergroupmodecontent<<-APT::Periodic::Update-Package-ListsAPT::Periodic::Download-Upgradeable-PackagesAPT::Periodic::AutocleanIntervalAPT::Periodic::Unattended-Upgrade更详细的说明以及定制方法,请阅读Ubuntu官方教程:https 最后,设置服务器自动更新时间#updatedtimefromcentralservereveryday,particularly#whencertsare3file'/etc/cron.daily/ntpdate'ownergroupmodecontent<<-ntpdate- 我们设置了一个时钟守护作业,每天根据Ubuntu的时间服务器,更新服务器的时间。使用SSL证下一节,我们会设置,控制哪些端口可以从外部在外部世界和服务器上运行的服务之间添加了一个防护层,控制IP能服务器的哪些端口。我们要设置一个,默认对所有端口的,然后使用Chef管理要开放的端口UFW(简 UFW使用IPTables设置,操作方便,可以添加和管理规则,定义开放和禁用的端口default.rb配方中的以下代码会对UFW做基本的设置#nowallowSSHtrafficthroughthefirewallandrestart#unlessotherwisespecified,blockbash"openingufwforsshtraffic"usercode<<-ufwdefaultufwallowufw--如上所示,我们再一次使用Chef执行标准的终端命令。下面这行ufwallow告知UFW,允许端口22(SSH使用的端口)进出的所有流量。下面这行ufw--会启用UFW。注意,一定要在启用之前允许通过SSH的流量,否则可能无法从SSH登入。在终端服务器上执行下面令,可以查看是否启用了UFW,以及当前使用的规则:sudoufw上述命令的输出如下112345默认情况下会所有端口除非指定打开某个端口这就是我们需要的效果默情况下,安装一个新服务时,除非手动打开端口,否则会一切外部连接。接下来的设置有点高级#ifwe'vespecifiedfirewallrulesinthenode#thenapplythemhere.Theseshouldbeinthe#{"port":"x","ip":ifnode['firewall_allow'].eachdobash"openufwfrom#{rule['ip']}onport#{rule['port']}"usercode"ufwallowfrom#{rule['ip']}toanyport我们在server.json角色的默认属性中定义了如下所示的属性这个数组可以使用如下形式的{"port":"x","ip":basic_security-tlq配方会遍历这个Hash,为指定的IP开放指定的端口例如如果正在设置的服务器上运行有MySQL服务器端口为3306,要对另一台服务() {"port":"3306","ip":这个设置的意思是,允许IP为的服务器连接到端口3306,但其他IP到这个端口的连接记住,可以执行sudoufwstatus命令查看当前使用的规则 的端口可以在UFW的日志中查看,默认情况下,保存在/var/log/ufw.log。只要执行下面7.3 41sudotail-f就能实时看到写入日志的最后一条信息你可以试着从不同的服务器连接各个端口,看是否已被禁用。这么做可以1)的端口是否被禁用,2)如果服务器之间本该可以连接,但现在无法连接,排查问题。把示例模板应用到VPS现在,我们基本设置好了一台服务器,包括安装常用创建用设置SSH登入 [ 这一节我们要把这个简单的节点定义应用到VPS上,后续的章节再继续编写假定你从第6章起一直阅读到这一节,且完成了以下操作克隆了示例仓库 /TalkingQuickly/rails-server-tem执行berksinstall--pathcookbooks命令,在本地安装了食具体的步骤和5.4节把Redis的设置应用到服务器上一模一样。1)把公钥到VPS上:把示例模板应用到VPS ssh-copy-id在服务器上安装 knifesoloprepare生成节点定义文件nodes/yourserverip.json,写入如下代 确保按照7.1中的方法设置好了用户数据把节点定义应用到VPS knifesolocook希望上面的步骤能表现出使用Chef配置服务器是多么简单。只要编写好了角色和食谱,配置一台新服务器只需简单的四步。其实,如果经常要重用某个节点定义,可以将其另存为,例如nodes/side_project_server.json,然后执行下面令: knifesolobootstraproot@yourserverip上述命令会在yourserverip这个VPS上安装Chef,然后应用节点定义nodes/side_project_-现在可以以deploy用户的通过SSH登入服务器,使用提供的公钥进行验证,例如 sshhto(只需输入htop情况了。还可以执行sudoufwstatus命令,查看是否启用了,以及使用的规则。安装生产环境使用的Ruy版本要和开发环境中的一样,这一点非常重要。如果版本不一样,有可能出现难以修复的错误和异常表现。一般来说Ubuntu源中的Ruy版本过旧一种解决办法是使用第源更新系统中的Ru和本地的版本一致。虽然这种方法可行,但我更倾向于使用可以自由切换Ruy版本的工具。使用这类工具最大的好处是,可以同时安装多个版本,相互之间无干扰,而且可以快速在不同的版本之间切换。如果升级后出现了意想不到的问题,就能体现这类工具的优势了,无需彻底回滚到安装前的状态,切换到上一个版本即可。rbenv和开发过程中经常会发生这样的讨论我的工具比你的好用rvm和rbenv各有优缺点rbenv的上列出了为什么别用rvm而要用rbenv: 简单来说,我选择rbenv的原因是,操作简单,问题容易解决。所以,本书将使用rben。如果你倾向于使用rvm,也有很多第食谱可以安装,使用起来也不复杂。rbenv要理解rbenv的工作机理,首先要理解$PATH的作用。初看起开,$PATH有点吓人,在解决问题的帖子和StackOverflow的回答中经常可以看到它的身影“啊,很显然不在你的$PATH中但很少有人解释$PATH到底有什么用。其实,$PATH的作用很简单。如果在本地终端输入echo$PATH,会看到如下的输出8.0安装/Users/ben/.rvm/gems/ruby-1.9.3-p286-falcon/bin:/Users/ben/.rvm/gems/ruby-1.9.3-p286-n@global/bin:/Users/ben/.rvm/rubies/ruby-1.9.3-p286-ben/.rvm/gems/ruby-1.9.3-p286-falcon/bin:/Users/ben/.rvm/gems/ruby-1.9.3-p286-l/bin:/Users/ben/.rvm/rubies/ruby-1.9.3-p286-可以看出,这就是一些文件夹的路径,用冒号隔开。在这台电脑里,我是用的是rvm,所以有很多rvm相关的文件夹。如果你使用的是rbenv,可能会看到如下输出:在终端输入命令后,例如rake或irb,系统会按照顺序从头到尾搜索$PATH中的文件夹,寻找和命在上一节第二个输出中可以看到,rbenv在$PATH的最前面加入了下面这个文件夹因为$PATHbundle或rub件夹是/usr/local/rbenv/shim。如果在这个文件夹中找到了对应的可执行文件,就会执行这个文件。所以,如果这个文件夹中有名为bundle如果查看这个文件夹的结构(ls/usr/local/rbenv/shim,会看到:-rwxr-xr-x1rootroot393Apr172013-rwxr-xr-x8rootroot393Apr172013-rwxr-xr-x8rootroot393Apr172013-rwxr-xr-x8rootroot393Apr172013-rwxr-xr-x8rootroot393Apr172013-rwxr-xr-x8rootroot393Apr172013-rwxr-xr-x8rootroot393Apr172013-rwxr-xr-x8rootroot393Apr172013-rwxr-xr-x8rootroot393Apr172013如果查看各文件的内容(例如,执行cat/usr/local/rbenv/shims/ruby命令)会发现,其实就是简单的s 。这些s 会对输入进行处理,然后把命令交还rbenv处理。然后,rbenv会按照下面的顺序决定要使用Ruby哪个版本执行这个命令RBENV_VERSION环境变量中指定的版从被执行所在的文件夹开始,向上层文件夹递升,直到根 的第一个.ruby-version文件中指定的版本 开始,从被执行所在的文件夹开始,向上层文件夹递升,直到根 止,在这个过程中找到的第一个.ruby-version文件中指定的版本∼/.rbenv/version(如果在系统层面安装,就是/usr/local/rbenv/version)文件中指定的版本,即Ruby全局版本。如果上述寻找都无果,就会使用没有安装rbenv之前使用的版本(例如,系统自带的其实各Ruby版本就安装在∼/.rbenv/versi
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年湖北驾驶员货运从业资格证考试题
- 2024年河北客车驾驶员考试试题加解析
- 2024年东营申请客运从业资格证模拟考试
- 2024年德宏小型客运从业资格证理论考题
- 功能章操作协议书
- ITO离被淘汰不远了-石墨烯等新材料靠啥上位-
- 四川省凉山彝族自治州会东县会东南山实验学校2024-2025学年六年级上学期期中数学试题
- 产品质量改进方案
- 供应链整合管理方案
- 沙漠工程钢结构安全协议
- 福建省公需课考试题目(2024年)
- 全国新世纪版信息技术七年级上册第一单元第四课《电脑是如何工作的》教学设计
- 工程伦理与工程认识智慧树知到期末考试答案章节答案2024年哈尔滨工程大学
- 旅游景区物业管理方案
- 侵权告知函(盗用图片)
- 2024年汽车维修工技能理论考试题库附完整答案(历年真题)
- 猪、牛、家禽屠宰冷链加工一体化项目可行性研究报告
- 诺贝尔生理学或医学奖史话 知到智慧树网课答案
- 太阳能光热转换和热储存技术
- 植物病虫害防治绿色防控
- -原料药的优良制造规范指南(ICH-Q7)学习与问答
评论
0/150
提交评论