什么是 Kubernetes?

简介

Kubernetes是一个强大的开源系统,最初由Google开发,由云原生计算基金会(CNCF)支持,用于管理集群环境中的容器化应用程序。它旨在为跨各种基础设施管理相关的分布式组件和服务提供更好的方法。要了解更多关于Kubernetes的信息,请浏览下面的指南。如果您正在寻找托管Kubernetes托管服务,查看我们为growth.构建的简单托管Kubernetes服务

在本指南中,我们将讨论什么是Kubernetes,Kubernetes的一些基本概念。我们将讨论该系统的体系结构、它解决的问题,以及它用来处理容器化部署和扩展的模型。

什么是Kubernetes?

Kubernetes ,在其基础层面上,是一个用于跨机器集群运行和协调容器化应用程序的系统。它是一个平台,旨在使用提供可预测性、可伸缩性和高可用性的方法来完全管理集装化应用程序和服务的生命周期。

作为Kubernetes用户,您可以定义应用程序应该如何运行,以及它们应该能够与其他应用程序或外部世界交互的方式。您可以扩展或缩减服务,执行优雅的滚动更新,并在不同版本的应用程序之间切换流量,以测试功能或回滚有问题的部署。Kubernetes提供了接口和可组合的平台原语,允许您以高度的灵活性、强大性和可靠性定义和管理应用程序。

Kubernetes架构

为了理解Kubernetes如何能够提供这些功能,了解它是如何在高级别上设计和组织的是很有帮助的。Kubernetes可以被可视化为一个分层构建的系统,每个较高的层抽象较低的层的复杂性。

在它的基础上,Kubernetes使用共享网络将单独的物理机或虚拟机聚集到一个集群中,以便在每台服务器之间进行通信,无论是物理机还是虚拟机。该Kubernetes集群是配置所有Kubernetes组件、功能和工作负载的物理平台。

Kubernetes集群中的每台机器都在Kubernetes生态系统中扮演一个角色。一台服务器(或高可用部署中的一小组)充当 服务器。该服务器充当集群的网关和大脑,为用户和客户端公开Kubernetes API,检查其他服务器的运行状况,决定如何最好地拆分和分配工作(称为),以及协调其他组件之间的通信(有时称为容器编排)。主服务器充当与集群的主要联系点,负责Kubernetes提供的大部分集中逻辑。

集群中的其他机器被指定为 节点 :负责使用本地和外部资源接受和运行工作负载的服务器。为了帮助实现隔离、管理和灵活性,Kubernetes在 ** 容器** 中运行应用程序和服务,因此每个节点都需要配备容器运行时(如Docker或rkt)。节点从主服务器接收工作指令,并相应地创建或销毁容器,调整网络规则以适当地路由和转发流量。

如上所述,应用程序和服务本身在容器内的集群上运行。底层组件确保应用程序的期望状态与集群的实际状态匹配。用户通过直接与主Kubernetes API服务器或与客户端和库进行通信来与集群交互。要启动应用程序或服务,需要以JSON或YAML格式提交声明性计划,定义要创建的内容以及应该如何管理它。然后,主服务器获取该计划,并通过检查系统的要求和当前状态来确定如何在基础设施上运行该计划。这组按照指定计划运行的用户定义的应用程序代表了Kubernetes的最后一层。

主服务器组件

如上所述,主服务器充当Kubernetes集群的主控制平面。它是管理员和用户的主要联系点,还为相对简单的工作节点提供了许多集群范围的系统。总体而言,主服务器上的组件协同工作以接受用户请求、确定调度工作负载容器的最佳方式、对客户端和节点进行身份验证、调整集群范围的网络以及管理扩展和运行状况检查职责。

这些组件可以安装在一台机器上,也可以分布在多台服务器上。我们将在本节中查看与Kubernetes集群的主服务器相关的每个组件。

etcd

Kubernetes需要运行的基本组件之一是全球可用的配置存储。该团队在CoreOS(操作系统)开发的etcd project,]是一个轻量级的分布式键值存储,可以配置为跨多个节点。

Kubernetes使用etcd存储配置数据,集群中的每个节点都可以访问这些数据。这可用于服务发现,并可帮助组件根据最新信息配置或重新配置自身。它还通过领袖选举和分布式锁定等功能帮助维护集群状态。通过提供简单的HTTP/JSON API,设置或检索值的界面非常简单。

与控制平面中的大多数其他组件一样,etcd可以配置在单个主服务器上,或者在生产场景中分布在多台机器上。唯一的要求是每台Kubernetes机器都可以通过网络访问它。

***APIserver

最重要的主服务之一是API服务器。这是整个集群的主要管理点,因为它允许用户配置Kubernetes的工作负载和组织单位。它还负责确保etcd存储和已部署容器的服务详细信息一致。它充当各组成部分之间的桥梁,以维持集群健康并传播信息和命令。

