kubernetes资源通过什么区分 如何重塑虚拟机

有很多帖子试图说开始使用 Kubernetes 是多么简单。但是这些帖子中有很多都使用了复杂的 Kubernetes 术语,因此即使是那些具有一些服务器端知识的人也可能会感到困惑。让我在这里尝试一些不同的东西。与其解释一个不熟悉的事情(如何在 Kubernetes 中运行 Web 服务?)与另一个(你只需要一个清单,三个 sidecars 和一堆官话),我将尝试揭示 Kubernetes 实际上是如何自然发展的好的旧部署技术。

如果您已经知道如何使用虚拟机运行服务,希望您会发现最终并没有太大区别。如果您对大规模运营服务完全陌生,那么跟随技术的发展可能也会帮助您了解当代方法。

与往常一样,本文并不全面。相反,它试图总结我的个人经验以及多年来我对该领域的理解是如何形成的

如何使用虚拟机部署服务

早在 2010 年,当我刚刚开始我的软件工程师职业生涯时,使用虚拟机(有时是裸机)部署应用程序是很常见的。

你会从头开始 Linux VM,放下你的PHPweb 应用程序在那里,在它前面放 nginx 或 Apache 反向代理,然后在它旁边运行一堆辅助守护进程和 cronjobs。

这样的机器将代表服务的单个实例,或为简洁起见,服务本身将只是一组命名的相同机器,分布在网络上根据您的业务规模,您可能只有几个、几十个、数百个甚至数千个盒子分布在服务于生产流量的多个服务中。

kubernetes资源通过什么区分 如何重塑虚拟机(1)

服务的抽象将应用程序的复杂性隐藏在单个入口点后面。 服务的抽象将应用程序的复杂性隐藏在单个入口点后面。

使用虚拟机部署服务的挑战

通常,机器群的规模会定义配置(安装操作系统和软件包)、扩展(产生相同的盒子)、服务发现(将盒子池隐藏在一个名称后面)和部署(运送新版本的代码)的方式到盒子)完成了。

如果你是一个小勇敢的与只有几个类似宠物的盒子的公司在一起,您可能会发现自己很少和半手动地配置新盒子。这通常意味着较低的总线系数(由于缺乏自动化)、较差的安全状况(由于缺乏定期补丁)以及可能较长(呃)的灾难恢复。从好的方面来说,管理成本会很低,因为不需要扩展,你的部署会很简单(只需几个盒子来交付代码),而且服务发现会很简单(由于相当静态地址池)。

对于拥有大量盒子的公司来说,现实情况会有所不同。大量机器通常会导致更频繁地需要提供新盒子(更多盒子意味着更多破损)。你会投资自动化(投资回报率会很高)并最终得到许多像牛一样的盒子。作为不断重新创建框的副产品,您会增加总线因子(脚本不能被总线击中)并改善安全状况(自动应用更新和补丁)。不利的一面是,扩展效率低下(由于每日/每年的流量分布不均)、过于复杂的部署(很难将代码快速交付给许多盒子)以及脆弱的服务发现(您是否尝试过大规模运行consulzookeeper?)会导致更高的运营成本。

像 Amazon Elastic Compute Cloud (EC2) 这样的早期云产品允许更快地启动(和关闭)机器;使用packer制作并使用cloud-init定制的机器映像使配置稍微容易一些;puppetansible等自动化工具支持应用基础设施变更并大规模交付新版本的软件。但是,仍有很大的改进空间。

Docker容器解决了什么问题

过去,拥有不同的生产和开发环境是很常见的。这会导致应用程序可能在您的 Debian 机器上本地运行但由于缺少依赖项而无法在生产中的香草 CentOS 上启动的情况。相反,您可能会在本地安装应用程序的依赖项时遇到一些麻烦,但由于高资源需求,为每个服务运行预先配置的虚拟机进行开发是不可行的。

kubernetes资源通过什么区分 如何重塑虚拟机(2)

即使在生产中,虚拟机的庞大性也是一个问题。每个服务都有一个虚拟机可能会导致低于最佳资源利用率和/或相当大的存储和计算开销,但将多个服务放入一个盒子可能会使它们发生冲突。多分钟的启动时间也需要一些改进。

这就是容器的用武之地。就像虚拟机允许将裸机服务器分割成几个更小(和更便宜)的机器一样,容器将一个 Linux 机器分成几十个甚至数百个孤立的环境。

在容器中,您可能会觉得自己拥有一台虚拟机,以及您最喜欢的 Linux 发行版。好吧,至少乍一看。从外部来看,容器只是在主机操作系统上运行并共享其内核的常规进程。

