发布于 2026-01-06 3 阅读
0

Kubernetes 简介:它解决了哪些问题?DEV 全球项目展示挑战赛,由 Mux 主办:快来展示你的项目吧!

Kubernetes简介:它解决了哪些问题?

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

封面图片来自Unsplash 的Manuel Nägeli

如今,Kubernetes 是构建云端大型分布式系统最流行的工具之一。许多公司选择在新项目中使用它,或者将现有系统迁移到 Kubernetes 平台。尽管如此,如果您还不了解 Kubernetes,那么这篇文章绝对适合您。

假设我们现在有一台时光机,可以回到2000年代(为了帮助你回忆,试着想想那时你听过什么乐队的歌,或者穿过什么衣服)。我们在一家大公司的软件开发部门工作。我们有一个很棒的新应用创意。

那我们该怎么办?我们可以马上开始编写代码、运行应用程序并展示给潜在用户吗?这取决于具体项目,但可能不行。为什么呢?

这取决于具体公司,但通常来说,这并非易事。主要原因是,在大型组织中,软件/硬件基础设施要么组织混乱,要么申请软件工具、服务器、数据库等的流程过于冗长,以至于从一开始就阻碍了新项目的开展。开发团队无法从一开始就专注于交付业务价值,而是被迫首先回答诸如“数据库在哪里以及如何运行?”、“如何在服务器上部署应用程序?”、“如何设置网络流量?”等等问题。而解决这些问题可能需要数月时间,等待基础设施团队来解决。

信不信由你,当时很多公司都面临着这个问题(有些公司至今仍在为此苦恼)。有一家公司尤其深受其害,他们试图在几个月内开发一款新产品,结果却超时了。这家公司名叫亚马逊

和21世纪初的其他公司一样,亚马逊也在努力寻找提高软件开发团队效率的方法。其中一个主要障碍是,当时没有一款内部工具能够让所有员工都能使用,并且易于使用,还能解决所有基础设施方面的痛点。

换句话说,亚马逊试图找到一种在很短时间内运行和部署应用程序的方法。

这就是亚马逊网络服务(AWS)的由来。最初它只是一个内部工具,但在2006年8月,他们决定将其对外开放,这使其成为首个基础设施即服务(IaaS)服务。

此后,其他公司也开始创建自己的云平台,例如微软 Azure谷歌云IBM 云甲骨文云阿里云红帽 OpenShift Online。同时,也涌现出一些规模较小的新兴公司,例如HerokuDigital Ocean。但迄今为止,它们都没有像AWS那样占据如此巨大的市场份额。

云服务提供商

随着云服务提供商如雨后春笋般涌现,选择哪一家变得越来越难。我指的并非价格或选择最适合企业需求的服务,而是供应商锁定问题。

当公司出于各种原因(例如价格、地域限制、功能限制、性能等)决定更换云服务提供商时,就会发生这种情况。这可能会相当具有挑战性,因为组织首先需要学习如何使用新的云平台,了解其 API,并采用其自动化应用程序部署流程。根据基础设施的复杂程度,这种迁移可能需要数月时间,并且成本可能很高。

所以,我们最终引出了两个主要问题:

  • 如何将硬件基础设施与软件解耦,以便在运行应用程序时将其视为抽象层?
  • 是否有可能制定一套适用于所有云服务商的标准化云操作方法?

为了增添趣味性,近年来出现了两个主要概念,即分布式系统(微服务)和容器化(特别是Docker )。

第一个概念意味着,与其构建一个大型应用程序,不如将其拆分成许多较小的应用程序,每个小应用程序只负责整个系统的一小部分。

Docker彻底改变了应用程序的开发方式。容器技术可以将应用程序及其所有依赖项打包成一个小型可运行文件,无需安装额外的库,即可在任何地方使用。这支持了微服务模式,因为每个应用程序都可以使用不同的编程语言编写,从而使开发团队能够灵活地选择他们最熟悉的技术。

随着这两个概念的兴起,如何轻松运行应用程序变得至关重要,因为现在不再是运行在单个服务器上的大型应用程序,而是数百个运行在Docker容器中的小型微服务,理想情况下,这些微服务还需要以可靠的方式运行。而Kubernetes正是解决这一问题的利器。

但在深入探讨之前,我想先说明一点:Kubernetes并非唯一的容器编排工具。还有其他一些工具,例如Docker SwarmApache MesosRancher。此前,人们并不确定哪一种会成为主流技术,但如今我们可以说Kubernetes已成为事实上的标准。它甚至成为了云原生计算基金会(CNCF)的一部分——该组织致力于为云环境中使用的软件建立标准工具。

Kubernetes 的诞生

Kubernetes是Google在 2014 年创建的。虽然没有确切的创建日期,但通常指的是GitHub 上的第一次提交