API服务器实现了REST风格的接口,这意味着许多不同的工具和库都可以很容易地与其通信。名为kubectl的客户端是从本地计算机与Kubernetes集群交互的默认方法。

kube-控制器-管理者

控制器管理器是一项具有许多职责的一般事务。首先,它管理不同的控制器,这些控制器管理集群的状态、管理工作负载生命周期和执行常规任务。例如,复制控制器确保为Pod定义的副本(相同副本)的数量与当前在群集上部署的数量匹配。这些操作的详细信息写入etcd,控制器管理器通过API服务器监视更改。

当看到变化时,控制器读取新信息并执行实现所需状态的过程。这可能涉及放大或缩小应用程序、调整端点等。

kUBE-调度程序

将工作负载实际分配给集群中特定节点的进程是调度程序。该服务读取工作负载的操作需求,分析当前的基础架构环境,并将工作放在一个或多个可接受的节点上。

调度程序负责跟踪每台主机上的可用容量,以确保调度的工作负载不会超过可用资源。调度程序必须知道总容量以及已分配给每台服务器上的现有工作负载的资源。

云管控经理

Kubernetes可以部署在许多不同的环境中,并可以与各种基础设施提供商交互,以了解和管理集群中的资源状态。虽然Kubernetes使用资源的通用表示,如可附加存储和负载均衡器,但它需要一种方法将这些映射到非同构云提供商提供的实际资源。

云控制器管理器充当粘合剂,允许Kubernetes与具有不同功能、特性和API的提供商进行交互,同时在内部维护相对通用的构造。这使得Kubernetes可以根据从云提供商那里收集的信息更新自己的状态信息,根据系统需要的变化调整云资源,并创建和使用额外的云服务来满足提交给集群的工作需求。

节点服务器组件

在Kubernetes中,通过运行容器执行工作的服务器被称为 节点 。节点服务器有一些必要的要求,用于与主组件通信,配置容器网络,并运行分配给它们的实际工作负载。

A容器运行时

每个节点必须拥有的第一个组件是容器运行时。通常,可以通过安装和运行Docker,)来满足这一要求,但也可以使用RKTrunc等替代方案。

容器运行时负责启动和管理容器,即封装在相对隔离但轻量级的操作环境中的应用程序。集群上的每个工作单元在其基本级别上都是作为一个或多个必须部署的容器来实现的。每个节点上的容器运行时是最终运行提交给集群的工作负载中定义的容器的组件。

每个节点与群集组的主要联系点是一个名为kubelet 的小服务。该服务负责与控制平面服务之间传递信息,以及与etcd存储交互以读取配置详细信息或写入新值。

kubelet服务与主组件通信,以向集群进行身份验证,并接收命令和工作。工作以清单 的形式接收,其中定义了工作量和操作参数。然后,kubelet进程负责维护节点服务器上的工作状态。它控制容器运行时根据需要启动或销毁容器。

kube-proxy

为了管理单个主机的子网划分并使服务可用于其他组件,每个节点服务器上都运行一个名为 kube-proxy 的小型代理服务。这个过程将请求转发到正确的容器,可以进行基本的负载平衡,并且通常负责确保网络环境是可预测和可访问的,但在适当的情况下是隔离的。

Kubernetes对象和工作负载

虽然容器是用于部署容器化应用程序的底层机制,但Kubernetes在容器接口上使用额外的抽象层来提供可伸缩性、弹性和生命周期管理功能。与直接管理容器不同,用户定义由Kubernetes对象模型提供的各种原语组成的实例并与之交互。我们将在下面介绍可用于定义这些工作负载的不同类型的对象。

Pods

APod 是库伯内斯处理的最基本的单位。容器本身不会分配给主机。相反,一个或多个紧密耦合的容器被封装在称为Pod的对象中。

Pod通常表示应该作为单个应用程序进行控制的容器。Pod由紧密结合在一起运行、共享生命周期的容器组成,并且应始终安排在同一节点上。它们完全作为一个单元进行管理,并共享其环境、卷和IP空间。尽管它们的实现是容器化的,但您通常应该将POD视为单一的、整体的应用程序,以便最好地概念化集群将如何管理POD的资源和调度。

通常,Pod由一个满足工作负载一般用途的主容器和一些辅助容器(可选)组成,这些辅助容器促进密切相关的任务。这些程序受益于在它们自己的容器中运行和管理,但与主应用程序紧密相关。例如,当检测到外部存储库中的更改时,Pod可能有一个运行主应用程序服务器的容器和一个将文件下拉到共享文件系统的助手容器。通常不鼓励在Pod级别上进行水平缩放,因为还有其他更高级别的对象更适合该任务。