将应用程序及其所有依赖项打包的能力,包括特定版本的操作系统用户空间和库,将其作为容器映像发送,并在安装了 Docker(或类似软件)的任何地方的标准化执行环境中运行,大大提高了工作负载的可重复性.

由于容器边界的轻量级实现,计算开销显着减少,允许单个生产服务器运行数十个可能属于多个(微)服务的不同容器。当然,以降低安全性为代价。

由于不可变和共享的图像层,图像存储和分发也变得更加高效。

在某种程度上,容器也改变了配置的方式。使用(粗心编写的)Dockerfile 和(神奇的)工具,如koJib,责任大大转移给了开发人员,简化了生产 VM 的要求——从开发人员的角度来看,你只需要一个 Docker-(或后来的 OCI-)兼容运行您的应用程序的运行时,这样您就不会再要求安装特定版本的 Linux 或系统包来惹恼您的系统管理员朋友了。

最重要的是,容器加速了运行服务的替代方式的开发。现在有17 种在 AWS 上运行容器的方法,其中大部分是完全无服务器的,在足够简单的情况下,您可以只使用 Lambda 或 Fargate,并从类似牛的盒子中受益!

容器无法解决的问题

容器被证明是一个非常方便的开发工具。构建容器镜像也比构建 VM 更简单、更快速。结合如何有效分离团队之间职责的旧组织问题,它导致典型企业拥有的平均服务数量显着增加,并且每项服务的盒子数量也有类似的增加。

对于我们这些没有跳上 Fargate/Lambda 火车的人来说,它使扩展、服务发现和部署变得更加复杂……

Docker 推广的容器形式实际上具有欺骗性。乍一看,您的每个服务实例似乎都有一个廉价的专用 VM。然而,如果这样的实例需要sidecars(比如在你的网络应用程序前面运行的本地反向代理来终止 TLS 连接或守护进程加载秘密和/或预热缓存),你会立即感觉到复杂容器与虚拟机的区别。

Docker 容器被特意设计为仅包含一个应用程序。一个容器——一个 Nginx;一个容器——一个 Python 网络服务器;一个容器 - 一个守护进程。容器的生命周期将绑定到该应用程序的生命周期。并且特别不鼓励将systemd之类的 init 进程作为顶级入口点运行。

因此,要根据本文开头的图表重新创建一个 VM-box,您需要具有三个具有共享网络堆栈的协调容器盒(好吧,至少本地主机需要相同)。要运行该服务的两个实例,您需要六个容器,分成两组,每组三个!

从扩展的角度来看,这意味着我们需要一起扩展(和缩小)一些容器。部署也需要同步进行。新版本的 Web 应用程序容器可能会开始使用新的端口号,并变得与旧版本的反向代理容器不兼容。我们显然错过了一个像容器一样轻量但又像原始 VM 盒子一样富有表现力的抽象。

此外,容器本身也没有提供任何将框分组为服务的方法。但是他们促成了包厢人数的增加!Docker 竞相用其 Swarm 产品解决这些问题,但另一个系统赢了

Kubernetes 解决了这一切……还是没有?

Kubernetes 设计者显然没有发明新的方法来运行容器,而是决定重新创建基于 VM 的良好旧服务架构,但使用容器作为构建块。好吧,至少这是我的看法。

YMMV,当然,但对我来说,作为一个有 VM 经验的人,一旦我了解了新术语并弄清楚类似的概念,许多最初的 Kubernetes 想法就会开始看起来很熟悉。

Kubernetes Pod 是新的虚拟机

让我们从 Pod 抽象开始。Pod 是您可以在 Kubernetes 中运行的最小的东西。最简单的 Pod 定义如下所示:

apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.20.1 ports: - containerPort: 80

乍一看,上面的清单只是说明要运行什么图像(以及如何命名)。但是请注意containers属性是一个列表!现在,回到那个nginx web app例子,在 Kubernetes 中,您可以简单地将反向代理和应用程序本身放在一个盒子中,而不是为 Web 应用程序容器运行额外的 Pod:

apiVersion: v1 kind: Pod metadata: name: foo-instance-1 spec: containers: - name: nginx # <-- sidecar container image: nginx:1.20.1 ports: - containerPort: 80 - name: app # <-- main container image: app:0.3.2

然而,Pod 不仅仅是容器组。Pod 中容器之间的隔离边界被削弱。与在 VM 上运行的常规进程非常相似,Pod 中的容器可以通过localhost或使用传统的 IPC 方式自由通信。同时,每个容器仍然有一个独立的根文件系统,以保持打包应用程序及其依赖项的好处。对我来说,这看起来像是在尝试同时获取 VM 和容器世界的最佳部分:

