@gaoxiaoyunwei2017
2017-10-19T14:30:22.000000Z
字数 9462
阅读 480
毕宏飞
陈尔冬
链家运维总监,负责基础设施研发与运维工作,曾于新浪任职技术总监,负责私有云平台研发与运维并支撑新浪微博从零至上市高速发展的过程。后于华为任职技术专家,致力于提升华为公有云运维能力。2017初受鸟哥邀请加入链家网,负责基础设施研发与运维工作。曾译《奔跑吧,Ansible》一书,最近几年一直致力于研究如何根据公司不同情况,打造出最适合的运维体系。
今天分享的题目是“让配置飞起来”,我做运维相关领域的工作有十多年时间了,也参与翻译过一些 ansible 的文章,翻译过一本书叫《奔跑吧 Ansible 》,其实这是 ansible 诸多书籍中很不错的一本。当时翻译的时候是觉得 ansible 的中文书籍不是很多,当然现在有很多很优秀的。在我看到 ansible 时, ansible 确实是配置管理领域的后起之秀,大概是2013年才刚刚创立的项目。后面也会跟大家讲一讲 ansible 哪些优点让我觉得不错,对于我从事的这些公司为什么适合用 ansible ?我从来不会向大家推一个东西,说这个东西好,大家都用吧,可能在我看到的场景是适合的,至于大家的场景适不适合,要根据自己的情况。
今天我会从以下四个维度去聊 ansible 和我从事的各种公司的结合:
一、配置管理
二、配管工具与 ansible
三、Beyond the Ansible
四、动态配置管理
像 Puppet 、 SaltStack 这样的很出色的管理工具,为什么我们选用 ansible ?今天也会讲到基于 ansible 我们会达到什么样的效果,帮助我们在哪些方面做了提高。如果 ansible 有缺点,或者它有它的能力边界,当我遇到边界的时候,怎么样超越 ansible 标准的能力和功能,进一步帮到我们的企业,帮到我们的团队做运维。去年我在北京站的运维大会上分享过关于在链家网的一些实践,当时我简单提到了所谓动态配置管理的理念,之后也有一些朋友在高效运维社区里问我,动态配置到底应该有什么样的实践?今天我跟大家简单交流一下动态配置,跟大家说说我对于动态配置的理念和理解。
我在运维领域应该有15年左右,2015(时间不确定,需老师确定)年的时候是在新浪工作,参与了新浪微博从0到最后上市的整个过程。从新浪出来之后加入了华为,因为在新浪的时候做了一个有点像私有云的产品,不过当时不叫它私有云,是新浪微博在这个产品上跑的应用之一。加入华为后开始做华为公有云,主要是负责华为公有云运维能力提升的方向,实际上在2012实验室,会跟华为公有云的团队一起做配合。后来我加入到链家网,去年我在运维大会上分享了在链家网这一年左右的工作,链家网不做公有云也不做私有云,但是我们是公有云的用户,我们使用AWS,另外也有自己租用的数据中心。之前也聊过,我实际上参与过公有云项目、私有云项目,同时也是公有云、私有云产品的用户,我觉得自己在运维以及云计算领域还是有那么一点点发言权。当然,配置管理后面我会讲,配置管理其实是渗透在层层环节之内的,你的环境越复杂,你的规模越大,你就越需要去把你的配置管好。
最后有一个今天想要跟大家分享的感想,去年我说的是灰度,今年说的是没有银弹,这个论文七几年就发表了,没有银弹是一篇软件工程的论文。我们经常会看到很多老师跟大家分享的时候说没有银弹,看到很多文章里讲没有银弹,那篇论文实际上阐述的是我们不可能在十年时间让软件工程的生产力提升10倍。举个例子,我们没有可能拿一个软件或者拿一个软件的方法,放之所有公司皆准的,这是为什么 ansible 适合我的团队。我不认为会有一个产品或者开源项目,所有的朋友拿到自己公司的场景里都好用、都能解决大家的问题,而且不会带来任何额外的问题。即使最好的软件,比如谷歌现在用的,谷歌的系统好,但是要有顶尖的工程师去研发维护。假如那个东西拿到我的公司,我的公司是不是就一定能够有成本把它管理好?能不能开发得了?真的有那么大用吗?有那么大规模吗?全中国有多少套房子,全世界有多少套房子,和互联网上的网页数量比,链家的数据太小了。与其我们去寻找这样的银弹,不如用好自己手里的平底锅。这也是为什么今天我在配置管理这个领域和 ansible 这个工具话题跟大家讲。
如果要讲配置管理,实际上还是需要回到 Unix 诞生之初。我们知道有一本非常著名的书叫《 Unix 编程艺术》,里面产生了 Unix 一些经典的哲学。
我不一一阐述,举几个今天会遇到的。比如在这个场景里我想跟大家阐述配置, Unix 里面有几个理念:
回到配置的话题,刚才讲了万物皆文件,机制与策略分离,要有地方配策略,所以就有了配置,就是一个配置文件而已,无外乎把这个配置文件编辑一下就好。
这是我画的一个示意图,在一个计算机里,比如现在我们的生产环境一般用 Linux ,会装中间件,甚至一系列中间件,比如 Nginx 、 Apache , Linux 系统可能就需要配置。中间件刚才我们聊了, Nginx 要配置文件,应用可能也会有配置,我们自己写的产品也有可能留一些机制,以备后面调整策略,不要重新改代码,这是很正常的设计。我们看到在我整个一台服务器的生产环境里有多个维度都需要调整配置,最下面叫 Provisioning ,把一个物理服务器装操作系统,装一个基本环境,后面当配置管理,往往是管中间件层的配置。这个配置管理实际上是柔性的,可能管操作系统配置,也会管应用配置。应用本身我们叫发布,很多时候我们可能会把应用配置放在SCM管理体系里,软件配置管理。有一个专门的流程是管理我们软件的配置,在把软件配置落实到生产环境里就通过部署这个环节做。实际上 ansible 这三个领域都可以做,如果你是一个物理服务器,可能 ansible 不适合做 Provisioning 。但如果你是私有云或者公有云,创建一个虚拟机或者容器完全可以用 ansible 做,配置管理完全可以用 ansible 做,发布完全可以用 ansible 做。
现在是云计算时代,不管我们是不是云厂商,一台服务器总归是不够的。一台没问题,不就是切分文件吗,有的是办法。但如果我有一百台服务器,还是拷的过来的。如果有一万台服务器呢?我们看一个经典的例子,这个例子举的是豆瓣的例子,大家不要误会,我是非常尊敬豆瓣的。
豆瓣曾经拿一台服务器扛整个豆瓣,这台服务器豆瓣起名叫(指环王角色名,需要老师确认),以豆瓣的发展,这一服务器早晚不够。豆瓣当时的做法是给每台服务器都起个指环王角色的名字,当豆瓣有一千台服务器的时候,恐怕把每个矮人战士的名字都放在服务器上,好管吗?
这是微软云计算的数据中心,是模块化的,每一个集装箱就是一个集群,一个数据中心里有多个集群。如果一个集群有一千台,这个数据中心能放多少台,他可能不止一千台。回到刚才的例子,指环王角色的名字还够用吗?用星球大战也不够用,别说给服务器起名字了,连阿里巴巴给员工取名字用金庸小说也不够。为服务器起名字这个事不能这么干,这么干下去没名字可用了。
这是一篇老外的PPT,其实最早是微软在论文里提及,也是很经典的一个理念,相信大家也都听说过,就叫做宠物对公牛。所谓宠物理念就相当于大家刚才看到的,这台服务器就是我的一个宠物,像这只可爱的小猫,悉心照料它,给它起个名字,它生病了我就照顾它,把它照顾好,每天让它陪我玩。但如果我有一万只小猫,怎么取名?如果这里养了一群奶牛,我养一万台奶牛,怎么取名?真正的牛场不取名,是使用编号的,一直编到一万。如果生病了怎么办,杀了。这就是在大规模服务器管理里面我们需要去考虑或者需要去采用的方法,我这些服务器就代表了一到一万个数字,如果服务器坏了怎么办,不要了,换一台新的上来。这里举了一些刚才说的例子,你给宠物起特殊的名字,服务器不要起特别有意义的名字,你起的就是一个编号。
我们公司大概上千台服务器,靠手工是没戏的,所以我们需要自动化。配置管理就是干这个事的,帮我们自动化去管服务器。运维管服务器有很多领域,很重要的是 Provisioning 配置管理、发布,后面两个领域包括第一个 Provisioning 领域,我们都可以用配管工具来实现。
这是 Puppet 发布的, Puppet 每年会发布一篇 State of DevOps Report 的研究报告,我取的是2017年新版,会看到跟2016年的数据做了对比。每年IT企业的发布速度,2016年发布的频率比2015年频繁了200倍,2017年比2016年居然更频繁了46倍。手工发布的话可能吗?即使多雇了200倍的人也不能保证你发布速度频率能增长那么快,这说明了企业越来越深度的使用自动化管理手段,既然叫 DevOps Report ,就是说企业在应用了 DevOps 以后,发布的频率变得越来越频繁了,包括下面变更的速度越来越快了。2016年变更2555倍,既然到2017年还能增长440倍,说明实际上现在自动化的能力在不断提升,还有故障恢复的速度变得越来越快了,变更导致故障的比例变得越来越低了。
怎么样达到上面所说的效果呢?先讲讲所有的配置管理工具, Puppet 是比较老牌的,还有 Ansible 、SaltStack 。配置管理工具有这样几个优势,首先自动化是肯定的,最主要的是它实现了基础设施即代码,为什么跟 DevOps 连接在一起? DevOps 对我们整个的基础设施运转的体系提供新的建议,其中一点就是基础设施即代码,配管工具就能实现。如果大家用过 Puppet 和 Ansible ,我们会把我们的服务器上面装什么软件、运行什么程序、启什么进程、计划软件都会配到配管软件里,配件软件本身又有一个配管软件,这样就实现了你的基础设施是存在一份代码里的。后面还有模板引擎,再后面是配管工具还会基于状态的管理。为什么基础设施即代码有意义,它是随时更新的,基础设施可以随时写一份文档,这份配置文件永远是线上最新状态的一份描述。再有是它会有些抽象,不一样的配管工具抽象不一样,所以我们可以选择哪一个更适合我,我的团队是写 Python ,可能 Ansible 或者 SaltStack 更适合我们,因为这两个软件是用 Python 写的。
刚才聊到了宠物还有公牛,现在聊到配管工具,看看配管工具里怎么去应用公牛理念。基本上理解了这个理念之后,往你的配管工具配置就完全没有问题。
举个例子,我有两个数据中心,上面一个下面一个,实际上代表了廊坊一个、深圳一个。每个数据中心里面有两组web服务器,两组数据中心服务器。做模型定义,每一台服务器在这个模型里就可以是web01、02、03,我们看到的除了编号之外,编号对我们来讲没有意义。我们看到的是模型,如果是web服务器,我就可以对web服务器做什么样的操作。抽象成模型之后,你仅仅是对一台服务器做编号,你没有办法对服务器做管理,怎么办?某一类服务器建一个模型,比如web服务器,比如廊坊服务器和深圳服务器,可以给廊坊配相关配置,深圳配相关配置,所有都需要装 Nginx ,这是基础设施即代码的应用。大家会不会发现一个问题,如果我对于廊坊的web服务器和深圳的web服务器在配管工具上还要特殊处理,是不是管理成本会很高。我刚才举的例子是一个数据中心里有一万台或者十万台服务器不好管,那么如果有十个数据中心是不是也不好管?这里面模板引擎的意义就来了,我们为什么需要模板引擎?
我仍然举数据中心的例子,这是一份 Apache 数据中心的抽样,会配一些环境变量,一个程序它不知道自己最终会在哪个数据中心跑,它运行时怎么知道,有一种办法是让它通过环境变量去获取,显然在不一样的数据中心要定义不一样的数据中心环境变量。这个问题就来了,我们需要对每一个组定义不一样的变量,这显然很不易于管理,所以出现了模板。右边这个脚本是很久以前写的,这是 Apache 模板引擎,谈不上引擎,是一个模板程序,右边配置文件变成模板文件,当我们把模板文件修改的时候,右边的处理程序就会升级成最终的 Apache 配置文件。你在现在的配管工具里,不管是 Ansible 还是 Puppet ,都会有非常强大的模板引擎,可以帮你把你的配置管理规整。比如我们要建模型,要利用公牛的理念去管理我的服务器,但是我的web服务器就是有千差万别的特点,用你的模板引擎帮你把web服务器变成一类。
这是 Ansible 的架构,非常简单,非常易于在我的企业里应用。实际上当我看到 Ansible 的时候,我的公司里面已经有很多乱七八糟的基础设施、运维产品、脚本。但 Ansible 很简单,每一台服务器肯定要开SSH,每台服务器几乎都会装 Python ,几乎所有 Linux 操作系统上都会装 Python 。所有 Ansible 依赖的软件你都装上了,就是 Python 和SSH。 Ansible 的原理是我在中心,左侧是中心管理服务器,当把你定义的配置管理定义好之后,它生成一个对于被管理服务器的 Python 脚本,把这个 Python 脚本传到目标服务器上执行一遍,把结果拿回来,就这么简单。原则上说,你现在所编写的任何脚本都可以在 Ansible 上去运行。可能你现在在一台服务器上,放到 Ansible 上就可以在一千台服务器上管,就这么简单。
我为什么选ansible,对于我的团队来讲,进入成本是非常重要的,我们有很多历史包袱。
刚才我聊到了易于复用所有脚本,最主要的是第二个维度,也是我们要基于 Ansible 做扩展时所需要设计的。我们可能会连接不一样的工具, Ansible 也有弱点,任何软件都有弱点,有一天你会发现 Ansible 不够你用的了,我也发现了,它有一些弱点被我遇到了,仅仅是 Ansible 不能符合我的需求。 Ansible 设计理念是薄薄一层,就按照 Unix 传统哲学设计的,非常易于你自己的软件或者另外的开源软件上下游连接。举个例子, Ansible 有个配置文件叫 Inventory ,我知道在大家的企业里可能会有比如 CMDB ,可能你是用公有云,比如说亚马逊、阿里云,在阿里云创建虚拟机之后,这些虚拟机资产是在阿里云自己的系统管。比如你用的是 OpenStack ,创建了虚机之后,虚机的状态和整个资产都在 OpenStack 里创建的,这个时候怎么办?如果这个信息需要人抽抄到 Inventory ,明显很不自动化, Ansible 引入了一个环节叫动态 Inventory ,动态的配置文件,可以支持写一个脚本叫 Inventory 这个名字, Ansible 发现这个文件是可执行的,它就执行一遍,把结果当做资产。这资产完全可以存在你的 CMDB 的,但是最好是ABI化的,可以是 Ansible 每次运行的时候运行一个脚本,抓 CMDB 出来,抓完之后给 Ansible 用,完全自动化,不需要一台服务器配两遍。 Ansible 非常适合做一个基本的 orchestration 软件用,如果 Ansible 对你来讲不够用了,你怎么扩展它?它把自己设计成薄薄的一层,一个很基本的 orchestration 软件,这是非常利于扩展的。
回到这张图, Ansible 很容易被大家抨击的点是因为它的性能很差,因为 Ansible 是 Python 写的,由SSH到我的目标服务器上,每连到一个目标服务器上建一个进程,由于 Python 是脚本语言,所以比较吃内存。当你要管的服务器,同时执行的命令服务器数量比较多,比如十万台,要启十万个进程,而 Python 本身要占内存,所以可能把你服务器内存吃爆。 Ansible 其实是一个非常模块化设计的,我们可以把SSH拿掉,用我们自己写的 Agent ,或者是用拉取模式,或者用任何样的模式,可以把性能问题简单的解决。当你遇到这个问题的时候,你完全可以在它上面做些工作或者用其他的模式解决这个问题。 Ansible 还有一个配置文件 playbook ,当你的服务器非常多的时候你会做很多抽象,但是你把这些东西都配成文本文件,你觉得非常不利于保管,实际上我们完全可以把这些文件放到git里, Ansible 每次运行的时候从git里面取,取出来之后再运行,这个很简单。还有一个你完全可以把你这些配置放到数据库里每次你到数据库里把这些配置取出来,生成一个文本文件,然后 Ansible 运行,管理你的服务器。这样你就把 Ansible 扩展成一个可以设计自己的自动化运维系统,模型可以按自己习惯的模式来。因为你以前用了 Ansible ,你又不想这个时候把 Ansible 全替了,那你完全可以把 Ansible 当做 orchestration 来用。为什么使用 Ansible ?因为它非常易于进入,非常易于扩展,你即使不把它完全替掉,只替掉一部分也是完全ok的。
Ansible 在我们的平台里会逐渐替换成 orchestration ,最早就用 Ansible Inventory 文件, orchestration 可以完全从 CMDB 里获取信息。
Ansible 就变成 orchestration 这一个模型,而不是所有的自动化运维的工具,可以基于整个体系扩展一部分。如果有一天我把其他的东西都做完了,我也有想法把 Ansible 整个替掉,当然整个替掉都没有问题,我从来不认为某一个软件是必须的或者它能够解决所有问题。
之前我提到过关于动态配置的理念,有的朋友在高效运维社区里向我提问,动态配置到底是什么玩意?
为什么它叫动态配置,实际上我认为动态配置来源于这里,如果大家比较关注应用架构会发现有很多应用开发工程师会倾向于把自己应用的配置放到 Zookeeper 或者 etcd 里,它有很多好处,分布式并且近乎于一致的,不需要触发什么工作,包括所有微服务架构都可以引入,比如命名服务。既然有这么好的一个东西,它可以放应用配置,为什么不能放系统配置,当我第一次看到有人用 etcd 存应用配置时我就想这个问题,为什么不能存系统配置。
先看一个应用配置的例子,这是以前我做过的项目。我介绍一下背景,大家都用过 Memcached ,是一个非常简单好用的应用缓存服务器,但是 etcd 它的分布式也是一个比较简单的模式,有时候我们会遇到一个问题,我的应用程序是PHP的,就用标准的 Memcached 。曾经 Memcached 我做过一个项目,我们管它叫分布式缓存,其实本质一样,不用标准的一致性哈希,靠客户端解决这个问题,客户端解决得不好,把所有的分布放到 Zookeeper 里,当我有一台节点宕机了,应用程序再来问这个key是什么,我告诉它这个key失效了,去数据库里取吧, Zookeeper 明显是一个应用级的配置。
为什么不能把应用配置扩展成静态配置呢,其实完全可以。
这是一个例子,现在国内有些公司也在这样用。刚才聊到 etcd 也好, Zookeeper 也好,有一个机制,比如这里有个key,当这个key变化的时候,会告诉你监测的程序有变化,你有一个配置发生变更了。这个架构里这个程序关联的是 confd ,其实是一个关联于 etcd 的模板引擎,当它知道这个key对应的 value 变化了,取出来重新渲染一遍,该更新什么东西更新什么东西。比如更新一下 Apache ,重启一下 Nginx ,我就可以把 Nginx 变更成动态配置, Nginx 有一些配置内容,比如 real Server 是会动态变的,这个不取决于 Nginx 自己, Nginx 不需要做任何调整。但后面有一个应用服务器宕机了,或者有应用服务器硬件故障,把它下掉,这不取决于 Nginx 自己,但是它需要感知后面我应用服务器的变化。当然也有一些维度,配置管理不摘,它以后总要检查这台服务器。
这个时候引入这样一个机制,如果我们用 Ansible 来做,即使用模板引擎,实际上是每次渲染这个模板引擎,如果模板引擎设计不好,这是两个变量,要两个变量一起改。真的是动的吗,当然是,但本质实际上没有变化。 confd 本质上是一个模板引擎,上面是它的模板,下面是 confd 本身的配置,如果这样配 confd , etcd 里存的内容就是右上角存的内容。当 etcd 里内容有变更,比如有台服务器挂了,它就会自动更改 etcd 的内容, etcd 会自动通知 confd ,说这个东西变了,你赶紧变吧,然后 confd 取出那个东西来重新渲染,整个过程是动态。在CPU里都是同步运行,CPU一个核心同一个时刻只能运行一个程序,本质上就是同步的,你能看到的异步无外乎是一个我们编程语言语义上的异步,你认为异步了,实际上在CPU那还是同步一件事一件事干。这里的例子一样,所谓动态配置无外乎是在我们的整个价值上,给上层管理员语义上的感受,这是一个动态的,实际上根还是模板引擎,然后下发你的配置,生效你的配置,你要先把模型建立好,模板引擎建立好,然后文件下发。做运维无外乎就是这三板斧,除非你的架构彻底变成更先进的架构。
你真的需要动配置吗?这个话题完全是因为有人在高效运维社区里向我讨论这样的话题,我实际上在生产环境里没有用动态配置,因为我的团队认为并不需要,我们玩好 Ansible 和配置,完全可以实现近乎于动态配置的效果。
在我的理念里一直认为,工具就是工具,没有一个工具可以把所有事都干掉。把运维拆解开,在配置管理这个领域,我认为就是把模型建好,建立好相应的模板,有一个模板化,你有一个工具能够帮你把你改造后的文件批量下发。我认为 Ansible 既可以做一个集体化一站式的东西,你没有任何基础设施,拿 Ansible 让它从0开始到完成是可以的。或者你有基础设施,有一些想法了,你希望有些自己做, Ansible 帮你做其他东西,也是完全可以的。这也是为什么我个人比较提倡 Ansible 的点,我并不认为 Ansible 是一个放到所有场景都好用而且没有缺点的软件,我只是认为它的缺点很容易被这种模块化的设计改进掉。