k8s标志

从一开始,它就被设计成一个开源项目,其功能与谷歌内部工具Borg有重叠之处。与Kubernetes类似,Borg 的创建初衷是为了管理(编排)容器化应用程序,当时容器技术尚未普及,Docker甚至还未出现。毋庸置疑,谷歌是全球最大的公司之一,拥有庞大的流量,因此需要一种智能的方式来管理数量惊人的应用程序。

基于这一经验,几位谷歌开发人员决定创建一个新的开源工具,它将以更好、更新颖的方式完成类似的工作。

它是如何运作的?

至此,我希望您已经理解了Kubernetes试图解决的问题:它抽象化(虚拟化)了底层硬件基础设施,这样您在部署应用程序时就无需了解其构建方式。这大大简化了开发人员和基础设施维护人员的工作。

为了便于理解,我们来看下面的场景。

你想创建自己的Kubernetes集群。你在地下室找到了 3 台看起来很旧的机器:

  • 树莓派(CPU:1GB,RAM:100MB)

  • 一台旧笔记本电脑(CPU:2GB,内存:200MB),

  • 以及一台“老旧”的服务器(CPU:3GB,内存:300MB)

附注:请不要在意CPU和内存的具体数值,这只是为了演示目的😉。

一旦它们启动并运行,您就可以安装和配置 *Kubernetes,* 因此您应该拥有一个具有 3 个节点的硬件基础设施(节点是一台单独的机器,可以是物理机或虚拟机)。

Kubernetes

现在,如果您想将应用程序部署到此集群,无需考虑应该将其安装在哪台机器上,因为Kubernetes ( K8s ) 会自动处理。要与Kubernetes通信,您可以使用命令行工具 kubectlHTTP API

另一个很棒的功能是,集群内所有节点的所有资源都可以视为一个资源池,即所有底层节点资源的总和。

Kubernetes架构

从架构角度来看, Kubernetes内部包含两个主要部分:控制平面工作节点

