K8S丨1. Kubernetes介绍

1. Kubernetes介绍

1.1 初衷

这些年来,谷歌开发出了一个叫Borg的内部系统(后来还有一个新系统叫omega),应用开发者和系统管理员管理那些数以千计的应用程序和服务都受益于它的帮助。除了简化开发和管理,它也帮助他们获得了更高的基础设施利用率,在你的组织如此庞大时,这很重要。当你运行成千上万台机器时,哪怕一丁点的利用率提升也意味着节约了数百万美元,所以,开发这个系统的动机是显而易见的。
在保守BorgOmega秘密数十年之后,2014年,谷歌开放了Kubernetes,一个基于BorgOmega及其他谷歌内部系统实践的开源系统。

1.2 Kubernetes 集群架构

  • 主节点:它承载着Kubernetes控制和管理整个集群系统的控制面板;
  • 工作节点:它们运行用户实际部署的应用;

1.kubernetes介绍-1.png

控制面板

控制面板用于控制集群并使它工作。它包含多个组件,组件可以运行在单个主节点上或者通过副本分别部署在多个主节点以确保高可用性。这些组件是:

  • Kubernetes API服务器:你和其它控制面板都要和它通信;
  • Scheculer:它调度你的应用(为应用的每个可部署组件分配一个工作节点);
  • Controller Manager:它执行集群级别的功能,如复制组件、持续跟踪工作节点、处理节点失败等;
  • etcd:一个可靠的分布式数据存储,它能持久化存储集群配置;

控制面板的组件持有并控制集群状态,但是它们不运行你的应用程序。这是由工作节点完成的。

工作节点

工作节点是运行容器化应用的机器。运行、监控和管理应用服务的任务是由以下组件完成的:

  • Dockerrtk 或者其他的容器类型;
  • Kubelet:它与API服务器通信,并管理它所在节点的容器;
  • Kubernetes Service Proxy(Kube-proxy):它负责组件之间的负载均衡网络流量;

1.3 在 Kubernetes中运行应用

为了在 Kubernetes中运行应用,首先需要将应用打包进一个或多个容器镜像,再将那些镜像推送到镜像仓库,然后将应用的描述发布到 Kubernetes apl服务器。
该描述包括诸如容器镜像或者包含应用程序组件的容器镜像、这些组件如何相互关联,以及哪些组件需要同时运行在同一个节点上和哪些组件不需要同时运行等信息。此外,该描述还包括哪些组件为内部或外部客户提供服务且应该通过单个IP地址暴露,并使其他组件可以发现。

描述信息怎样成为一个运行的容器
当API服务器处理应用的描述时,调度器调度指定组的容器到可用的工作节点上,调度是基于每组所需的计算资源,以及调度时每个节点未分配的资源。然后,那些节点上的 Kubelet指示容器运行时(例如 Docker)拉取所需的镜像并运行容器。
仔细看图1.10以更好地理解如何在 Kubernetes中部署应用程序。应用描述符列出了四个容器,并将它们分为三组(这些集合被称为pod)。前两个pod只包含一个容器,而最后一个包含两个。这意味着两个容器都需要协作运行,不应该相互隔离。在每个pod旁边,还可以看到一个数字,表示需要并行运行的每个pod的副本数量。在向 Kubernetes提交描述符之后,它将把每个pod的指定副本数量调度到可用的工作节点上。节点上的 Cubelets将告知Docker从镜像仓库中拉取容器镜像并运行容器。

保持容器运行
一旦应用程序运行起来, Kubernetes就会不断地确认应用程序的部署状态始终与你提供的描述相匹配。例如,如果你指出你需要运行五个web服务器实例,那么Kubernetes总是保持正好运行五个实例。如果实例之一停止了正常工作,比如当进程崩溃或停止响应时, Kubernetes将自动重启它。

同理,如果整个工作节点死亡或无法访问, Kubernetes将为在故障节点上运行的所有容器选择新节点,并在新选择的节点上运行它们。

1.kubernetes介绍-1.png

扩展副本数量
当应用程序运行时,可以决定要增加或减少副本量,而Kubernetes将分别增加附加的或停止多余的副本。甚至可以把决定最佳副本数目的工作交给Kubernetes。它可以根据实时指标(如CPU负载、内存消耗、每秒查询或应用程序公开的任何其他指标)自动调整副本数。

命中移动目标
Kubernetes可能需要在集群中迁移你的容器。当它们运行的节点失败时,或者为了给其他容器腾出地方而从节点移除时,就会发生这种情况。如果容器向运行在集群中的其他容器或者外部客户端提供服务,那么当容器在集群内频繁调度时,它们该如何正确使用这个容器﹖当这些容器被复制并分布在整个集群中时,客户端如何连接到提供服务的容器呢?

为了让客户能够轻松地找到提供特定服务的容器,可以告诉Kubernetes哪些容器提供相同的服务,而Kubernetes将通过一个静态P地址暴露所有容器,并将该地址暴露给集群中运行的所有应用程序。这是通过环境变量完成的,但是客户端也可以通过良好的DNS查找服务IP。kube-proxy将确保到服务的连接可跨提供服务的容器实现负载均衡。服务的I地址保持不变,因此客户端始终可以连接到它的容器,即使它们在集群中移动。

