[Q]: 你是如何进入科技领域的?
[Kelsey]: 高中时期,学校里有个计算机编程相关的社团。我起初觉得计算机不太合我作为“酷孩子”的路线。但我很喜欢AutoCAD,甚至参加过竞赛,最后得了第二名。在社团的CAD课上,有位同学教会了我Ti Basic。课上有人介绍说这不只是绘图计算器,还能编程。我当时很好奇,那时大家都会从杂志上抄代码,制作贪吃蛇游戏,输入代码运行后就能玩。于是我也开始研究。那是我第一次接触编程,就是在Ti 86计算器上写代码。
[Q]: 高中毕业后,你是上了大学,还是考虑过上大学?
[Kelsey]: 我确实考虑过上大学,但头两周我就觉得节奏太慢了,这不是我想要的。另外,我毕业时是1999年,电视上人们排着队等待新版本的Windows,很疯狂。美国在线(AOL)开始淡出,高速互联网开始普及。我当时想,时代在前进,同时也听到一些说法:比尔·盖茨从大学辍学,大家不再推崇学历,而是强调技能。很不幸,我身边没有程序员,也没有系统管理员,当时企业用的都是Sun微系统或IBM大型机这类设备。看招聘信息时,我发现很多技能我根本不知道怎么学习。
[Kelsey]: 有一次去书店,我看到一本A+认证指南,一些招聘启事要求具备A+认证才能担任技术支持之类的职位。我想,这不需要大学学历,但书只要35美元。我买了那本书,里面包含官方的认证流程,反复通读。书中涵盖了所有基础知识,书末还附有模拟考试。对我这样的人来说,这种快速反馈循环很有帮助。后来我就拿到了A+认证。
[Kelsey]: 拿到证书后有个招聘会,凡持有A+和Network+认证的人,都可以参与承包商的工作,当时的工作是将用户的拨号上网升级为DSL。就这样,我算正式进入了科技行业。
[Q]: 你当时是否认为这是进入科技行业最高效的途径?
[Kelsey]: 是的,我认为这是唯一的方法。
[Q]: 大学难道从来没告诉过你,那也是一条路吗?还是说,当时你根本没见过有人走这条路?
[Kelsey]: 我没见过有人走这条路,也从未见过圈子里有成功的先例。当时课程教的东西,我觉得不值那么多学费。也许学校不好或者我选错了课,原因很多。但在我眼里,那些我敬佩的人,似乎都不是靠这种方式起来的。而且当时我已经厌倦了学校,因为学业对我来说太轻松,拿全A毫不费力,根本感受不到真正的挑战。我想,难道还要再读四年吗?
[Kelsey]: 后来我才明白,本科阶段大部分内容和中小学差不多,无非是听课、记东西;硕士才真正开始深入;博士则是为领域贡献新东西。但我身边从来没人走到那一步,所以我根本没把它列入选项。反倒是A+认证给了我即时反馈,让我感觉自己已经可以进入这个行业、去工作了。所以对我来说,这条路看起来更靠谱,也是我自己能掌控的。
[Q]: 拿到认证后你得到的第一份工作是什么?
[Kelsey]: 当时贝尔南方公司算是美国最大的电信运营商。那时它已经从AT&T分拆出来,负责铺设电话线的是贝尔南方的正式技术人员。但转向高速互联网后,意味着他们必须接触电脑。工会表示他们不碰电脑,甚至不进用户家门,只到户外的分界点就止步。所以他们雇佣承包商来做,承包商需要进屋,做一些简单的布线工作。
[Kelsey]: 另一项工作是你得打开电脑操作。如果他们的电脑够新,可以用USB调制解调器,但它不太稳定,经常坏,得反复上门维修。如果你真想做好,就在电脑背面装一块网卡(Cat 5端口)。那时候是Windows 98,装驱动时大约20%的情况电脑会蓝屏,你就得现场排错,把它恢复上线。顺利的话,有了网卡再接上外置调制解调器连到电话线,高速互联网就通了。
[Kelsey]: 一年后,我开始接企业客户。但到企业客户那里,八台电脑只有一台能上网。我记得老板(比如开小保险公司的)会问:“怎么让其它电脑也上网?”第一次被问时我不知道,我们只负责一台,确保它能用就行。但后来我决定去学习。我去电脑设备商店问,他们说可以买个路由器,就是那种飞船造型的Linksys路由器,大概50美元。我买了一个,研究如何让多台电脑共享一个连接。后来我发现这个不能在工作时间内做,因为我们必须完成规定任务后离开。但我给他们留了我的电话。
[Kelsey]: 我记得自己第一次独立安装时,客户给我开了张支票。我说可以开给Kelsey Hightower,但他们说支票不能开给个人,只能开给公司。我当时就想,那我得有个公司。于是随口编了个“数字网关”公司名,他们写在支票上。我拿着支票去银行,银行说需要营业执照。我当时19岁,只好去办营业执照、开对公账户,才能兑现那张支票。那时我发现这比原来的工作赚钱多。
[Kelsey]: 后面我越来越擅长做网络安装,也很会排障。最后我决定自己干,租了办公场地,在亚特兰大城外开了一家小电脑店。我从分销商买零件,那时大约20岁,采购量不够开账户,但幸好一家我之前常去的小电脑店向分销商推荐了我,说“这是我们的客户,刚开始做”,于是分销商给了我账户,我能买主板、显卡等。客户带小孩来,拿着零件清单要组装电脑,我们就装好卖给他们。同时这也是所有服务请求的总部。
[Kelsey]: 这样做了三四年,同时期(2000-2001年)很多音乐工作室从模拟设备和大调音台转向Pro Tools,需要机架式设备、Mac和转换器,我也承接这些业务。我在店里搭建了一套演示环境,艺术家和音乐家来看了就说要在他们工作室里也做一套,我就接单,把这些也纳入我的服务范围。
[Kelsey]: 创业期间整体上我做得应该说很成功。后来发现谷歌在附近有数据中心,而我认为自己的技能还不错,懂硬件的机架堆叠部分和网络栈的物理层,也懂Linux和Windows,还有创业者的心态。我不觉得有什么是我做不到的。
[Kelsey]: 当时谷歌招数据中心技术人员,薪资还挺高。我当时想:每天只需工作8小时,不用开发票,不管怎样每两周准时拿薪水,还不用自己垫资进货,太爽了吧?所以我去面试了。
[Kelsey]: 其实我对Linux并不精通,但幸运的是我对FreeBSD很熟。面试时我直接说,“我懂FreeBSD”,老实说我觉得自己运气好。其中一轮面试,我看到面试官腿上有个FreeBSD的纹身,我一看就知道有救了。于是我们开始聊FreeBSD的问题,最后我通过了面试。
[Kelsey]: 入职后感觉不错,但节奏有点慢。我只负责一个岗位,很快就能把工作做好。因为我把它看成一种竞赛:谁是这里最好的数据中心技术员?他们的指标是多少?我怎么超越他们?我想学会在数据中心里的每一项工作技能。因为以前做老板时,技能越多,赚得越多。所以我每3到6个月换一次岗,纯粹是为了探索一切、提升能力。算下来每次跳槽大约涨薪25%。起点不高,但几次之后,薪水翻倍了。
[Q]: 当时谷歌的大型数据中心是什么样子?你在那里具体负责什么工作?
[Kelsey]: 当时很多数据中心就像一个大仓库,大约是在一个地方放置20万台服务,所有东西都是机架式的。很多人在数据中心工作过,那里通常一团糟,线缆散落各处,服务器临时添加或移除都很随意。但谷歌很系统化。机器用卡车运来,推进机位时包装完好,你只需连接网线,它们就会PXE启动,然后进行烧机测试。
[Kelsey]: 我的工作内容之一是推着维修车巡视。如果服务器坏了,就需要修复。例如走到第7号机架,拉出一台服务器,看一眼然后说“SATA卡烧了”,然后进入系统,提交预测说“这个SATA控制器需要更换”,接着换掉它,再经历烧机流程,重新加入集群。考核指标就是你预测的准确度。为了快速推进,我不会在这上面浪费时间,因为我想提高指标。于是直接换掉控制器,重新接好所有线缆,滑回机器,走完流程,然后去修下一台。
[Kelsey]: 有个趣事:Tim Hockin在Kubernetes社区很有名,他是网络负责人,当时在谷歌的另一边(更大规模的部分)工作。他早期的项目之一是一个小工具,可以插在主板上,上面大约有9个指示灯,灯光来回闪烁,指示哪些内存插槽可能有问题。
[Kelsey]: 高效的技术人员不会浪费时间运行内存深度测试程序,而是学会使用这个小设备,走到主板前先读取指示灯。比如它显示DIMM 1和DIMM 2有问题,我的推车上有备用的内存条,先把这两个槽换了,重启机器,然后就收工,系统里只记一句“更换了 DIMM 1和2”。
[Kelsey]: 当时的考核指标是:这台机器多久后会被退回返修?如果在30到60天内没有被退回,你就做得很好;如果没有,分数就会低。那些鲁莽的技术人员甚至不认真诊断,换错部件,换错硬盘,结果他们修的机器总是被退回来返修,效率不高。我后来能做到保持90%以上的准确率,同时维修数量是别人的三倍左右。处理大量机器后,我还学会了做网络交换机,还有电源审计,那时我才20出头。
[Q]: 你的绩效被持续度量、得到反馈并据此评估,这种方式感觉比软件工程师(包括谷歌的)要严格得多,无论是评估频率还是期望标准。
[Kelsey]: 我不觉得这些指标让人难受,因为我能自己控制结果。那些指标不是摆在那里没用的。如果我感觉分数在下滑,就会意识到自己有点马虎,诊断机器的方式不够严谨。
[Kelsey]: 于是我开始写额外的Shell脚本,把不同的功能组合起来。我可以同时诊断一台机器的多个部件:在做内存诊断的同时检查SATA阵列和所有硬盘。机器重启时,我一边整理推车,一边再运行一次脚本,多缓存一次结果。这样我就能按自己想要的节奏快速处理,绩效也能一直保持。
[Kelsey]: 所以对我来说,当分数与实际工作表现相匹配时,那就是正向反馈。我把它当作个人工具来用,早上起来查看自己的绩效指标,根据这些详细反馈来调整策略。我很感激当时那种细粒度的反馈,它对我很有帮助。
[Q]: 你说你的职业生涯有两个很大拐点,具体是什么?
[Kelsey]: 谷歌当然是一个大的转折点,创业也是。后来我做网站托管,去了一家叫Pier One的公司。它是从Rackspace拆分出来的,主打完全自动化的自助托管。那是2006年左右,他们的口号是“拖延致命”。
[Kelsey]: 那时很多客户是托管游戏服务器的人,你会去Server Beach这类托管商。Rackspace更像是你买一台服务器,但有很多手动步骤;而Pier One是全自动化的:机器PXE启动后运行PHP脚本。
[Kelsey]: 如果你订购了RAID配置,我们会在机器网络启动时配置RAID,然后把你放到对应的VLAN上,根据订单安装正确的操作系统。整个过程就是填写表单,然后走完所有步骤,大约一小时完成。完成后你会得到一个IP地址、登录凭据,以及邮箱和网站管理等附加服务。你用完后归还机器,我们把它放回资源池,供下一个客户使用。我看到这个流程后觉得自动化的确可行。
[Kelsey]: 另外,我们还会更新RAID控制器的固件。因为一旦PXE启动服务器,系统就在内存中运行,可以访问所有硬件,但还没绑定操作系统,所以你可以做任何操作。配置RAID控制器时,当时还没有干净的API,我们直接运行交叉脚本和命令行工具来把机器配置好。完成后就投入集群。
[Kelsey]: 那时我很年轻,觉得没有什么是我做不到的。我们甚至要自动化Windows 2000服务器,就构建屏幕抓取工具,登录Active Directory,模拟鼠标移动来打补丁。没有什么“需要特定工具才能做”的概念,当时就是做任何必要的事,因为客户每月只付99美元。我没时间花一整周解决一个问题。客户打电话来时,你不知道他们的设置和基础设施,只有几分钟让他们恢复在线。所以每个人都学会快速行动,不抱怨。接到工单就是让你自己解决,有时找队友帮忙。
[Kelsey]: 但真正的转折点来自技术支持岗位。客户打电话说MySQL不工作、DNS不工作,有时甚至描述不清问题。我们都接听电话队列,来电轮流分配。如果你解决不了或解决太慢,就建一张工单。工单积压,换班时越积越多,客户自然不满。三天没有回应是常事。
[Kelsey]: 有一天我说,我不登录电话队列了,只处理工单。我回到创业心态,写小脚本处理工单。看到问题——比如MySQL需要清理数据库,简单,运行脚本,关闭工单;或者升级PHP,关闭工单。工单队列变成零,整天空着。
[Kelsey]: 有人发现我没接电话,经理就把我叫进办公室,问我原因。我说我们不需要所有人都接电话,只要有一个人保持工单队列为零就行。我告诉同事,如果你们快速解决不了,就马上建工单,我来处理。有些人只精通Windows,接到Linux电话就不知道怎么办,我说别担心,放队列里,继续接下一通。我变得非常高效。我把这个流程解释给经理听,他决定采纳,但前提是工单队列必须保持零。
[Kelsey]: 那是我第一次学会区分“活动”和“影响力”:你接了很多电话是活动,但团队工单队列仍然很高;你跳出来说“我不接电话,我保证工单为零”,那是影响力。到周三团队交接时,我们交出一个空队列。后来管理团队决定所有人都这样做。我意识到自己是可以改变流程的,那是一个巨大的转折点。
[Kelsey]: 下一个转折点更多是关于职业成长:不要频繁跳槽。因为几次晋升和产生影响后,我转向下一件事,不必长期承受某些决策的后果,但也不够久到能真正影响企业文化。后来我进入金融服务行业,那是我第一次受到严格限制,因为这类公司不能只追求速度。谷歌要快,要和大公司竞争,用廉价硬件、聪明人,不择手段;网站托管利润薄,也要快;但金融服务则完全不同。
[Q]: 后来你加入了金融服务公司?
[Kelsey]: 是的,那是我第一次工资翻倍。
[Q]: 薪水翻倍,期待值也会随之拉满。结果进去之后有点落差,你会不会忍不住想:是不是我漏掉了什么?这里应该更高级一点吧?
[Kelsey]: 当时太天真,根本不理解走错一步的后果。一开始我在想这些人效率怎么这么低,他们做的事每一步都像在冒险。但其实一次好的变更,花时间等待是值得的。这些我一开始并不懂,只觉得大家都太慢了。我观察他们怎么做部署和配置服务。后来我学会了耐心一点,学会怎么和领导层打交道,怎么和高层沟通,不只是跟工程师聊,还要赢得他们的信任。
[Kelsey]: 我在那里待了大约三年。当时有个任务:用Apache和一些Java插件去对接JBoss实例。每个连接在负载均衡器上占用大量内存。我们正在从大型机迁移到这套新的Java体系,但服务器老是崩溃,事务量处理不了。我看着团队一次次进入变更窗口,一次次失败。CTO说这会让我们赔钱,出现拒付还得交罚款。
[Kelsey]: 有个开发环境用的是Nginx,去掉了所有Java那套东西,直接走HTTP。我读了规范,根本不需要那个Java连接器,内存占用只有原来的一小部分,而且Nginx的线程模型更好。我当时觉得配置已经完美了,把Apache配置移植过来,重定向、路由、旧C代码全都处理好,肯定能跑通。但公司说这没认证,我说Nginx在Red Hat的RPM库里,官方有,这样他们才松口。大约一周后,他们让我进了变更窗口。
[Kelsey]: 金融机构里,变更窗口一般从午夜开始,到早上6点结束,而且得提前通知所有客户我们要改环境了,可能会出点状况。如果影响业务,客户可以反对。拿到许可后,那个窗口是你唯一的机会。如果没按时完成,要么回滚,要么恢复到之前的状态。
[Kelsey]: 我记得把Nginx部署上去之后,整个公司没人有Nginx经验,大多数人反对,觉得这是个馊主意。这时候你的口碑全押在上面,没法躲在团队后面,所有人都在后面看着你。好在领导层表态支持,说他们也在押上自己的职业生涯。大约两小时后,所有东西跑通了。内存占用从32GB降到了约2GB,系统也不再崩溃。
[Kelsey]: 大家不敢相信,都在问这靠谱吗?谁也没底。我们当时测试平台的方式是,派人开车去加油站,用信用卡买点油,看交易能不能落在Oracle数据库里,这样就可以把整个过程串起来跟踪。一旦确认跑通了,大家就觉得好了。但真正让人放心其实要到第二天上午10点左右。凌晨3点我回家也睡不着,脑子里全是:生产环境里这么大一块基础设施被我改了。到10点再看,Nagios警报没一个响。我想,可能真没问题了。
[Kelsey]: 当时我说不上多有战略眼光,但我意识到,如果能把这个做成,不是“我成功了”,而是“我们成功了”,然后再请大家一起吃个饭,那整个团队的认可度就不一样了。那次经历之后我想,成长大概就是这样。不只是拿出正确的方案,还要达成共识、让各方认可,同时你的口碑也押在上面。那次变更真的改变了我对“成功”的理解,也是我的转折点。
[Kelsey]: 后来我自然把Puppet引入了那家公司,用类似的流程把一切自动化都做了一遍。Puppet是配置管理工具。我们之前写一堆Shell脚本,做一些随机操作和半吊子自动化,但大多数时候还是手动。比如来了个工单说要在某台服务器上加个SSH密钥,等软件装好了,你手动复制粘贴输出,关掉工单,第二天又来一个,周而复始。这就是为什么我常说,有些人虽然有20年经验,实际上是一年经验重复了20次。他们从未跨出自动化的一步,也不学新工具、新技能。所以我开始想,也许可以引入Puppet(当时还是 0.2.4.8 的版本)试试看。
[Kelsey]: 在DevOps这个词出现之前,我开始学怎么写代码,给Java生产环境写东西,也写Puppet——用它的DSL,有时得写一点Ruby来创建新资源类型。我也开始参与开源:遇到问题就往上提交修复。这些都在空余时间做,为下一阶段做准备。
[Kelsey]: 我记得经理去参加一个会议,回来跟我说:“Kelsey,我终于知道你在做什么了。”我问是什么,他说:“你在做DevOps。”我当时有点不舒服,心想你凭什么给我做的事命名?其实那时所有人都在谈论DevOps。
[Kelsey]: 经理说他遇到一个叫James Turnbull的人,在Puppet Labs工作,写了我买的那本Puppet入门书。我一听这名字耳熟,回头一看桌上那本书,确实是那本书的作者之一。James当时写了不少技术书,他要来我们公司,经理想让他看看我们是怎么用Puppet的。那时候我已经把Puppet藏在Jira工单后面,用户直接开个Jira单子就行了。所有东西我都打成了RPM包,下拉菜单选包,选环境,然后一切自动完成,结果就出来了。
[Kelsey]: 多数人根本不知道Puppet的存在,他们只知道可以按需获取任何东西。比如你可以申请一台新机器,或者申请一个环境,说要数据库,要IBM MQ消息服务器,要这三个应用,还要配好防火墙,没问题,打开对应的Jira工单,等审批通过。我们有个自动化脚本,我管它叫“Mr. Resetti”,取自一个游戏角色。一旦工单获批,Mr. Resetti就会接管这张工单,提取自定义字段,调用对应的Puppet配置,然后把执行结果更新回工单里。这样一来,产品经理和开发人员几乎可以即时拿到他们想要的东西。
[Kelsey]: 整套系统我们都搭好了,但同事们不知道。我晚上和周末还在给Puppet贡献代码,因为当时的上班时间是不允许的。
[Q]: 那时候很多人大概也不懂开源是什么,对吧?
[Kelsey]: 他们说要求用自己的时间来做,所以我就在晚上和周末搞。后来经理正在向团队介绍James,最后介绍到我。James转向我,说“Kelsey Hightower,我们认识你,很喜欢你贡献的代码”。经理一脸懵:“什么贡献?我们没做贡献啊。”James一边跟我握手,一边像老朋友一样跟我聊天。因为我一直在跟Puppet Labs团队协作,给Puppet做开源贡献。
[Kelsey]: 到了楼上,经理就说看看我们的配置。我说:“James,我们这边有很多Puppet配置清单,用了外部节点分类器,从数据里读取配置参数,我还读了Mark Burgess的承诺理论,把整个体系调通了。但从界面层面来说,我不想让每个人都去学Puppet,所以我们把它跟Jira集成在一起。”
[Kelsey]: 我给他演示了整个工作流程,他就坐那儿看着,说:“我完全没有任何建议,这太棒了。”这就是真正改变游戏规则的地方。后来他邀请我去Puppet大会做演讲,那是我第一次正儿八经地在技术大会上发言,也是第一次感觉在台上能做自己,完全放松。
[Kelsey]: 在俄勒冈州波特兰市的一家小咖啡馆里,Puppet的创始人Luke Kanies问我:“你想来这儿工作吗?”我说当然,100%愿意。薪水涨了不少,还能远程办公。于是我立刻离开亚特兰大。回去后,经理很认可我这些年取得的进步,我也算是闯出了点名堂,他给了我一笔不错的奖金。我说“这很好”,但接着说“我要辞职去Puppet”。
[Kelsey]: 我们之间有过复杂的矛盾,但总的来说,他帮助我成长了。他很惊讶我在这里待了这么久,这对我来说是极大的认可,因为你不只是做出了成绩,而是真正改变了这里的文化,完成了一个完整的循环。
[Kelsey]: 转眼过了七年,Kubernetes出来了。我回到那家公司,发现他们已经在生产环境里用上了Kubernetes,连我当年做的一些老旧工具都还在跑。那次回去给了我一个很重要的反馈:如果你真的产生了影响,那种影响是可以持续很久的。即使我不在那里了,他们依然形成了一种文化:面对新技术,他们知道怎么把它引入自己的技术栈。
[Q]: 当时容器技术开始兴起了吗?你最初是怎么接触容器的?又是在多早的时候意识到它会变得重要且大规模使用的?
[Kelsey]: 当时我并没有觉得它很重要。我当时在Puppet Labs,在那之前,我一直在为Python核心生态做贡献,参与过virtualenv和pip相关的工作,那时候Python就已经有包管理的问题了。所以我当时全身心投入Python。后来学Puppet,又全身心投入Ruby。
[Kelsey]: 我觉得DevOps加配置管理就是一切问题的终极答案。当时是2011、2012年,在我看来,竞争者不过是Puppet、Chef和Ansible这几家。所以我对这条路深信不疑,在Puppet Labs干得很投入。
[Kelsey]: 某种程度上,我觉得我们当时在主导未来。我们去客户公司,让他们理解配置管理,向他们宣讲速度提升、合规性等等的好处。我们是一群把SharePoint转成可执行代码的人,觉得自己才刚开始,根本没有想过这件事不需要再做十年。
[Kelsey]: 我们甚至从VMware拿到资金,把Puppet集成进去,当时Chef也在集成进AWS。所以我们都觉得,这件事终于快要做成了。我们只需要通过DevOps把系统管理员培养成工程师,让他们开始用这些工具就行了。
[Kelsey]: 我最早注意到的是Go语言。那时Ruby已经遇到了性能问题:GIL导致没法同时做多件事,即便能也很费劲。我们试过J Ruby,甚至对Puppet的部分组件用了Closure。当时还在纠结:要不要开始用C++或C写?但那些Ruby贡献者怎么办?我们依赖Ruby Gems等生态,要转型会很困难。
[Kelsey]: 真正让我对Go产生兴趣的,是我写了一个叫Factor的原型。Factor是Puppet的一个agent,负责收集机器信息,比如操作系统版本、内核版本、用户信息等。这些信息会传给Puppet,让配置代码知道当前环境是什么。它原本是用Ruby写的,有时候跑得慢,因为要串行读取所有这些文件。我当时就想,要不试试Go。在Mac上写完代码,编译完用SCP传到一台Linux机器上一跑,速度快得惊人。并行收集所有信息,总耗时只有原来的一小部分。
[Kelsey]: 后来Terraform出现了。在Docker之前,Terraform已经开始改变一些东西了:它也开始用Go写,至少引起了我的注意。Terraform的理念是:谁还在乎单个节点?全部围绕着API走。而我们这些人都是从服务器世界来的,脑子里全是节点上的agent,但云已经开始慢慢成为主流了。
[Q]: Terraform本来就是为云设计的,你可以把云环境基础设施配置成代码。
[Kelsey]: 我们当时还在尝试教Puppet通过节点间接配置云端服务器,这太奇怪了。然后Terraform出现了,Mitchell Hashimoto开发的,他也是早期DevOps的重要人物。他之前做Vagrant时用的Ruby,属于同一个生态,后来分出来单干,做了Terraform。我当时看到他们用Go来写,就觉得值得关注。
[Kelsey]: Docker刚出来时,Puppet还在推动创新,我们鼓励大家换种思路、走出舒适区。但Docker出来后,办公室里大多数人都不把它当回事,觉得它连配置管理都没有,谈不上企业级,像个玩具。他们不是不尊重,只是没人觉得它是威胁。
[Kelsey]: 我当时也没完全看懂,直到我离开Puppet,去另一家公司做工程VP,有机会写Go。当时看到Java占用太重,我就开始用Go重写部分微服务,云开销逐步降下来,最后旧系统淘汰,全部切到Go代码上。那时候我觉得Puppet好像不再那么必要了。
[Kelsey]: 后来我开源了一个叫confd的项目,从etcd里拉取变量,生成刚好够用的配置——只保留了我认为Puppet里有意义的那部分。然后Docker就真正兴起了。对我而言,Docker当时最大的价值在于把每个应用(包括定制应用)打成RPM包。Red Hat的包管理就是那套体系,你用yum install Nginx、yum install Postgres都可以。
[Kelsey]: 但大多数人,即便今天,也不会把自己的应用(比如开发团队自己写的应用)打包成系统包。通常的做法是:把代码复制过去,或者打个tar包。我们很少会去制作正式的Debian包或RPM包。
[Kelsey]: 这其实就是Puppet的价值:不用再做那些打包工作,但仍然能得到一个可重复的交付物。以前我们用Python的virtualenv、Ruby的gems、以及各种虚拟环境做的事,现在全都不用管了。把一切都塞进一个Docker容器里,就省掉了大量开发工具链的维护成本。我觉得这就是它之所以能引起开发者强烈共鸣的原因:终于不用再为多个项目之间的环境混乱头疼了。
[Kelsey]: 接着CoreOS出现了,我当时觉得知道自己想做什么了。但其实我对分布式系统的理解还远不到CoreOS在做的那种程度。
[Q]: CoreOS当时背后的理念是什么?
[Kelsey]: CoreOS的理念是:把Google级别的基础设施能力普及开来。当时已经有Mesos了,论文也发了。但我当时完全看不懂,安装也特别复杂,说服不了自己去用Mesos,而且跟我的思路完全不搭。即便我在Google工作过,他们确实有一套类似的系统(Google Cluster File System),看起来也没Mesos那么复杂。所以我当时就把它忽略了。
[Kelsey]: 但CoreOS是在Docker之上构建的,它的思路是:一个操作系统上面只跑Docker。所有东西都用Go写,再带一个小型KV存储,把配置放进去,它会自动同步到所有机器上。这跟我的confd非常契合。所以我一看到CoreOS,就觉得它更接近未来。
[Kelsey]: 运维人员可以从“极简”的思维方式中学到很多。因为作为系统管理员,我们总是尽量精简操作系统,删掉不需要的东西,让它更安全、更可重复。Docker的做法是:需要变动的部分,放在这里隔离起来。而CoreOS更进一步,它的操作系统就是专为这个设计的。
[Kelsey]: 我在GopherCon上遇到了CoreOS团队,他们看了我的演讲。从Puppet时代起我就明白一个道理:每次演讲都是一次面试。你在台上,别人能看到你是什么样的人。那次大会上,Rob Pike和Go语言的创始人们都在场。大会的组织者是Brian Kettles和Eric St. Martin,他们是社区成员,也是第一次办这种大会。当时Ruby仍然很强势,街对面就在开Ruby大会。
[Kelsey]: 我的演讲题目是《系统管理员的Go语言》,我该怎么向系统管理员证明Go对他们是有好处的?于是我写了一个用Go实现的PXE服务器。当时用的是VMware Fusion,可以创建虚拟机,我配了一张支持iPXE的网卡。我想演示的是:从我笔记本上用Go写的PXE服务器启动多台虚拟机。
[Kelsey]: 在PPT里我放了一段PXE服务器的代码,点一下“Run”按钮,后台就启动了服务。我调出VMware,确认网卡换成了iPXE的,开机。在Go Present的PPT里能看到日志:HTTP在传输镜像文件,虚拟正在启动。台下观众都看呆了,满脸写着:你刚才是怎么做到的?
[Kelsey]: 接着我又加了一些东西,边演示边讲。这对我们这个领域来说是革命性的,终于有一个工具既能写出高性能的东西,又保持命令式编程的简洁性。而且不再局限于脚本,是真的可以构建系统了。
[Kelsey]: 演讲很顺利,大家都在鼓掌。我回头一看,后面站了一堆人,认出其中有Ruby社区的,是写Ruby书的人。散场后他们跟我说,看到Twitter上这边疯了,就专门从隔壁Ruby大会跑过来看。
[Kelsey]: 那一刻我知道,这事成了。CoreOS团队也在现场看着我,因为我在用PXE启动CoreOS。这也印证了我一直说的:每一次演讲都是一次面试。他们当时就觉得我应该加入CoreOS,最终我也去了。也是从那时起,我觉得容器技术真的有戏了。那大概是在Kubernetes出来前的一两年。
[Q]: 接着Kubernetes出现了,你也开始为此做出贡献。
[Kelsey]: 是的。当时很多软件工程师在看台上的人时,心里会疑惑:这人到底懂不懂?他是不是只是个布道者?这个PPT是别人帮他写的吗?是不是别人给他准备好的,他上台跑一遍就行了?我能理解为什么有人会这样想。因为有时候你很难评估自己不具备的技能。
[Kelsey]: 很多软件工程师在这方面其实挺糟糕的,你让他们讲清楚某件事、把概念简化,他们可能做不到;也许他们代码写得确实不错,但演讲、表达、传递理念这一套,他们不一定有。所以当你看到台上那种人时,自然会产生质疑。
[Kelsey]: 在CoreOS的时候,我们在开发自己的集群管理系统,叫Fleet,基于systemd,通过etcd同步配置。CoreOS集群中所有节点都通过etcd通信。我们换了一种思路:不用手动复制,而是把unit文件放进etcd,由对应节点自己拉取并运行。这就是Fleet的雏形。我们大概花了近一年时间构建这套分布式系统。
[Kelsey]: 接着Kubernetes出现了,我们提前一天才收到通知。Google团队说:“我们明天要发布这个东西,这是GitHub仓库,你们要保密,不能提前说。”我当时想:这里面没有我们的事,因为根本没提到CoreOS,只有Google和Red Hat,DockerCon上发布。
[Kelsey]: 那我们能做什么?我熬夜拿到仓库权限,读所有Go代码,没有文档,只能靠猜。把二进制都搞清楚,然后在CoreOS上跑通了。第二天Google正式发布,Docker主题演讲上宣布了这件事,Hacker News上那条公告冲到了第一。然后我们发了一篇帖子,说:“既然他们发布了,那我们来说说怎么在CoreOS上跑,给你示例和命令。”
[Kelsey]: 我还得做几个补丁才真正跑起来,编译一些二进制才能搞定。我一夜没睡,终于搞清楚了怎么编译所有东西。当时他们有个gcloud的SSH脚本,但我没用Google Cloud,所以得自己反向搞清楚。我们在CoreOS上跑,用的是裸金属,所以有PXE启动那些东西。只要把所有组件放在正确的位置,连上我们自己的etcd。我猜API Server会连到etcd,当时还没有Volume和ConfigMap,所以只能先把集群跑起来,然后提交配置,底层它会调用Docker来运行。这些我都能写下来,于是我把整套流程跑通,写了一篇详细的指南。
[Kelsey]: 团队里有人把它发到了CoreOS官网上,然后在Hacker News上重新推了一次,直接冲到了第一。大家都不清楚Google刚发布的东西是什么,然后我发了那篇指南,大家终于知道Kubernetes是什么、怎么装、怎么跑了。于是很多人为了体验Kubernetes,开始下载CoreOS。
[Kelsey]: 大概一周后我有个演讲,我对主办方说原定的主题不讲了,我要讲Kubernetes。当时大家都不知道Kubernetes是什么,我就开始做现场演示,展示kubernetes怎么跑起来。但其实当时CoreOS内部团队还没完全接受,因为我们有自己的路线图。
[Kelsey]: 而且当时也不确定Kubernetes的关注度如何。毕竟Docker是当时的王者,还有Docker Swarm。Google之前也发布过一个叫lmctfy(Let Me Contain That For You)的容器运行时,用C++写的,想跟Docker竞争,但没人关注。直到我开始下班回家后,做一些小贡献,读代码,慢慢摸清楚它的思路,我才觉得:不,Kubernetes有戏。
[Kelsey]: 后来我们做了一个决定:放弃Fleet,之前做的那些也全部放弃,All in Kubernetes。我很高兴我们做了这个决定,因为Alex Polvi后来提出了“Operator”这个概念,后来成为Kubernetes社区的核心思想之一。我和另一个同事还参与了CNI(容器网络接口)的开发,它是Kubernetes的网络层。
[Kelsey]: Kubernetes对我而言意味着:过去15年在数据中心积累的全部经验——学习承诺理论、Puppet、理解它的适用场景和局限、认识到Puppet并非唯一答案——所有这些反复迭代的过程,最终都汇聚到了这里。Kubernetes出现时,我觉得这正是我一直想做的东西。
[Kelsey]: 在之后的某届GopherCon上,一家叫KSA的小公司,某种程度上算是CoreOS的竞争对手,他们提出应该办一个类似GopherCon的Kubernetes大会,我们叫它KubeCon。Joseph设计了logo,CoreOS团队资助了第一届活动。现在12年过去了,CNCF持续运营至今。
[Q]: 你觉得Kubernetes真正取得突破、成为容器编排事实标准的决定性因素是什么?毕竟在CoreOS时我们在做Fleet,Docker有Swarm,就像你之前说的,那时候看起来Kubernetes并不像能发展到今天这个规模。
[Kelsey]: 我认为第一成功要素是Docker。当时有Mesos和Mesosphere,它们有自己的运行时。HashiCorp也推出了Nomad,也有自己的运行时。但真正获得全球共识的运行时是Docker。到那时候,已经存在大量Docker容器、Docker工作流以及Docker Swarm。
[Kelsey]: Docker Swarm的致命弱点在于它的设计:它试图把在单节点上运行良好的Docker API扩展到多系统,但这个API本身并不适合做这种横向扩展。他们不断尝试添加存储、添加网络,但Docker API从未为此设计过。
[Kelsey]: 而Kubernetes团队做得很聪明。他们没有摆出“谷歌比谁都强”的姿态,而是做对了几件事:直接用etcd,直接用Docker。把这些已有的组件,加上Omega论文作者们的经验融合在一起。
[Q]: 所以Omega是Google在Borg之后计划构建的系统,但从未真正落地,对吗?
[Kelsey]: 他们当时有一个“element service”,就像Omega系统里的那个agent,更偏向声明式,里面很多设计思路后来在Kubernetes里都体现出来了。
[Kelsey]: PS:Borg现在仍然是Google管理服务器的方式。当年是数十万台,现在可能是数百万甚至数千万台。据称,他们在这方面是全球做得最好的。所以他们从中积累了大量经验。
[Kelsey]: Borg是一个集硬件、软件、包管理、配置管理于一体的综合系统。它会持续扩展和增长,Google从中积累了大量的认知和经验。你不需要那种过度工程化的高性能方案,特别是当你能给调度器提供更多关于工作负载的元数据时,有一种更简单的调度方式。
[Kelsey]: 更重要的一点是,你不再需要讨论Java、Python还是Ruby的优劣,你只需要关注如何调度Docker容器。这就是我认为Kubernetes成功的首要因素。我们一开始就站在了起跑线上,因为只需要复用已有的Docker容器,而不用重新构建镜像。作为一个新系统,它在很多方面都是在填补空白。一个关键空白是Docker有一个入口点。如果需要一个Ruby应用,它依赖Nginx,你仍然要写一个shell脚本作为入口点,几乎是在模拟一个init系统。
[Kelsey]: 而Kubernetes的做法是:不需要这样,你只需要把应用打包成容器,Kubernetes会以进程树的方式运行它们。对很多人来说,终于有了一个清晰的应用架构思路,像积木一样组合起来,而不需要去打开入口点才能看到具体执行内容。这样就解决了第一个大问题。
[Kelsey]: 第二个解决的关键问题是:我们从“基础设施即代码”演进到了“基础设施即数据”。Kubernetes的思路是:只需要精确地声明你想要的容器是什么、需要多少内存,然后通过状态字段告诉你它们是否在运行。你手工编写一个数据对象,提交给API,控制循环根据这个状态自动协调。
[Kelsey]: 这意味着不管你是用Ruby、Python还是其他任何语言,都可以用IDE写一份YAML,交给工具处理,甚至对YAML做转换后再传给API Server。你可以任意组合资源,而不需要自己写编译器。这对我来说是一个根本性的改变:执行kubectl apply,提交一个对象,它就跑起来了。
[Kelsey]: 最后一点,我认为要归功于Brendan Burns。Kubernetes提供了一流的扩展能力,OpenStack没有做到,Mesos 也没有真正实现。在Mesos里,你有一个调度器,然后在它上面再建另一层调度器,所以可以跑Spark、Hadoop、Marathon,但这些工具都堆在同一个底层之上。Mesos的扩展很重,几乎像是再构建一个完整的系统。
[Kelsey]: Kubernetes强大的地方在于它定义了数据模型,为基础设施提供了类型系统。所以,你不再是写命令式的shell脚本,而是用类型来表达。如果你用过Python这类动态语言,再转到带类型的语言,类型能帮你减少很多认知负担,比如你很清楚函数需要什么类型的输入,传错了就是不行,不会出现字符串被当作整数用的情况。Kubernetes把同样的类型语义带到了基础设施层面。这样一来,自动化就安全多了,因为组合的都是真正有结构、有类型的东西。
[Q]: 我们之所以喜欢类型,而各种语言也都在往这个方向靠,根本原因就是安全,类型能帮你消除一整类错误。
[Kelsey]: 有了类型之后,你可以做静态分析,也可以用其它工具去编译不同组件,确保它们完全匹配。还有验证器会告诉你“这不是正确的对象”、“这不是正确的字段”。有了这些,你就能构建一个非常可靠的部署系统。用kubectl部署容器没问题,但其它东西呢?Kubernetes并没有试图自己去覆盖所有场景。
[Kelsey]: 我记得坐在Brendan Burns旁边,他说:“Kelsey,我给你看个东西。你只需要描述你想要的资源类型,就能扩展Kubernetes。”这个机制出来后,你想管理防火墙?可以,你描述一个防火墙资源,交给Kubernetes,所有工具链自然就能用。你执行kubectl apply就能创建防火墙。于是像cert-manager这样的工具出现了:你只需声明域名和存储位置,剩下的自动完成。这打开了整个生态系统,是真正把社区拉进来的转折点。
[Q]: 后来你加入谷歌,这并不太令人意外,但具体过程是怎样的?你之前也为Kubernetes做了很多贡献,团队也在谷歌,你加入的是Kubernetes团队吗?
[Kelsey]: 不是,那时候我还在CoreOS,Kubernetes已经火了。我到处做主题演讲,做各种原型,推动一些事情的发展,还有一本Kubernetes的书出来了,我是作者之一,和Brendan Burns、Joe Beda一起写的。那时候我其实已经在想“退休”这件事了。
[Kelsey]: 我们的职业生涯里,为了进入这个领域,做了很多努力:考证、参加培训班、学习,有些人上了大学。进来之后,又开始考虑升职路径:高级工程师、首席工程师、杰出工程师。几乎整个职业生涯都在走这条轨迹。在技术领域,不管是个人贡献者还是领导者,都很少真正去想“退休”这个概念,因为可供参照的先例不多,Linus也还没退休。
[Kelsey]: 在CoreOS达到那个高峰的时候,我觉得自己已经做完了所有想做的事。1999年我开始进入这个行业,从一个没有自信的人,到后来自己的照片出现在博物馆大楼外墙的全景图上,我尝到了成名的滋味。看GitHub时会有人来跟我说用过我写的库和命令行工具。我刚开始工作的时候有些人甚至还没出生,而他们后来是通过我写的那些书进入这个行业的。所以那时候我觉得,我已经完成了整个循环,开始思考如何走完最后这一步。
[Kelsey]: 原本我去过NASA的喷气推进实验室,这是我第一次看到一群人用技术不是为了多做几个App,也不是为了往数据库里多写几条数据,而是为了真正推动人类做一些事情。所以我原本打算离开CoreOS后去NASA,甚至已经签了录用意向书,在NASA参与火星任务,负责基础设施团队。然后谷歌打电话来说:“来谷歌吧。”
[Kelsey]: 我当时想:为什么?我一直很敬佩像Brian Grant、Eric Brewer这些人,通过Kubernetes社区有机会和他们共事。某种程度上,我觉得自己已经是团队的一部分了,因为那时我已经有了Kubernetes的提交权限。我想做的那些事,似乎已经都实现了。那我为什么要去那里?去了也就是个大机器里的齿轮,可能会被淹没,整天被安排做Google内部的事情,有什么意义?
[Kelsey]: Google给了我做DevRel的机会,那是我第一次接触。DevRel代表的是自由:没有工单,不需要按某个基准去写代码。但我当时想,我不想要那种自由,我想要的是自己有影响力。Google团队很聪明,他们说:“我们有DevRel这个方向,你可以自己定义要做什么。”
[Kelsey]: 但如果你来了之后真的只做外界认知里的DevRel:去开会、做布道者、写教程和指南,我觉得会被解雇。对我来说,这些都只是活动,不是影响力。我是看重实际结果的人。所以到Google后,我做的第一件事就是找客户在哪里,我们怎么在云上赚钱?我需要弄明白怎么跟客户交流。
[Kelsey]: 于是我找到销售团队说:如果你需要Kubernetes方面的人,随时叫我。我飞去Disney、去Walmart现场,白板讲上6个小时,因为那才是收入来源。全球各地都跑,澳大利亚、加拿大也不在话下,哪怕那里还没有我们的区域,我也去从零开拓。所以我在收入这边的影响力也在不断扩大。
[Q]: 为什么你会说,如果真那样做了会被解雇?
[Kelsey]: 我想确保自己对业务有实质影响。对大多数公司来说,收入就是衡量标准。没有人强迫我这么做,也不是说DevRel团队会拿指标来考核我。是我自己明白收入的价值,所以我愿意走出去,而且能以真实的方式去做。产品影响层面,为什么要局限在Kubernetes?有Serverless、有数据库、有监控,有太多东西可以涉及。所以我想把自己学的东西和全部技能都用上。我在金融服务行业积累的经验,让我有能力担任执行赞助商。
[Kelsey]: 我清楚如何从技术演示走向商业价值,所以参加客户简报时,我不会花时间展示Kubernetes的最新特性,因为那没有意义。他们想知道的是,这些工具如何组合起来,才能产生实际的影响和成果。所以我在那里逐渐成熟,也更懂得如何运作。我在Google推的第一件事,就是“共情工程”。怎么说服其他工程师和他们的经理?怎么能让他们信任我?
[Kelsey]: 第一场共情工程工作坊,我把Kubernetes团队关在一个房间里,让他们手动安装Kubernetes,但不准用任何脚本。在场的有杰出工程师、首席工程师,甚至Borg的参与者和Kubernetes的原始作者。他们折腾了一个小时没搞定。我演示了一遍手工安装流程,然后问:“从工程角度,怎么让这个过程变简单?”于是催生了kubeadm,一个简化安装的命令行工具。同时,我意识到自己不想要一个隐藏所有细节的工具,我想知道底层怎么运作。所以写了《Kubernetes The Hard Way》指南,用来教GitHub的工程师如何在裸机上跑Kubernetes。
[Kelsey]: 正是这套“共情工程”的方法,让我在Google产生了影响力,我不去猜测别人需要什么,而是基于自己的现场经验和企业背景,真正理解他们的处境,然后把大家聚在一起,让他们自己去发现问题、找到答案。
[Q]: 在你晋升为杰出工程师之前,你提过微软和那份offer的事,能具体讲讲吗?
[Kelsey]: 我还是CoreOS时代的那个Kelsey,在Google干得不错,自由度很高,有影响力,也有口碑。所以我觉得自己的轨迹挺好,没必要换。坦白说,我不喜欢Windows,不喜欢Azure,不喜欢.NET,GitHub和VS Code确实不错,但我的整个职业生涯基本都建立在真诚和热爱的基础上,只做自己真正关心的事情。
[Kelsey]: 但我还是去见了微软的人。我当时真正尊重微软的一点是,他们已经收购了GitHub,有了很大的愿景和多样性。我想,这里确实有很多机会,他们也全面拥抱Kubernetes,刚收购了Deis团队,Brendan Burns也在那边。所以我觉得,去了也能产生影响,也有成长空间。于是我决定试试,去参加面试。回家路上,我收到了微软CEOSatya Nadella的邮件。他写了一封很友好的信,表示我在微软会受到尊重,团队会支持我。CEO亲自发邮件支持一个候选人,这本身就让我很意外。
[Kelsey]: 在职业生涯中,工资数字后面加个零这种事并不常见。我还还了个价,结果微软给了一个更高的数字。我当时就觉得,他们不是闹着玩的,所以我当时是真的认真考虑去微软的。
[Kelsey]: 我跟我的经理关系非常好,我跟他说我打算接受这个offer。他看了Offer之后说了一句话:“我想让你知道,你值这个价。”这句话对我来说意义重大,因为他比任何人都了解我,我的强项、弱点、野心和动力,他这么说很重要。他把我的情况往上汇报,Google几小时内就匹配了offer,给了更多股票。我当时想,这下我既有了钱,又留在了想留的公司。我继续做出成绩,后来在Google晋升为杰出工程师,也告知了微软团队。
[Kelsey]: 应该是半年之后,Satya Nadella想见我。我心想微软的CEO居然有时间见我。见面之后他告诉我,他们团队曾列过一份“想要但错过的领导者”名单,我在上面。他说:“我们给你的offer是让你逃离某处的,而不是让你奔向某处的。”这句话很有诗意,我印象深刻。那次见面后,我真正觉得自己属于这个行业。不只是Google或Kubernetes的人,而是整个行业。所以我很安心地准备在一两年后退休。
。。。