来源:[kubernetes.io](https://kubernetes.io/docs/concepts/overview/components/)来源:kubernetes.io

第一个负责管理整个集群,第二个负责托管应用程序(容器)。

控制平面决定每个容器运行在哪个工作节点上,检查集群的健康状态,提供与集群通信的 API 等等。如果某个节点发生故障,而某些容器正在该故障节点上运行,控制平面将负责在其他节点上重新运行这些应用程序。

在控制平面内部,我们可以找到几个较小的组件:

  • kube-api-server——它负责向集群提供 API,它提供端点,验证请求并将其委托给其他组件。

  • kube-scheduler — 不断检查是否有新的应用程序(具体来说是Pod ,K8s 中代表应用程序的最小对象),并将它们分配给节点。

  • kube-controller-manager包含多个控制器,这些控制器监控集群的状态,检查期望状态是否与当前状态相同,如果不同,则与kube-api-server通信以更改状态;此过程称为控制循环,它涉及多个Kubernetes对象(例如节点、Pod 副本等等);每个K8s对象都有一个控制器来管理其生命周期。

  • etcd——它是一个可靠的键值存储数据库,用于存储整个集群的配置数据。

  • 云控制器管理器— 包含特定于云提供商的控制器,仅当您在集群中使用至少一个云服务时才可用。

此外,还有一个上图中未提及但非常重要的组件,那就是DNS。它使集群内的应用程序能够通过特定的(人类可读的)名称而非 IP 地址相互通信。

除了控制平面之外,每个Kubernetes 集群还可以拥有一个或多个工作订单节点,应用程序就运行在这些节点上。为了将它们与 Kubernetes 集成,每个工作订单节点都需要:

  • kubelet — 负责管理节点内的Pod并与控制平面通信(当集群状态需要改变时,这两个组件会相互通信)。

  • kube-proxy — 负责集群内部的网络管理,制定特定规则等。

Kubernetes 对象

在上一节中,我提到了Kubernetes 对象,所以让我们快速了解一下它们是什么。

如前所述,Kubernetes 提供了一种基础设施的抽象。要与集群交互,我们需要使用某种接口来表示集群的状态。这些接口就是Kubernetes对象,它们都代表了整个系统的状态。这些对象通常以 YAML 文件的形式定义,以便可以保存在版本控制系统中,并以声明式的方式描述整个系统,这与基础设施即代码 (IaC)的理念非常接近

物体的种类有很多,但我只想提其中几种最重要的:

  • Pod——如前所述, Pod是Kubernetes中代表应用程序的最小对象。需要注意的是, Pod本身并非容器。它们是对一个或多个容器的封装,这些容器不仅包含运行中的应用程序,还包含一些元数据。

  • 部署负责Pod的生命周期管理,包括创建Pod、升级和扩展 Pod。

  • 服务负责处理网络任务,以及集群内Pod之间的通信。这是因为Pod的生命周期非常短暂,它们可以在很短的时间内创建和销毁。而且,每次 IP 地址都可能发生变化,因此集群内的其他Pod需要不断更新所有依赖应用程序的地址(服务发现)。此外,集群内可能存在同一应用程序的多个实例——服务负责在这些Pod之间进行负载均衡

  • Ingress与 Services 类似,负责网络通信,但层级不同。它是集群的入口,允许外部人员/设备根据Ingress Controller中定义的规则进入集群。

  • 持久卷——为数据存储提供了一种抽象的方式, Pod可能需要这种方式(例如,将一些数据永久保存或缓存)。

  • ConfigMaps——它们保存键值数据,可以将其注入到 Pod 中,例如作为环境变量,从而将应用程序与其配置解耦。

除了标准对象类型之外,Kubernetes还允许创建自定义资源,从而可以创建现有对象的新版本(具有不同的行为),或者创建涵盖不同方面的全新资源。它们广泛应用于一种称为Operator 模式的机制中,例如数据库 Operator 可以定期执行数据库备份(更多 Operator 示例可在OperatorHub.io上找到)。借助 Operator,您可以轻松地根据自身需求定制基础架构,并在Kubernetes之上构建完整的生态系统

Kubernetes 的其他特性

我希望您现在能够理解Kubernetes试图解决的一个主要问题。但这并非全部,它还涉及软件工程的更多方面。

可扩展性

Kubernetes最重要的特性之一(前面已经部分提到过)是它可以根据 CPU 使用率来扩展应用程序实例的数量(水平自动扩展)。

这是云计算的基本概念之一,即根据应用程序的繁忙程度(需要多少 CPU),K8s可以决定运行同一个Pod的额外实例,以防止低延迟甚至崩溃。

可扩展性

例如,夏季电商应用的用户流量通常较低。顾客更倾向于去风景优美的地方度假,而不是购买新商品。但在一年中的某些时期(例如黑色星期五、圣诞节前夕),应用的用户数量会急剧增加,这就需要服务器端投入更多资源。

传统的做法是,为了防止这种情况发生,电子商务公司需要一台大型、昂贵的服务器来处理这种流量高峰,但在一年中的大部分时间里,这些资源都不会被使用(并给公司造成损失)。

这就是为什么云计算(尤其是Kubernetes)如今如此流行的原因。它可以根据应用程序的繁忙程度自动扩展实例数量。您只需为应用程序实际需要的资源(CPU、RAM、内存)付费。

高可用性

大型公司运行应用程序时,都希望确保其可靠性。这意味着他们绝不会接受应用程序哪怕只有一分钟的故障,因为这可能会导致客户流失,进而造成经济损失。

但在现实生活中,很多糟糕的事情都可能发生。例如,一个或多个服务器(节点)可能会宕机。或者,一个或多个微服务可能会因为各种原因而宕机。作为开发人员和基础设施专家,我们应该确保这种情况永远不会发生,但这只是一种徒劳的希望。

幸运的是,Kubernetes提供了一种应对这种情况的机制。例如,如果某个应用程序(Pod)崩溃,它会尝试自动重建该应用程序。或者,如果某个节点宕机,它会自动将所有运行在该节点上的Pod转移到一个新的节点上。

可用性

监测与可观测性

如前所述,Kubernetes能够根据 CPU 使用率自动扩展应用程序实例的数量。它通过Metrics API收集每个应用程序的资源使用情况指标,从而决定何时增加/减少 Pod 的数量。此外,它还可以在仪表盘上提供当前的资源消耗信息。

Minikube 控制面板,用于显示整个集群的 CPU 和内存使用情况Minikube 控制面板,用于显示整个集群的 CPU 和内存使用情况

Kubernetes默认提供Metrics Server来提供此类指标,但也可以替换为自定义的指标服务器。最流行的选择是Prometheus

分布式系统的另一个问题是,很难追踪多个应用程序之间的完整流程。在单体应用中,这很简单,只需在一个地方查看流程日志即可;但在微服务架构中,则需要单独检查每个应用程序。

因此,在Kubernetes中,每个应用程序都应该提供三个基本概念,以实现可观测性,并让集群全面了解它们:

  • 指标——它们提供健康状况信息(本节开头部分已提及),

  • 日志——表示应用程序内部的描述性事件(通常为全文),并写入标准输出;所有应用程序的所有日志都可以使用例如Elastic Stack(Elasticsearch、Kibana、Beats 和 Logstash)聚合到单个位置。

  • 跟踪——允许将多个组件中的多个事件/操作组合在一起,因此单个跟踪表示所有组件(数据库、HTTP 请求等)之间的所有通信;用于跟踪的常用工具是Jaeger

不同的部署类型

软件领域最大的挑战之一是如何可靠地发布应用程序的新版本。这通常是一个如何快速推出新版本(并在必要时快速回滚)并使其对最终用户几乎无感的问题。

有些公司会在周末夜间发布应用。通常他们会提前通知用户,应用将暂时无法使用几个小时,以便用户进行完整升级。对于某些应用场景来说,这种做法完全没问题,但对于那些需要面向全球用户运行一整天的应用来说,就可能比较棘手了。

Kubernetes中,通过实现零停机部署可以轻松克服这个问题。而这可以通过遵循蓝绿部署模式来实现。

这个概念很简单。当我们想发布应用程序的新版本时,在集群内部,我们会将新版本与旧版本并排部署,但最初不会将任何流量路由到新实例。只有在确保没有出现任何问题后,才能将用户流量路由到新版本。

蓝绿色

但这还不是全部。Kubernetes支持更复杂的部署方式,例如金丝雀部署A/B 测试。这两种方式都会同时部署同一服务的两个版本。

首先,流量只会路由到一小部分用户,如果没有出现问题,流量就会稳步增加。

A/B 测试中,我们希望在一段时间内拥有两个不同版本的应用程序,以便我们可以比较哪个版本表现更好(用户流量更大,用户在哪个版本中消费更多等)。

Kubernetes 发行版

如果您或您的公司决定尝试使用Kubernetes,您可能会遇到一个问题——如何运行它?理论上,您可以克隆其源代码,编译并运行它,但这需要耗费大量的时间和专业知识,因此您很可能会认为Kubernetes不适合您。

部分原因是Kubernetes具有高度可配置性。幸运的是,有一些真正的专家提供了预配置的Kubernetes构建版本。你可以把它们想象成 Linux 发行版。它们都经过精心构建,以满足不同的用途,例如:

k8ses

K8s 并非万能灵药!

到目前为止,我一直在试图说服你们Kubernetes的优点,但现在让我们反过来思考。Kubernetes缺点是什么?

首先,我们需要明白,就像所有工具一样,Kubernetes的设计初衷是为了解决特定类型的问题。没错,它现在非常流行,很多公司都在迁移到 Kubernetes 或用它启动新项目,但不要被这些表象所迷惑。它并非万能灵药。

Kubernetes的一大特点是高度可配置性,可以根据自身需求进行调整,但这并非没有代价。它需要大量的专业知识和经验才能正确配置,尤其是在生产环境中,安全性和可靠性至关重要。

此外,它可能会增加基础设施的整体复杂性,尤其是在项目初期规模较小的时候。很多事情都可以简化实现(例如,将所有应用程序运行在单个Tomcat服务器上)。而且,如果没有计划部署大量微服务,可能只有几个较大的应用程序,那么使用这个工具也可能没有必要。

最后,还有大量的 YAML 文件😜 这有点像个玩笑,但我知道有些人不喜欢Kubernetes需要创建大量的 YAML 文件。为了缓解这个问题,可以使用Helm之类的工具,或者前面提到的Kubernetes Operator 模式。

崭新光明的未来

我没有水晶球可以预知 Kubernetes 的未来,但目前我们可以看到它未来可能的发展方向。

首先,它支持构建多云或混合(包括私有云和公有云)环境,使企业能够灵活选择合适的云解决方案。企业不必被迫选择单一云提供商或完全依赖自有数据中心,而是可以混合使用。

另一点是,得益于Kubernetes的可扩展性(自定义资源),它允许在其上构建完整的生态系统。例如,Knative就是一个旨在标准化无服务器框架的项目。此外,Tekton也构建于 Kubernetes 之上,它是一款云原生 CI/CD 工具。

此外,社区正在开发新型的Kubernetes发行版,这些发行版将针对不同的用途进行优化,例如物联网(安装在边缘设备上的轻量级版本)或机器学习。对于后者,已经有一个名为Kubeflow的工具。

最后,Kubernetes对软件开发产生了巨大影响。例如,在 Java 生态系统中,一种新型虚拟机——GraalVM——的出现,极大地缩短了应用程序的启动时间(这在无服务器工作负载中尤为关键)。由于 GraalVM 的出现,涌现出了QuarkusMicronaut等新框架,而Spring等目前广泛使用的框架也得到了更新

结论

我希望读完这篇文章后,您对Kubernetes有了更深入的了解,并明白它如今为何如此重要。如果您喜欢我的文章,或者还有任何不明白的地方,欢迎在评论区留言 😉。

参考

文章来源:https://dev.to/wkrzywiec/introduction-to-kubernetes-what-problems-does-it-solve-4n3d