Kubernetes 为何如此难用?本文给出了 4 个原因,并指出了如何做才能使其易于使用。
介绍
Kubernetes(k8s)在过去几年曾经风靡一时,因为对于运行容器的生产工作负载来说,应用程序编排已经成为事实上的牌局需求。“容器化”应用程序相对简单,大多数称职的 DevOps 工程师都能创建一些 Dockerfile,并都能在准备运行的管道中构建镜像。但是你在哪里“运行”你的 Docker 容器呢?你要部署哪些版本呢?所有的容器是如何相互通信的呢?这就是编排发挥作用的地方,也是大型供应商提供某些选项的地方。在撰写本文时,有两个主要的选项可用:来自 Amazon Web Services(AWS)的弹性容器服务(Elastic Container Service,ECS)及所有基础设施即服务(IaaS)提供商(甚至包括 AWS)提供的 Kubernetes。
编排的希望在于:能够使公司快速、轻松地将其容器化的应用程序交付到测试和集成环境中。理想的情况是“就是这么好用”( “ it just works”),也就是说,在看到应用程序在你面前运行之前,你只需要放松下手指并等待几分钟。理想情况下,你只需要指定运行应用程序所需的最少信息(名称、框架、依赖项等等,但这些最好也是从现有的可用配置文件中读取)即可。这就是编排希望的全部。
显然,从标题上看,我们关注的是 Kubernetes,主要是因为它是无处不在的,唯一例外的其他选项就是 ECS,但这也正好证明了我们论文的观点:Kubernetes 很难使用,因为 AWS 提出了自己的解决方案,并且更易于使用。但是为什么 Kubernetes 这么难用呢?用 K8s 运行应用程序需要多长时间?为什么它不易于使用呢?
Kubernetes 的基础设置很难用
即使大多数公司不会自己构建自己的 Kubernetes 集群,我们也要从基础设施开始。如果你打算使用托管基础设施服务,那么 K8s 将是首选。我敢肯定有些人会在自己笔记本电脑上启动minikube,然后对自己说,“哇,这太简单了!我可以自己做!!”这让我想起了那些在笔记本电脑上启动Elasticsearch容器的人,他们会说,“哇,我们应该在我们的网站实现这个!!”。快进到六个月或一年后的产品发布,简单的“我们自己能做到”的口号变成了“我希望我们不必再这样做了。”
如果你真的要构建自己的 Kubernetes 集群,那么你需要通过所选择的 IaaS 在你的裸机或虚拟机(VM)上构建所有的控制平面(control plane)服务器和服务,然后使用一些奇特的网络配置将它们连接在一起,以将控制平面流量与容器流量分开。你需要配置和运行所有的控制平面软件,并让它们相互通信,稳定运行并进行适当的监控。有悖常理的是,你需要编排用于编排应用程序的容器,但又无需进行大量的编排!当你在 Windows 上运行 minikube 或 Docker Desktop 时,你会看到一个奇妙的幻影,它隐藏了所有使用容器运行容器编排系统的初始状态。
我们甚至还没有谈到 Ingress(通常就是 nginx 实例)和位于控制平面堆栈顶部或旁边的负载平衡器的复杂性。很多时候,你会觉得自己在创建一个完整的基础设施,只是为了让你的基础设施运行(这并不罕见,但肯定不会比你自己尝试编排更好)。我们还没有深入了解基于角色的身份验证控制(Role Based Authentication Controls)和网络策略,这些需要设置成能支持在一个集群中运行的多个应用程序或堆栈。配置点和服务器端设置的数量开始迅速增加,我们甚至还没有开始编排应用程序,这才是我们创建编排系统的意义所在。
让我们假设你确实踏入到了波涛汹涌冰冷刺骨的北大西洋深处,并为自己建造了一艘具有生产价值的船只,可以将你的容器编排成一个实际的应用程序。你回过头来看下日历,从你开始到现在已经过去了六个月或者一年,你现在正在部署一个控制平面,上面写着“你好,世界!”(“Hello World!”)你认为自己成功了,正要庆祝一下,但查看网站上的发布板块时,却发现你又有一个新版的 k8s 要部署!!!
我听到你们在说什么了,“我们是一家大公司,我们有很多 DevOps 工程师,他们是全世界最顶尖的工程人才。我们能够应付所有这些繁重的工作。你只是个爱发牢骚、爱嫉妒的孩子。”我看到你了,Datadog和Ticketmaster。(顺便说一句,你对嫉妒的指责可能是对的。在我的好朋友 Justin Dean 的主题演讲结束时,他展示了所有团队成员的幻灯片,我的照片应该在上面——但我两年前就离开了团队。)对于其他所有人来说,我们一致决定不花六个月或一年的时间来构建自己的控制平面,只是启动我们 IaaS 供应商的托管服务,然后祈祷就好了。
k8s 的 YAML 不是标记语言
如果你已经跳过了前面的内容,并且刚刚启动了一个托管的 k8s 集群,你仍需经历一段漫长而乏味的旅程,会陷入 YAML 这个令人困惑的深渊。YAML 之于文本就像詹姆斯·乔伊斯(James Joyce)的《芬尼根的守灵》(Finnegan’s Wake)之于英语一样。如果你闭上一只眼,只用左手的小拇指和右手的大拇指跟随几个巴西音,把你的脚放在芭蕾舞的第五个姿势,然后再低声背诵二战密码,那么你就会很容易看出 YAML 是相当容易理解的了。一旦你掌握了它的窍门,就像骑自行车在一个冰冻的湖面上,虽然冰只有厘米厚,但狂野的狼在追你。这就像闯入了黄金大劫案时期在诺克斯堡(Fort Knox)举行的远古外星人(Ancient Aliens)鸡尾酒会一样简单。
看,实际上并不难,对吧?假设有一个人在街上向你走来。他是一位 k8s 专家,他将要向你展示部署“你好,世界!”这个 Web 服务是多么简单。对话是这样的:
这只是试着去阅读和理解文件。尝试阅读两个 k8s yaml 示例,然后从头开始自己编写一个。更好的方法是,每天都尝试一种 CodeKata 实践,编写可运行可部署的 Kubernetes 配置。
复制粘贴不是代码
我还在为上一节的内容而暗自发笑,因为这是我每天生活中的日常痛苦点,而直面这种痛苦就像是站在高速公路上 Keanu Reeves 驾驶的公共汽车面前一样。唯一能让我继续埋头苦干的是我意识到使用 NodeJs 会更糟。问题在于 Kubernetes 的文档相当好。你复制粘贴一些“你好,世界!”的示例,输出看起来就可以工作。你开始很擅长使用 kubectl 了。你可以在 YAML 中看到模糊的形状和轮廓。你开始有了信心,相信自己也许能做一些有用的事情。
“让我们尝试将应用程序迁移到 Kubernetes!“当你全身湿淋淋地从浴缸里出来、只裹着一条毛巾时,你大喊大叫,就像阿基米德(Archimedes)在雪城(Syracuse)的街道上奔跑一样。“我们只需在这里复制一些片段,然后粘贴到那里,就可以立即运行我们的应用程序了,”你屏息向同事解释。“行吗?!“他们兴奋地问。“还不行。我是说,还需要缩进下这个片段,删除一个在这个规范中没有使用的片段。然后需要决定是使用部署(deployment)或守护程序(daemonset),但它肯定能行的。我发誓!”
首先,穿上衣服。我完全赞成一边洗澡一边思考 kubernetes YAML 文件,但你需要先穿好衣服。另外,我知道如果你把 Macbook Air 丢进浴缸,结果可能会更另让人激动。其次,这里有一个谜团:你认为运行和部署应用程序需要多少个 YAML 文件?幸好人有十个手指和十个脚趾,这是件好事,因为这可能就是你需要的数量。它们都是相关的,但又并没有真正的关联。如果你喜欢冒险且容易上当受骗,你可以复制粘贴这些片段,但是你不知道这些片段是否兼容。只有四个必填字段,但都是乱码,所有内容都在spec:
(包括spec:
)下。大部分都是重复的,但都又只重复一点。它们在宏观上是相同的部分在微观上其实是不同的。
复制粘贴是一门很棒的艺术,我个人的整个职业生涯都是这样。我很高兴地承认,我生活中的所有产出就像是从 stack overflow 和文档示例中剪下的勒索信(ransom note)。但是,通过拼凑这张脆弱的文本网来做实际上本该很简单且明显的事情是乏味且容易出错的,而且这也是被反复验证的结果。更好的方法是表达你想要什么,并且能够实际地发出可操作的、可执行的代码来产生你想要的结果:即应用程序运行。
所有关于 YAML 的抱怨都很有趣,但实际上这也是原因的征兆:Kubernetes 如此难用,因为接口必须是完全刚性的。K8s 的配置不是活生生的、雄伟的树木,而是一堆枯木。它们比砍掉的木头还要糟糕,它们是整片石化的森林,巨大的岩石堆,上面印着几千年的年轮,已经被保存了数百万年。
不,它们比石化的森林还糟糕!Kubernetes 所展示的是二十一世纪的打孔卡片。每一个 YAML 都是一个孔的集合,这些孔被戳进我们无法阅读和理解的碎木卡中,我们盲目地将这些孔塞进kubectl apply-f
命令中,并且我们希望能以正确的顺序放置它们,在堆栈中的任何地方都没有放错孔。然后,就像过去的机器一样,我们试图通过观察闪烁的灯光和模糊的录音带输出来了解正在发生的事情,并希望能够收集到一些信息。
就像尝试在自动钢琴上重现莫扎特(Mozart)或贝多芬(Beethoven)的音乐一样,是一件乏味、费力、容易出错并且最终无法实现的事情,同样,k8s 的表现形式也会被永久冻结,无法表达性地写出来,而且会无限地演奏同一首曲子。尽管 v1 已经推出两年了,但人们仍然使用 v1beta1,原因是从那时起就没有人再生成新的 k8s 配置了。
很难调试
k8s 最棒的地方在于:当出现问题时,没人知道。我已经数不清有多少次我部署了一些东西,然后投入到其他事情中去了,几个小时后回来,发现部署悄然失败了,没有人通知我。只有几个地方的错误信息是可用的:部署日志中的还是在 pod 日志中?ingress 或 ingress 部署是否还在运行?在数十个 Kind 文件中,日志条目会出现在哪里?根本原因通常是一些不相关的问题:一个错误的、看不见的空格;应该用双引号但没有用;应该用单引号也没有用;或者三周前在修复复制-粘贴问题时,缩进被破坏了。
当然,有一些工具、技术和监控工具可以帮助我们解决这个问题;这就像埃隆·马斯克(Elon Musk)的火星轨道飞行器MVP:“这有用吗?“当然!!一千次,都是的!“它有什么用?“它几乎是你想要的任何东西!”你必须知道要找什么,在哪里找,然后必须知道如何找出解决方法,那么你就必须知道在这数十个文件中哪一行或哪几行需要修复,然后你也必须要知道如何修复它们。
k8s 的另一个优点是你拥有了它就拥有了一切。听着:朋友(friendo),伙计(pal),老兄(buddy),你选择了这种存在。你复制粘贴的“代码”。文档示例可以起作用。我可以在我的笔记本电脑上运行“你好,世界!”,很明显,这都是你的功劳。你就是那个穿着毛巾湿漉漉地跑过办公室喊“Kubernetes!”的人,如果希波克拉底誓言(Hippocratic oath)是“不要伤天害理”(“Do no harm” ),那么 Devops 的誓言可能就是“别做坏事,否则你将被解雇。”
而 k8s 最伟大之处在于:有很多人和公司声称他们知道发生了什么、该怎么办,他们会很乐意拿着你的钱来告诉你这是不是真的。在搜索引擎中输入 Kubernetes,就可以看到所有弹出的广告。本文就是该问题的一部分,也是解决方案的一部分,所以请继续听下去。
最后,解决方案
有几种方法可以使 Kubernetes 更易于使用:
不要用 k8s: run,尖叫着逃命吧
训练所有的人都来解决这个问题(当你完成后再来找我;我可能还活着。也许已经不在了。)
为你的团队雇佣更多的人来解决这个问题(我有空,打电话给我。哈哈,开玩笑的。)
请别人帮你做
等待更长的时间,少花钱多办事,最终选择做一些不可怕的事情
寻找一种解决方案,将你的应用程序部署到适合你的环境中,然后继续进行你实际上从事的任何业务。自动化工具和服务可以帮助你运行应用程序,而无需对上述活动进行投资。总得有人去做,但最好不是你。
原文链接:
评论