网络自动化实践中的一些问题(摘自zhihu)
关于网络自动化,有一个普遍的,也是笔者曾经相信的理论:先有标准化,再有自动化。这听起来很有道理对不对?毕竟有了标准以后,自动化就容易了,对着模板传参就可以了。但是如果自动化真的这么容易,我要不要程序好像也不重要,毕竟都标准化了,每次打开一个Excel去渲染一份配置不好吗?
这个理论有两个问题是永远无法解释的:
- 非标配置怎么办?如何兼容。
- 标准跟不上业务需求怎么办,是制造非标,还是让业务等等。
对于第一个问题,有大聪明就说了,我等着把非标下线不就好了吗?那我且问你,什么时候下线,谁来决定下线?但凡你的老板不是个糊涂蛋,在你提出非标的下线或者迁移的时候,老板问你的第一句话就是:为什么?
它跑的好好地你为什么要去动它?老板并不是无缘无故责难你,而是老板需要一个理由去说服其他人,他要做这件事,而这个理由,我就没见过有多少人能回答完美的,大部分都是选择了忽悠老板这条路。
更可怕的是第二个问题,标准跟不上业务需求怎么办。显然你不可能让业务等等,所以你只能制造非标。
所以,如果你基于标准化再做自动化这个逻辑去做自动化,你大概永远也无法实现自动化。
回归到网络原本的职能上去
会产生网络自动化需要先做标准化的根本原因,是对自动化理解的欠缺导致的。大部分人对自动化的理解来自于自己编写批处理任务脚本的经验,而这类脚本的特点就是,想好业务逻辑后,把参数提取出来,然后每次往里面传参执行。基于这个经验自然会产生需要先做标准化的想法,因为只有做了标准化,流程才能固定,脚本才能写出来。
更有大聪明在这个思路的基础上想出了,我写一堆脚本,每个脚本对应一个服务,不就能永远自动化了吗?想得很美好,实际落地的结果就是脚本海洋,playbook丛林。
这种思维实际上是很懒惰的,基于这种思维做出来的自动化,必然是难用,无法长期维护,容易变成屎山的东西。
但是我不得不说,对于Linux运维来说,这可能是有意义的,因为Linux运维里就是有很多零碎的ask,可是Network不是,Network的大部分task都不是零碎的,而是有上下游关系。我可以这样做一个类比,Linux运维有点像你挨家挨户去抄水表,而Network运维,往往是在外面把水阀关闭和打开。你重启一个系统服务可能不需要check什么东西,而Network切一下骨干链路或者新增一条骨干链路可不是开玩笑的,运气不好来个半数流量挂掉那就是丢工作了...
回到网络自动化需求的根源上, 我们为什么需要网络自动化?答案很简单,因为人工编写配置,批量配置容易出错,而且重复度高,浪费时间。也就是说,做网络自动化的核心就是解决工作中的重复问题的。
这个时候有大聪明就会说了,那你抨击的脚本逻辑就是为了解决这个问题而存在的呀?没错,它的确是。它的问题是,如果你的流程越来越多,你要写和维护的脚本就越来越多,脚本不可复用,最终就是脚本海洋。每次产生一个略微不同的需求,就需要重新写脚本,重写脚本,就要重写全部的逻辑,就意味着需要测试,因为可能会有Bug。
网络功能的结构化和数据化是网络自动化的基础
那么怎么解决这个问题呢?我的答案是:要把粒度做细。你不能基于一个特定的工作流去做自动化,而应该把无数的工作流中共性的部分提取出来,做成一个一个的模块和零件。我们做自动化的首要目标是减少人为失误,而不是程序自动执行完全不需要人(其实这根本就做不到)。
让我来举个例子。当我配置一个peering到一个客户的时候,我需要配置什么东西?我需要BGP,我需要route-policy,我需要prefix-list。这个还只是粗略的分类,更细分的话,我以prefix-list为例,它包含创建,调用和后续的更新。其中创建和调用是最初的事情,后续几乎不会变化,而更新是则是后续运营中经常会发生的事情,运维工作中其实最常见的就是更新,这包括删除一些前缀或者增加一些前缀。
如果你写脚本来完成这件事,大概率只能写出一个一开始帮你自动配置peering的脚本,填好参数run一下就结束了,但是后续运维的时候你还是需要到设备上去登录改配置,万一搞错,你就凉了。
我不知道各位读者是否注意到了几个事实:
- 初始化的时候的容错率其实更高,因为业务还没有上线
- 后续的运维才是真正需要自动化的地方
- 许多工作流里都包含相似的工作模块,比如prefix-list的更新
我们还以prefix-list的更新为例,它不只是在peering的时候有用,在其它情况下,比如DC内新增了一个子网的时候,我可能会需要更新边缘设备的入站策略。当然又有喜欢杠的大聪明就要说了,如果规划好subnet,不就不需要在这种场景下更新入站策略了吗?对,是这样没错,但这就回到了一开始的问题:规划设计缺位的时候怎么办?你设计一个工具,它建立在诸多的限制条件下,那必然导致你真正要用它的时候就用不上了。
何况我也只是举个例子,会需要更新prefix-list的情况非常多,理论上来说只要有peering,就需要prefix-list做filter,否则总有一天你会因为对端敲错了一条命令行而见鬼(比如给你发了一条默认路由过来...)
所以,其实真正需要被自动化的,是prefix-list的维护。而如果要做到当一个需求过来的时候,尽可能少的步骤完成prefix-list在需要的地方进行更新,prefix-list本身的操作维护代码只是非常小的一部分,我想它还至少要依赖以下模块才能工作:
- Network Device Database,网络设备的数据库,里面要包含设备的Role信息
- Network Interface/IP/Peering相关的Database,用于识别你要在哪里应用prefix-list以及更新哪些prefix-list
- 全网所有的route-policy和prefix-list的关系以及它们和peering之间的关系
这些数据,才是基础,甚至可以说是核心,所有周边程序其实都是在操作和维护这些东西。
一个数据库,以及良好的描述网络资源的包括interface,link,ip address,peering,route-policy,prefix-list和其中关系的数据结构,以及从网络中及时捕获变化和更新状态的扫描器,这些是做自动化的基础。当然,不是说所有的数据都要一开始全部收集好,我们还是以维护全网的prefix-list为例,它所需要依赖的底层网络数据是一个有限集合,比如至少IPSLA的配置,此时大概是不需要收集的。当你产生维护其他资源的需求的时候,你还会需要收集其他的依赖数据。
数据有了,你可能还需要一个Tag来做标记,当然你大概率还需要一个前端,这都是专业的程序员可以搞定的事情了。
现在,我们有了一个需求,需求说要在所有的数据中心放通一条新的anycast route。由于我已经为所有数据中心边界的prefix-list添加了Tag,所以现在我只需要过滤这些Tag,然后为它们添加这条新的anycast即可。剩下的事,就是其他后端程序的任务了,包括对于不同的平台的prefix列表配置的语义识别,转换,和具体的更新行为。
类似这样的对于网络元素的抽象,在你具有更高级的业务抽象,比如一个peering业务之前,我们依然可以通过这些基础网络服务的抽象来完成业务的配置,而且我必须要说的是,前端是必要的,因为人需要交互引导来完成工作。不Touch CLI是为了避免人为失误,那么就需要一个好的引导界面引导你组合合适的轮子,完成配置。
实际上BGP支持哪怕1000个feature,你用到的却并不多,对少量的feature做抽象开发也没有很难。
IT网络工程师和云网络工程师的思维差别
几乎所有的网络工程师都会有IT网络工程师这个阶段,在这个阶段,你维护的系统里没有平台,只有零散的网络,计算,存储这样的散件,用户需要知道去找谁和要什么东西,即便你有了线上流程也不过是让程序帮你转交请求顺带记录KPI而已。这个阶段的网络工程师,是直接对口业务的,是需要和业务直接对话的,因此网络配置里就会记录业务字段。业务信息插入到网络中这个状态,会持续很久,甚至会从中诞生出一些标准化,但是我想告诉你的是,它终将不可维护。
从网络配置携带简单的业务信息,到网络管理员开始主动管理业务和限制业务以求最大化利用自己有限的资源,包括有限的公网地址,有限的带宽等,这个过程,其实相伴而生的,往往是公司的第一个业务成长期,有一个业务主轴的时候。什么时候会开始出问题并且让网工焦头烂额呢?主要业务增长受阻,开始开辟新赛道的时候。
你为了保护主要业务而设定的规则和标准,随着公司转向多个赛道的探索会开始出问题,首先的问题就是,业务变化带来的人员变动和传承终结。新人不识旧规则,只道你的工单效率低,影响他上线。更多的事业部,更多的业务,人家根本不跟你聊规则,不要说你基础设施了,就连原本的业务管理系统都给你翻咯。
我们且不说这个状态下公司的发展如何,至少有一件事可以确定,你的IT管理逻辑到头了。
从这个时候开始,你原本的规则和标准需要修改了,譬如有个对延时不敏感的大流量业务,正确的做法是给他开辟两条便宜的大带宽让他在那跑去(比如点对点两条移动宽带上起个隧道)。又或者,如果你恰好资金充裕,公司愿意投入,那么你需要转变思路,将原本的QoS分类的逻辑转为流量监控过了50%的水位线就开始张罗扩容否则无法承载公司的业务,产生的成本算到业务部门头上去。
包括网络配置也不再需要和业务强关联,取而代之的是,网段要有明确的负责人,这是资产,分给谁谁自己管好,避免僵尸网段的出现。
这个时候原本在单轴业务时代的很多自动化和标准已经没有意义,我们需要把视野固定在网络本身,思考怎么把网络本身的东西服务化交付给客户,与此同时,大概率这个时候公司里会开始有一批人说我要做个平台...嗯,所以网络需要和平台去整合么?未必。
还没上平台的客户是你的客户,平台,也是你的客户。你需要的是交付服务,既然有人要做平台,就意味着,他要直接对客户提供服务,将你的服务封装起来。谁做平台,谁对客户负责,如果客户不上你的平台,他仍然直接选择找每个人,那也是人家的自由,在网络工程师看来,平台和直接找网工创建网络的客户是同一个级别。而平台的客户,那不是网络的客户,平台的客户遇到问题,先找平台,不要直接找网络。
从这个时候开始,网络工程师就开始变成云网络工程师了,核心就是关注自己能做什么,然后封装为服务输出。简而言之,你不再是网络管理员,而是交付网络服务的...乙方。好像更惨了。
大部分公司都会在这个阶段遇到大量的转型问题,产生大量的技术债务,在这个阶段,网络架构的设计也会变得不一样,运维关注点也会不同,网络在这个阶段要向基础服务去演进,而不是跳出来说我有XX标准,但与此同时,上层平台要对自己有点B数,能做什么,不能做什么,需要别人帮你做什么,如何合作,都是值得讨论的问题。
平台不是随便做的
我至少两次碰到老板不清楚自己团队斤两吹牛逼自己要做平台的情况了。历史上,我曾经有过一个vDC,virtual Data Center的流产经历,其实在design那个东西的时候,我和我的同事就感觉到这东西没那么好做,涉及的点太多,而无论是团队技术实力还是人员储备都不够。说白了,你总不能真的靠一堆脚本去作为平台运行的引擎吧,做一个平台需要的资源是巨大的,哪里是几个写脚本的运维就能做的?
哪怕你能设计出结构,技术,DB Schema,也是远远不够的,后端代码谁写?引擎和调度器在哪里?前端界面有没有?说白了,如果你没有做出一套东西,只是扯一个概念交付给用户,用户根本就不会给你买账。
尾声
最后扯的有点远是因为,网络自动化这个事情,我发现它对于不同的网络环境来说真的是不一样的,对于业务单一逻辑简单的网络来说,可能就是脚本驱动就够了,对于业务复杂的网络来说,脚本本身就会变成巨大的技术债务。加之网络工程师接触自动化时间尚短,可能很多人还没有来得及想明白到底什么是封装,以及怎么对现实世界抽象。当然了,网络自动化还有个最大的拦路虎:五花八门稀奇古怪的设备,有些设备别说API了,连CLI都没有,只有一个难看又难用的GUI,自动化?不存在的。你看我GUI点点点,是不是很厉害?