通常,用户不应该自己管理pod,因为它们不提供应用程序通常需要的一些功能(如复杂的生命周期管理和伸缩)。相反,鼓励用户使用更高级别的对象,这些对象使用pod或pod模板作为基本组件,但实现了额外的功能。

复制控制器和复制集

通常,在使用Kubernetes时,您不是使用单个Pod,而是管理多组相同的、复制的Pod。它们是从Pod模板创建的,并且可以由称为复制控制器和复制集的控制器进行水平扩展。

复制控制器 是一个对象,它定义了实例模板和控制参数,通过增加或减少运行副本的数量来水平缩放实例的相同副本。这是在Kubernetes中本地分配负载和提高可用性的一种简单方法。复制控制器知道如何根据需要创建新的Pod,因为与Pod定义非常相似的模板嵌入在复制控制器配置中。

复制控制器负责确保群集中部署的Pod数量与其配置中的Pod数量匹配。如果Pod或底层主机出现故障,控制器将启动新的Pod进行补偿。如果控制器配置中的副本数量发生变化,则控制器会启动或终止容器以匹配所需数量。复制控制器还可以执行滚动更新,将一组Pod逐个滚动到新版本,最大限度地减少对应用程序可用性的影响。

复制集 是复制控制器设计的迭代,在控制器如何识别它要管理的Pod方面具有更大的灵活性。复制集开始取代复制控制器,因为它们具有更强大的副本选择功能,但它们不能像复制控制器那样进行滚动更新以将后端循环到新版本。相反,复制集应该在提供该功能的更高级别的附加单元中使用。

与Pod一样,复制控制器和复制集都很少是您将直接使用的单元。虽然它们构建在吊舱设计之上以增加水平伸缩性和可靠性保证,但它们缺乏在更复杂的对象中找到的一些细粒度生命周期管理功能。

部署

部署负载 是最常见的直接创建和管理工作负载之一。Deployment将复制集用作构建块,从而为组合添加了灵活的生命周期管理功能。

虽然使用复制集构建的部署可能看起来重复了复制控制器提供的功能,但部署解决了实施滚动更新时存在的许多痛点。在使用复制控制器更新应用程序时,用户需要提交新的复制控制器的计划,以取代当前的控制器。在使用复制控制器时,跟踪历史记录、从更新期间的网络故障中恢复以及回滚错误更改等任务要么很困难,要么由用户负责。

部署是一个高级对象,旨在简化复制Pod的生命周期管理。通过更改配置可以轻松修改部署,Kubernetes将调整副本集,管理不同应用程序版本之间的转换,并可选地自动维护事件历史和撤消功能。由于这些特性,部署很可能是您最常使用的Kubernetes对象类型。

有状态集♪

有状态集 是提供有序和唯一性保证的专用实例控制器。主要是,当您有与部署顺序、持久数据或稳定网络相关的特殊要求时,可以使用它们来进行更细粒度的控制。例如,有状态集通常与面向数据的应用程序(如数据库)相关联,即使重新调度到新节点,也需要访问相同的卷。

有状态集通过为每个Pod创建唯一的基于数字的名称来提供稳定的网络标识符,即使Pod需要移动到另一个节点,该名称也会持续存在。同样,当需要重新计划时,可以使用Pod传输永久存储卷。即使在删除Pod以防止意外数据丢失后,卷也会继续存在。

在部署或调整规模时,有状态集根据其名称中的编号标识符执行操作。这提供了更大的可预测性和对执行顺序的控制,这在某些情况下可能很有用。

守护程序设置

守护程序集 是另一种特殊形式的Pod控制器,它在集群中的每个节点(或子集,如果指定)上运行Pod的副本。在部署帮助执行维护并为Kubernetes节点本身提供服务的Pod时,这通常是最有用的。

例如,收集和转发日志、聚合指标以及运行可提高节点本身功能的服务都是守护进程集的热门选择。由于守护程序集通常提供基本服务,并且整个机群都需要守护程序集,因此它们可以绕过Pod调度限制,这些限制阻止其他控制器将Pod分配给某些主机。例如,由于其独特的职责,主服务器经常被配置为不能用于正常的Pod调度,但守护程序集能够逐个Pod覆盖限制,以确保基本服务正在运行。

作业和Cron作业

到目前为止,我们描述的工作负载都假设了一个长时间运行的、类似服务的生命周期。Kubernetes使用称为作业 的工作负载来提供更多基于任务的工作流,运行中的容器在完成工作一段时间后将被期望成功退出。如果您需要执行一次性或批处理,而不是运行连续服务,则作业非常有用。

