过去相当长一段时间,我认为自己是一个强烈的Kubernetes怀疑论者。无论是项目还是创业,裸机永远是我的首选,包括运行这个博客的堆栈(https://freeman.vc/notes/architecting-a-blog)。该堆栈是一个持续集成(CI)工具链,在主机上配置了Nginx。它可以处理数量惊人的并发负载,每月10美元的托管费用,它可以很好地与企业级博客平台配合使用,而后者的托管成本要高出两个数量级。我相信一家过早将其架构变得过于复杂的公司不仅会给工程师带来问题,还会给用户带来不稳定。所以我认为带有简单服务器的单个代码库(Monorepo)可能就足够了。此时只需运行一个基本的Docker实例即可最大限度地减少依赖地狱并确保远程配置可在本地开发机器上重现。如果需要增加流量,可以租用更强大的服务器;或者部署一个简单的负载均衡系统来路由到多个后端设备。虽然这正是我在做的事情,但最近用于负载平衡系统背后的几个副项目的单个物理服务器不能满足我的要求——它大部分时间都是空闲的,但它需要几十个带有GPU的虚拟机。这迫使我求助于更复杂的服务器管理解决方案。在使用Kubernetes构建了几个月之后,我必须承认:我越来越喜欢它了。第1天:奋斗我已经在裸机上拥有一个功能完备的后端应用程序。我真的必须用不同的产品重新构建我的堆栈吗?尤其是像Kubernetes这样的超级解决方案?我正在尝试使用实例模板和托管组来设置集群,这相当于谷歌的亚马逊ECS。从控制台启动基本集群相对简单,但我需要一些自定义逻辑来处理SHAS更新时的启动和停止。我将其切换为编写为Python库的GitHubActions管道。在仔细研究了GCP文档后,我想出了一个可行的解决方案,但同时也发现了一些缺点。①大部分必要的部署代码都可以用标准的谷歌客户端库函数实现,这对于参数类型检查和面向对象非常有用。但是,pypi库中有一些命令不受支持。为此,我通过代理连接到GCP公开的RESTWeb服务。为什么会出现这种不匹配?我不知道。在开发过程中处理两种相似但不同的API格式真的很令人困惑。②部署需要在启动时提供Docker镜像,实例模板支持这些镜像。但他们不通过API支持它们,而只能在Web控制台或CLI中支持。通过REST调用实现容器服务需要检查gcloud网络流量并复制包含在实例创建负载中的yaml文件。它带有一条注释警告不要复制yaml文件,因为更改不是语义版本化的并且可能随时更改。③开始觉得自己是在重新实现服务端的核心逻辑。以前一定有人解决过这个问题数百次,考虑到范围相对简单,我可以忽略它,但它不知何故让我烦恼。这里的主要障碍是价格。我需要部署其中两个具有不同容器的集群,这些容器需要由内部负载平衡器进行前置。这允许主后端服务器与静态API端点通信并分配负载。这两个负载平衡系统是对路由后端流量的现有负载平衡系统的补充。这意味着存储成本也开始成倍增加,因为我需要在默认硬盘驱动器配置上有一些缓冲空间。即使在零数据处理的情况下,测试该基础设施的费用也会飙升至每天28美元,这对于一家有现金消耗的公司来说微不足道,但对我来说还不够。第2天:Kubernetes,你好吗?显然,Google的裸机方法看起来前景不佳。它需要太多的手动绑定,以至于成本猛增,所以我开始寻找其他托管产品。如果我在这个单独的数据管理集群中重构计算密集型部分,它可能会将数据处理与机器学习分开。但是,我查看的所有产品都只提供预留GPU。如果我们选择硬件配置,它们会生成虚拟机或专用服务器。如果我们有请求需要处理,动态扩容是没有的。虽然每美元的芯片比谷歌的好,但它与专业计算的结构相同。对于此部署,空闲时间将多于活动时间,因此这是行不通的。我不情愿地深入Kubernetes堆栈,从文档开始,然后用扩展逻辑的核心元素构建了一个POC集群。我什至没有专注于部署实际的应用程序。我只是优先考虑基础设施配置,这是让我亲身体验Kubernetes设计的好方法。第3天:晚餐费用GCP和AWS都对Kubernetes控制平面收取每月70美元左右的费用。控制平面与每个托管的Kubernetes集群捆绑在一起,因此它甚至在使用计算资源之前就设定了业务成本的底线。GCP增加这项费用时引起了轩然大波,因为它成倍增加了用户使用单独集群的成本。虽然Azure是唯一仍然拥有免费控制面板的主要提供商,但我发现其托管产品的功能少于其他两个。因此,我不希望提供商的控制面板永远免费。虽然GCP仍然在单个区域提供免费仪表板,但它主要用于Beta测试。此外,这种单区域支持与使用裸机的专用服务器相同,虽然用户可以在托管设备的任何区域进行托管,但如果该区域出现问题(或者如果底层服务器),你运气不好。如果要在裸机上做多区域负载均衡,那么硬件成本会翻倍。但即使有开销,设置托管集群仍然比使用特定于云的产品自己构建一个集群便宜得多。GCP上的内部负载平衡每月花费18美元,推出4项服务来创建内部DNS网格将超过控制面板的成本。而我使用Google产品的简单组合从头开始制作的原型成本接近18美元。我目前正在做的是,我开始在这个免费的区域集群中托管我的所有项目。到目前为止,它完全可靠,没有停机时间。如果没有机器学习相关的计算资源,平均成本约为每天6美元。其中大部分(85%)用于3个CPU、11.25GB内存集群的计算、内存和存储资源。其余费用用于存储和Docker映像托管。第4天:理解术语我发现Kubernetes的一个有用的心智模型是将容器编排视为对不同原语的操作。一些原语包括:Pod是Docker容器或容器化的应用程序逻辑;服务控制同一pod的重复副本,因此如果pod在托管期间崩溃,则可以确保冗余;入站控制器定义外部连接(例如常规Web请求)如何流入集群,到达正确的服务;节点是物理硬件,是运行1+个pod的实际服务器;集群是一组具有相似特征的一个或多个节点,指示哪些pod放置在哪里等信息。还有操作:获取(get)一个原语下可用的实例列表;描述(describe)这些元素的定义,并查看当前状态;查看活动或失败对象的日志(日志);一切都围绕着这些逻辑对象,这些实体中的大多数都具有与其关联的相同CLI行为:$kubectlgetpodNAMEREADYSTATUSRESTARTSAGEbackend-deployment-6d985b8854-45wfr1/1Running018hbackend-deployment-6d985b8854-g7cph1/1运行018hbackend-deployment-6d985b8854-mqtdc1/1运行018hfrontend-deployment-5576fb487-7xj5r1/1运行027hfrontend-deployment-5576fb487-8dkvx1/1运行027hfrontend-deployment-5576q/6f128s027h$kubectlgetserviceNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEbackendClusterIP10.171.351.3
