了解什么是 Kubernetes 以及为什么它对于可靠、可扩展的现代应用程序至关重要的初学者指南。
如果你在 IT 行业,你可能经常听到“Kubernetes”这个名字(在希腊语中意为“飞行员”或“舵手”)。它所做的通常被称为容器编排,尽管人们有时指出它也不是一个准确的术语。
那么它到底是什么?
Kubernetes 确实很受欢迎。根据 CNCF(云原生计算基金会)发布的《 2021 年第一季度_云原生开发状况报告》,全球有 680 万云原生开发者(其中 560 万使用 Kubernetes,比上一年增长 67%),运行着 1020 万个容器。(我们稍后会解释什么是容器。)
CNCF 估计全球有 2680 万开发人员,因此全球约有五分之一的开发人员目前正在使用 Kubernetes。
要了解 Kubernetes 究竟做了什么以及为什么它在现代系统操作中如此受欢迎,我们必须快速回顾一下历史。
单体应用程序
在 2000 年代末,我曾短暂地担任过 Java 工程师。我们拥有的应用程序都是单体应用程序:它们使用 JavaServer Faces 或 Struts 来呈现网页,并使用 Spring 和 Hibernate 来查询数据库。一切都必须编译成一个巨大的.war文件才能在大型 Oracle 服务器上运行。
在一个更大的项目中,我们有一个大约 30 人的团队,分为系统分析师、Web 开发人员和服务开发人员。一切都在一开始就计划好了。然后客户决定在软件中增加一个新的功能分支。我们实际上不得不在我们的架构中插眼,因为我们没有时间修复它,这样做会导致更多的错误和混乱。
顾名思义,一个单体应用程序就像一块(巨大的)石头,所有东西都紧密耦合在一个代码库中。如果您有一个小型应用程序,这是一个合乎逻辑的选择。但随着项目规模的扩大,一切都开始失控。
一个称为面向服务架构 (SOA)的概念,试图通过模块化编程来解决这个问题:应用程序的后端与前端分离并拆分为单独的 Web API(使用 SOAP,简单对象访问协议)。这至少使项目开发更容易。
微服务时代
维护一个庞大的单体应用程序的麻烦只是问题的一半:它们也难以扩展,或者增加服务量来处理更多的用户和数据。当然,您可以部署更多服务器并在它们前面应用负载均衡器/反向代理,但任何更改都会使整个服务中断一段时间。
在最近的一篇文章中[2],Mario Izquierdo 解释了 Twitch 如何在 2010 年代初从 Ruby on Rails 单机应用程序切换到基于 Golang 的微服务架构以解决性能瓶颈。与 SOA 服务仍然是同一后端的一部分不同,微服务本身是独立的迷你应用程序,通常与自己的数据库配对。
具有讽刺意味的是,与 SOA 的 SOAP(简单对象访问协议)相比,最常见的微服务 API 之一 REST(表示状态传输)也更容易实现且更具可扩展性。
现在扩展很容易,您只需按需增加微服务的数量。您还可以在一台服务器上运行多个微服务实例,因为它们需要的资源更少。
虚拟机世界
下一个问题是很难在同一台服务器上运行不同的应用程序。因为您可能无法为每台服务器购买一种类型的应用程序。
例如:您有一个使用 Spring Boot (Java) 编写的微服务和另一个使用 .NET Core 编写的微服务。你有一个使用 React 构建的前端应用程序(它可能在 Node.js 中的服务器上运行)。您甚至可能拥有运行 Flask (Python) 的机器学习服务。尝试让它们一起工作会很麻烦,尤其是在不同类型的服务器上。
虚拟机 (VM) :机器级虚拟化,使用称为hypervisor的模拟器来“模拟”同一台物理机器上的多台机器。每个虚拟机都有自己的操作系统、内存和 CPU 资源。在 VM 中运行的任何内容都将与另一个 VM 中的应用程序完全分离。有许多云平台提供大规模的 VM 托管。
集装箱化
虚拟机很棒,但它们也需要大量资源并且启动速度很慢。Docker 在 2013 年推广的一个新概念 容器化就是一个解决方案。
Docker 容器实际上是轻量级 Linux 虚拟机。不同之处在于容器通过容器运行时共享主机操作系统内核和内存,只有应用程序和文件是分开的(操作系统级虚拟化)。容器启动速度更快,需要的资源更少,因此您可以在同一台机器上运行更多。
在IBM 于 2021 年进行的一项测试中[3],具有四台服务器(16 x 2.1 GHz 内核和 128 GB 内存)的虚拟环境可以运行 8 个 VM 或 33 个容器。多么大的不同!他们还尝试比较 32 个虚拟机与 33 个容器的年度运营成本。后者只需前者的 25%。
Twitch 的 Mario Izquierdo 在接下来的文章[4]中也提到了他们如何逐渐从 Amazon EC2(主机 VM)迁移到 AWS(容器)。被称为“Tiny Bubbles”的容器化微服务分别由不同的团队管理。
容器引擎使面向应用程序的基础设施成为可能:每个容器都是一个包含一个应用程序的气泡。管理容器本质上与管理应用程序相同。由于容器可以使用镜像进行克隆和移植,因此您几乎可以在任何地方随意部署和扩展任何应用程序。
容器编排
容器比虚拟机更容易管理,但当然,大规模手动管理任何东西并不容易。如果你必须运行 100 个微服务实例会发生什么?您必须创建 100 次微服务吗?你怎么知道他们中有没有挂掉的?数以万计的容器呢?
Kubernetes:一个开源项目,正是为此目的而设计的,它来自谷歌内部管理系统 Borg (2003) 和 Omega (2013) 的 15 年经验:
尽管对软件容器的广泛兴趣是一个相对较新的现象,但在 Google,我们十多年来的三个容器管理系统已经大规模管理 Linux 容器十多年,并在那时构建了三个不同的容器管理系统。
Google 开发的第一个统一容器管理系统是我们内部称为 Borg 的系统。它是为管理长期运行的服务和批处理作业而构建的 Omega 是 Borg 的后代,其驱动力是希望改进 Borg 生态系统的软件工程。
谷歌开发的第三个容器管理系统是 Kubernetes。它是在外部开发人员对 Linux 容器越来越感兴趣的世界中构思和开发的,而谷歌已经开发了一项不断增长的销售公共云基础设施的业务。
Borg:以星际迷航中虚构的外星种族命名,已经变得如此强大,以至于它已经在谷歌中以令人难以置信的规模运作:
Google 的 Borg 系统运行来自数千个不同应用程序的数十万个作业,跨越多个集群,每个集群拥有多达数万台机器。
Kubernetes 1.0 于 2016 年发布。它已被包括亚马逊、微软、谷歌、IBM、甲骨文和红帽在内的众多云提供商广泛采用。
我们在开头提到,Kubernetes 所做的被描述为容器编排:它使容器操作自动化,类似于指挥一群音乐家的指挥。
Kubernetes 能做什么在官方文档[5]中列出如下:
服务发现和负载均衡
存储编排(添加任何本地或云服务器)
自动部署和回滚
自动分配 CPU/内存资源
自我修复(需要时启动新容器)
Secret(安全相关信息)和配置管理
Kubernetes 是一种声明性工具:您不必自己运行容器。取而代之的是,您“声明”一个部署清单(如运输订单)以指定在 Kubernetes 环境中运行的容器和数量。
Kubernetes 监控容器,如果其中任何一个崩溃,将创建新容器以匹配您的清单。CPU/内存资源是自动分配的。容器作为单个 API 端点绑定在一起。Kubernetes 还提供了自己的负载均衡器,因此您可以通过简单地更改清单来扩展您的服务。
所以:Kubernetes 可以在几乎没有人为干预的情况下实现可靠、可扩展和自动化的容器操作。它还可以部署在多个物理或虚拟机上,这些物理机或虚拟机可以是云提供商或任何地方的本地服务器。它是现代信息系统大规模管理的关键。
Kubernetes 也为开发者带来了巨大的好处。部署在 Kubernetes 上的应用程序(不仅是微服务,还包括前端应用程序在内的任何应用程序)因其容器性质而具有“云原生”特性,更容易通过简单地更新清单来交换或升级。Kubernetes 可以在不停止服务的情况下执行滚动更新。
在云原生开发状况报告中,33% 的开发人员报告说他们可以每天发布生产代码,31% 每周发布。开发团队现在可以保持竞争力,因为他们可以比其他公司更快地推出新功能。
Kubernetes 集群的简化概述
我们不会在本文中过于技术化,但让我们看看 Kubernetes 集群内部是什么,它是部署的 Kubernetes 环境的基本单元(您的应用程序将部署在其中)。根据需要,您可能有多个集群一起工作。一个集群基本上有以下几个部分:
控制平面——Kubernetes 集群的大脑
工作节点——集群数据平面中虚拟机的物理节点
Pods — 每个 Pod 由一个或多个容器组成,这些容器在一个节点中共享相同的存储和网络
Kubernetes 默认使用 Docker 容器引擎,尽管还有其他选项。
目前,您无需过多担心控制平面或节点中的较小组件,它们是 Kubernetes 如何管理节点和 Pod 的较低级别的细节。
例如,kubelet是运行一个节点的代理,它就像一个向控制平面报告的组长(控制平面实际上是一个主节点的集合)。kube-proxy是每个节点的网络代理。etcd是控制平面本身的持久化数据库,节点控制器和 pod 调度器也在控制平面中,依此类推。
Kubernetes 还允许您将自定义资源(CR) 添加到集群中,该集群的工作方式类似于 pod 或容器,但具有更大的灵活性。
Pokémon GO 的成功
Pokémon GO 是 GKE(Google Kubernete Engine)最早和最大的用户之一。它在单个 Kubernetes 集群中运行容器化的前端应用程序和各种微服务。游戏公司 Niantic 只有一个小团队。发布时最差的估计用户流量是原始估计的 5 倍。
然而到了 2016 年 7 月 6 日,游戏在澳大利亚和新西兰上线后的 15 分钟内,这个数字就飙升到了他们目标的50 倍。
Niantic 寻求 Google 的帮助。谷歌迅速将数千个节点添加到集群中,这已经成为真正的行星规模。游戏顺利通过了万众瞩目的次日美国上线和日本当月下旬上线(是美国上线的 3 倍),数以万计甚至数十万玩家在线,每天 5~10TB 数据。
尽管 Niantic 没想到会如此受欢迎,但由于游戏的容器化设计以及将其部署在云上的决定,它可以在很短的时间内扩大规模。在某些方面,你可以说他们有点预料到了意外。
今天,企业拥有具有数千个工作节点的集群并不少见。Bayer Crop Science[6] 在 240,000 个 CPU 内核和 1.48 PiB 的 RAM 中运行一个包含 15,000 个节点(从 4,500 个节点集群扩大)的集群,以计算有前景的种子基因型。OpenAI[7]有一个 7,500 个节点集群来训练非常复杂的图像和文本 AI 模型。不一定是节点越多越好,但显然是可以实现的。
Kubernetes 为现代系统带来了非凡的可靠性和可扩展性,因此已成为成功的代名词。
概括
Google 的 Kubernetes 是一个开源项目,用于可靠、可扩展的容器操作,并已大规模应用。
容器化是更轻松地部署和扩展应用程序(尤其是微服务)的方式。