以工作为基础的是cron工作 。就像Linux和类Unix系统上按计划执行脚本的常规`cron``守护进程一样,Kubernetes中的cron作业提供了一个使用调度组件来运行作业的接口。Cron作业可用于安排作业在将来执行或定期重复执行。Kubernetes cron作业基本上是经典cron行为的重新实现,使用集群作为平台,而不是单一操作系统。

其他Kubernetes组件

除了可以在集群上运行的工作负载之外,Kubernetes还提供了许多其他抽象,帮助您管理应用程序、控制网络和实现持久性。我们将在这里讨论几个更常见的例子。

Kubernetes服务公司

到目前为止,我们一直在使用与Unix类似的传统意义上的术语服务:表示能够响应请求的长期运行的进程,通常是网络连接的。然而,在Kubernetes中,服务 是一个组件,充当基本的内部负载均衡器和实例大使。服务将执行相同功能的POD的逻辑集合组合在一起,以将它们作为单个实体呈现。

这允许您部署一个服务,该服务可以跟踪并路由到特定类型的所有后端容器。内部使用者只需要知道服务提供的稳定端点。同时,服务抽象允许您根据需要向外扩展或替换后端工作单元。服务的IP地址保持稳定,而不管它路由到的Pod发生变化。通过部署服务,您可以轻松获得可发现性,并可以简化您的容器设计。

任何时候,您需要向另一个应用程序或外部使用者提供对一个或多个Pod的访问时,都应该配置服务。例如,如果您有一组运行Web服务器的Pod,这些服务器应该可以从Internet访问,则服务将提供必要的抽象。同样,如果您的Web服务器需要存储和检索数据,您可能需要配置一个内部服务以允许它们访问您的数据库Pod。

虽然默认情况下,服务只能使用内部可路由的IP地址提供,但可以通过选择以下几种策略之一在群集外部提供这些服务。NodePort 配置的工作原理是在每个节点的外部联网接口上打开一个静态端口。流向外部端口的流量将使用内部群集IP服务自动路由到相应的Pod。

或者,负载均衡器 服务类型创建一个外部负载均衡器,使用云提供商的Kubernetes负载均衡器集成来路由到该服务。云控制器管理器将创建适当的资源并使用内部服务服务地址对其进行配置。

卷和永久卷

在许多集装箱环境中,在集装箱重新启动之间可靠地共享数据并保证其可用性是一项挑战。容器运行时通常提供一些机制来将存储附加到容器,该存储将持续到容器的生命周期之后,但实现通常缺乏灵活性。

为了解决这个问题,Kubernetes使用了自己的 抽象,允许数据被pod中的所有容器共享,并保持可用,直到pod终止。这意味着紧密耦合的pod可以轻松地共享文件,而无需复杂的外部机制。Pod中的容器故障不会影响对共享文件的访问。一旦pod被终止,共享卷就被销毁了,所以对于真正持久化的数据来说,这不是一个好的解决方案。

持久卷 是一种抽象更健壮的存储的机制,不受实例生命周期的限制。相反,它们允许管理员为用户可以请求和声明其正在运行的Pod的群集配置存储资源。一旦使用永久卷完成Pod,该卷的回收策略将确定是否保留该卷,直到手动删除或立即与数据一起删除。持久数据可用于防止基于节点的故障,并分配比本地可用存储更多的存储量。

标签和注释

Kubernetes的一个组织抽象与其他概念相关,但在其他概念之外,是标签。Kubernetes中的 label 是一个语义标签,可以附加到Kubernetes对象上,将它们标记为组的一部分。然后,当针对不同的实例进行管理或路由时,可以选择这些实例。例如,每个基于服务器的对象使用标签来标识它们应该操作的pod。服务使用标签来理解它们应该将请求路由到的后端pod。

标签以简单的键-值对的形式给出。每个单元可以有多个标签,但每个单元的每个键只能有一个条目。通常,name键被用作通用标识符,但您还可以根据其他标准对对象进行分类,如开发阶段、公共可访问性、应用程序版本等。

注释 是一种类似的机制,允许您将任意的键值信息附加到对象上。虽然标签应该用于有助于将Pod与选择条件匹配的语义信息,但注释更自由,可以包含较少的结构化数据。一般而言,注释是一种向对象添加丰富元数据的方式,这对选择没有帮助。

结论

Kubernetes是一个令人兴奋的项目,它允许用户在高度抽象的平台上运行可伸缩的、高度可用的容器化工作负载。虽然Kubernetes的架构和内部组件集乍一看可能令人望而生畏,但它们的功能、灵活性和健壮的特性集在开源世界和云本地开发中是无与伦比的。通过了解基本构建块如何组合在一起,您可以开始设计充分利用该平台的功能来大规模运行和管理工作负载的系统,从而构建令人惊叹的云本地应用程序。

Published At
Categories with 技术
comments powered by Disqus