1.4 使用Kubernetes的好处

如果在所有服务器上部署了Kubernetes,那么运维团队就不需要再部署应用程序。因为容器化的应用程序已经包含了运行所需的所有内容,系统管理员不需要安装任何东西来部署和运行应用程序。在任何部署Kubernetes的节点上,Kubernetes可以在不需要系统管理员任何帮助的情况下立即运行应用程序。

简化应用程序部署

由于Kubernetes将其所有工作节点公开为一个部署平台,因此应用程序开发人员可以自己开始部署应用程序,不需要了解组成集群的服务器。

实际上,现在所有节点都是一组等待应用程序使用它们的计算资源。开发人员通常不关心应用程序运行在哪个服务器上,只要服务器能够为应用程序提供足够的系统资源即可。

在某些情况下,开发人员确实关心应用程序应该运行在哪种硬件上。如果节点是异构的,那么你将会发现你希望某些应用程序在具有特定功能的节点上运行,并在其他的节点上运行其他应用程序。例如,你的一个应用程序可能需要在使用ssd而不是HDDs的系统上运行,而其他应用程序在HDDs上运行良好。在这种情况下,你显然希望确保特定的应用程序总是被调度到有SSD的节点上。

在不使用Kubernetes的情况下,系统管理员将选择一个具有SSD的特定节点,并在那里部署应用程序。但是当使用Kubernetes时,与其选择应用程序应该运行在某一特定节点上,不如告诉Kubernetes只在具有SSD的节点中进行选择。

更好地利用硬件

通过在服务器上装配Kubernetes,并使用它运行应用程序而不是手动运行它们,你已经将应用程序与基础设施分离开来。当你告诉Kubernetes运行你的应用程序时,你在让它根据应用程序的资源需求描述和每个节点上的可用资源选择最合适的节点来运行你的应用程序。

通过使用容器,不再用把这个应用绑定到一个特定的集群节点,而允许应用程序在任何时候都在集群中自由迁移,所以在集群上运行的不同应用程序组件可以被混合和匹配来紧密打包到集群节点。这将确保节点的硬件资源得到尽可能好的利用。

可以随时在集群中移动应用程序的能力,使得Kubernetes可以比人工更好地利用基础设施。人类不擅长寻找最优的组合,尤其是当所有选项的数量都很大的时候,比如当你有许多应用程序组件和许多服务器节点时,所有的组件可以部署在所有的节点上。显然,计算机可以比人类更好、更快地完成这项工作。

健康检查和自修复

在服务器发生故障时,拥有一个允许在任何时候跨集群迁移应用程序的系统也很有价值。随着集群大小的增加,你将更频繁地处理出现故障的计算机组件。

Kubernetes监控你的应用程序组件和它们运行的节点,并在节点出现故障时自动将它们重新调度到其他节点。这使运维团队不必手动迁移应用程序组件,并允许团队立即专注于修复节点本身,并将其修好送回到可用的硬件资源池中,而不是将重点放在重新定位应用程序上。

如果你的基础设施有足够的备用资源来允许正常的系统运行,即使故障节点没有恢复,运维团队甚至不需要立即对故障做出反应,比如在凌晨3点。他们可以睡得很香,在正常的工作时间再处理失败的节点。

自动扩容

使用Kubernetes来管理部署的应用程序,也意味着运维团队不需要不断地监控单个应用程序的负载,以对突发负载峰值做出反应。如前所述,可以告诉Kubernetes监视每个应用程序使用的资源,并不断调整每个应用程序的运行实例数量。

如果Kubernetes运行在云基础设施上,在这些基础设施中,添加额外的节点就像通过云供应商的API请求它们一样简单,那么Kubernetes甚至可以根据部署的应用程序的需要自动地将整个集群规模放大或缩小。

如果你的基础设施有足够的备用资源来允许正常的系统运行,即使故障节点没有恢复,运维团队甚至不需要立即对故障做出反应,比如在凌晨3点。他们可以睡得很香,在正常的工作时间再处理失败的节点。

简化应用部署

前一节中描述的特性主要对运维团队有利。但是开发人员呢?Kubernetes是否也给他们带来什么好处?这毋庸置疑。

如果你回过头来看看,应用程序开发和生产流程中都运行在同一个环境中,这对发现 bug有很大的影响。我们都同意越早发现一个bug,修复它就越容易,修复它需要的工作量也就越少。由于是在开发阶段就修复bug,所以这意味着他们的工作量减少了。

还有一个事实是,开发人员不需要实现他们通常会实现的特性。这包括在集群应用中发现服务和对端。这是由Kubernetes来完成的而不是应用。通常,应用程序只需要查找某些环境变量或执行DNS查询。如果这还不够,应用程序可以直接查询Kubernetes API服务器以获取该信息和其他信息。像这样查询Kubernetes API服务器,甚至可以使开发人员不必实现诸如复杂的集群leader选举机制。

作为最后一个关于Kubernetes带来什么的例子,还需要考虑到开发者们的信心增加。当他们知道,新版本的应用将会被推出时Kubernetes可以自动检测一个应用的新版本是否有问题,如果是则立即停止其滚动更新,这种信心的增强通常会加速应用程序的持续交付,这对整个组织都有好处。