如果你从头开始一个新项目——一个新的应用程序、服务或网站——你主要关心的通常不是如何在高可用性的网络规模上运行它。相反,您可能会专注于为您的目标客户打造正确的产品或寻找适合市场的产品。如果您要为初创公司创建 MVP,那么您需要在扩展之前了解它,否则,您为谁进行扩展?如果您是企业的开发人员,您希望确保满足业务的期望和需求。大规模运营充其量只是明天的问题。因此,在选择正确的技术集时,Kubernetes(通常与大型分布式系统相关)现在可能不在您的关注范围内。毕竟,它带来了大量开销:设置和操作集群、容器化您的应用程序、定义服务、部署、负载平衡器等等。这在早期可能看起来像是过度杀伤,您可能认为您的时间最好花在其他任务上,例如编写实际应用程序的前几次迭代。当我们在 2008 年开始构建 Stack Overflow 时,我们没有那个选择。没有 Docker(2013 年),也没有 Kubernetes(2014 年)。云计算还处于起步阶段:Azure 刚刚推出(2008 年),而 Amazon Web Services 大约成立两年。我们构建的内容是为特定硬件设计的,并对其进行了大量假设。现在我们正在对我们的代码库进行现代化改造并迁移到云中,我们必须投入大量工作才能使 Kubernetes 和容器正常工作。经历了这个过程,给了我们一个新的视角。如果您今天正在构建一个新应用程序,那么仔细研究一下使其成为云原生并从一开始就使用 Kubernetes 可能是值得的。设置 Kubernetes 的工作量比您想象的要少。当然,这比稍后重构您的应用程序以支持容器化所需的努力要少。以下是为什么从一开始就在 Kubernetes 上构建您的应用程序可能不再是一个坏主意的三个原因。几年前,当我们在 Stack Overflow 建立我们的第一个内部 Kubernetes 集群时,我们花了将近一周的时间来启动和运行一切:配置虚拟机、安装、配置、配置、配置。一旦集群启动,就会进行持续维护。我们最终意识到 Kubernetes 对我们来说很棒——但我们希望其他人来运行它。如今,Amazon 的 Elastic Kubernetes Service (EKS)、Microsoft 的 Azure Kubernetes Service (AKS) 或 Google 的 Google Kubernetes Engine (GKE) 等托管 Kubernetes 服务允许您在几分钟内设置自己的集群。例如,在 AKS 中,您只需单击门户中的几个按钮并填写几个表单:
这很方便,但您可能不想在工作流结束时实际创建集群。完成向导,但不要单击最后的蓝色“创建”按钮!相反,将您刚刚创建的配置下载为 ARM 模板并将其签入您的源代码控制系统。现在,您拥有两全其美的优势——易用性和基础设施即代码 (IaC)!一旦您在此处进行设置,一旦您开始扩展您的应用程序,除了向您的云提供商写更大的检查之外,几乎没有什么可做的。任何额外的资源分配都很容易。规模带来的问题——容错、负载平衡、流量整形——已经得到处理。在任何时候,你都不会被成功淹没的那一刻;您无需付出太多额外努力就可以使您的应用程序面向未来。如果您的项目成功,那么在早期阶段做出的技术决策很可能在未来数月或数年仍会产生影响。例如,Stack Overflow 最初是用 C# 编写的。 13 年后,它仍然是用 C# 编写的,但它曾经也是。偶尔有人(咳咳)建议我们用 Node.js 重写它。那还没有发生过。对云服务的依赖也是如此。您可以在基础设施即服务 (IaaS) 产品(如 Amazon 的 EC2)之上构建您的新应用程序。或者,您可能开始依赖平台即服务 (PaaS) 产品,例如 Microsoft 的 Azure SQL。但是,您是否愿意在现阶段对其背后的云提供商做出长期承诺?如果您还不知道您的旅程将带您到哪里,也许您更愿意保持云不可知状态一段时间。让我们回到基础设施即代码:将诸如 Terraform 之类的工具投入其中将帮助您在某种程度上保持与云无关。它提供了统一的工具包和配置语言 (HCL) 来跨不同的云和基础架构提供商管理您的资源。然而,您的应用程序不太可能真正与云无关,因为您可以像在家中的互联网或电力供应商一样轻松地切换云提供商。这是 HashiCorp 论坛中关于这个主题的一个很好的讨论:Terraform 真的与云无关吗?正如一位评论者指出的那样: > “Kubernetes 集群是对计算资源进行抽象的一个很好的例子:在不同平台上有许多托管和自我管理的实现,所有这些实现都提供了一个通用的 API 和一组通用的能力。”
这总结得很好!它仍然不是一个完美的抽象。例如,每个云提供商可能都有自己的自定义方式来实现公共负载均衡器和 Kubernetes 中的持久卷等内容。公平地说,如果您在 Kubernetes 上构建,您将在一定程度上保持云不可知论。 Kubernetes 通常被视为管理生产基础设施的一种方式。但是在 Stack Overflow,我们一直在使用它来动态管理我们的测试环境。我们使用 Kubernetes 来托管我们所谓的 PR 环境。只需按一下按钮,每个拉取请求都可以在隔离的测试环境中运行:当我们说“隔离环境”时,我们指的是一切:应用程序本身(带有 PR 分支中的代码更改)及其自己的专用实例SQL Server、Redis、Elasticsearch 和其他服务部分。所有这些都在几分钟内从头开始运行,并在专用命名空间中的少数容器中运行,只为您和任何对您的 PR 感兴趣的人服务。这不是我们发明的;其他组织一直在使用这个概念。这个想法是每个代码更改都会通过拉取请求进入像 Git 这样的版本控制系统。其他开发人员将审查代码,但代码不会说明整个故事。您希望看到代码的运行情况。通常,您必须在本地下载所有代码,编译并运行它。这可能很简单,但如果您正在运行一个从多个存储库中提取代码的大型应用程序,或者仁慈地使用微服务架构,那么您可能需要进行数小时的调试。更好的是,假设您已将一项新功能的所有提交压缩为一个,并将其作为单个 PR 提交。将该 PR 环境作为单个链接发送到销售或营销,以便他们可以预览正在运行的功能。如果您的销售团队想要演示具有特定功能或自定义构建的应用程序,请向他们发送 PR 环境链接。您不必花时间指导技术水平较低的同事完成构建过程。达到这一点需要大量的基础工作。首先,在 Windows Containers 中运行经典的 .NET Framework 并不是我们真正想要追求的途径。理论上这是可能的——自 v1.19 以来,Kubernetes 中已经提供了 Windows 支持——但 Docker/Kubernetes 生态系统实际上更以 Linux 为中心。幸运的是,我们向 .NET Core 的迁移已经在进行中,所以我们决定押注 Linux 容器。当然,这也带来了一系列挑战。当您处理一个 10 年以上的旧代码库时,您可能会发现关于它运行的基础设施的假设:硬编码的文件路径(包括我们最喜欢的:正斜杠与反斜杠)、服务 URL、配置等等在。但我们最终到达了那里,现在我们可以在自动扩展的 Kubernetes 集群上启动任意数量的 Stack Overflow、Stack Exchange 网络和 Teams 产品的测试实例。什么时候能活着!
回顾 Stack Overflow 的早期,拥有这种可用的工具会改变游戏规则。在构建产品的早期阶段,您通常希望尽可能快地构建、衡量和学习。使用容器和 Kubernetes 将允许您为此构建工具,并在您要扩展时为您提供面向未来的支持。那么,您应该从一开始就使用 Kubernetes 吗?可能是!当然,这仍然取决于您的特定项目、您的要求和您的优先事项。但是您是否一直在说“我们不需要 Kubernetes,因为我们还没有适合市场的产品”?仔细看看,也许你会发现自己在说“我们需要 Kubernetes,因为我们还没有适合市场的产品。”标签:kubernetes,软件开发,测试