kubernetes资源通过什么区分 如何重塑虚拟机(3)

扩展和部署 Pod 很简单

现在,当我们得到新盒子时,我们如何运行多个盒子来组成一个服务?也就是说,在Kubernetes中如何做伸缩和部署?

事实证明,这非常简单,至少在基本场景中是这样。Kubernetes 引入了一个方便的抽象,称为部署。一个最小的 Deployment 定义由一个名称和一个 Pod 模板组成,但指定所需的 Pod 副本数量也很常见:

apiVersion: apps/v1 kind: Deployment metadata: name: foo-deployment-1 labels: app: foo spec: replicas: 10 selector: matchLabels: app: foo template: metadata: labels: app: foo spec: <...Pod definition comes here>

Kubernetes 的伟大之处在于,作为开发人员,您不关心服务器(或 Kubernetes 术语中的节点)。你根据 Pod 组来思考和操作,它们会自动分布(和重新分布)在集群节点上:

kubernetes资源通过什么区分 如何重塑虚拟机(4)

这使得 Kubernetes 成为一种无服务器技术。但与此同时,Pod 的外观和行为与过去熟悉的 VM 非常相似(除了您不需要管理它们),因此您可以在熟悉的抽象中设计和推理您的应用程序:

kubernetes资源通过什么区分 如何重塑虚拟机(5)

内置服务发现

kubernetes资源通过什么区分 如何重塑虚拟机(6)

Kubernetes 的设计者肯定知道,仅仅启动一个盒子的 N 个副本并将其称为服务是不够的。客户端应该能够使用单个(可能是逻辑的)名称访问服务,并且服务发现系统应该能够将此名称转换为特定的 IP 地址(无论是隔离盒子的负载平衡器还是服务的特定实例).

在过去,您需要一个单独的(并且要求很高的)解决方案。但是,Kubernetes 内置了这个功能,而且默认实现还不错!它还可以使用LinkerdIstio等服务网格进行扩展,使其更加强大。

下面是一个简单的 Kubernetes 服务定义:

apiVersion: v1 kind: Service metadata: name: foo spec: selector: app: foo ports: - protocol: TCP port: 80

上面的清单允许app=foo使用default像foo.default.svc.cluster.local. 而且这一切都没有在集群中安装任何额外的软件!

请注意服务定义如何没有在任何地方提及部署。就像 Deployment 本身一样,它根据 Pod 和标签进行操作,这使得它非常强大!例如,Kubernetes 中良好的旧蓝/绿或金丝雀部署可以通过让两个部署对象在单个服务后面运行不同版本的应用程序映像来实现,该服务选择具有公共标签的 Pod:

kubernetes资源通过什么区分 如何重塑虚拟机(7)

现在,最有趣的部分 - 你有没有注意到 Kubernetes 服务与我们基于 VM 的旧服务是如何难以区分的?我很确定这是有意利用现有的机构知识,在这种情况下整个行业都是机构:

kubernetes资源通过什么区分 如何重塑虚拟机(8)

Kubernetes 即服务

那么,Kubernetes 是不是和 VM 一样,只是更简单呢?好吧,是的,不是。套用Kelsey Hightower的话,我们应该区分驾驶汽车的复杂性和修理汽车的复杂性。我们中的许多人都会开车,但很少有人擅长修理引擎。幸运的是,有专门的商店!这同样适用于 Kubernetes。

使用托管的 Kubernetes 产品(如 EKS 或 GKE)运行服务确实与使用 VM 类似但简单得多。但是,如果您必须维护 Kubernetes 集群背后的实际服务器,那就完全不同了……

总结

为了改善在 VM 上运行服务的体验,容器改变了我们打包软件的方式,大大降低了对服务器配置的要求,并启用了其他方式来部署我们的工作负载。但容器本身并没有成为大规模运行服务的解决方案。顶部仍然需要额外的编排层。

Kubernetes 作为容器原生编排系统之一,使用容器作为基本构建块重新创建了过去熟悉的架构模式。Kubernetes 还通过提供用于扩展、部署和服务发现的内置方法来平滑一些传统上的粗糙边缘。如果你今天使用 Kubernetes,你基本上依赖于你在 VM 成为主流的日子里所依赖的相同抽象(实例服务)。

原文出处:https://iximiuz.com/en/posts/kubernetes-vs-virtual-machines/

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页