Kubernetes 架构指南

了解 Kubernetes 架构的不同组件如何协同工作,以便您更好地诊断问题、维护健康的集群并优化您自己的工作流程。
34 位读者喜欢这篇文章。
Parts, modules, containers for software

Opensource.com

您使用 Kubernetes 来编排容器。这是一个很容易说的描述,但理解这实际上意味着什么以及如何实现它完全是另一回事。如果您正在运行或管理 Kubernetes 集群,那么您会知道 Kubernetes 由一台被指定为控制平面的计算机和许多其他被指定为工作节点的计算机组成。它们中的每一个都有一个复杂但强大的堆栈,使编排成为可能,熟悉每个组件有助于理解它如何运作。

控制平面组件

您在称为控制平面的机器上安装 Kubernetes。它是运行 Kubernetes 守护程序的机器,也是您在启动容器和 Pod 时与之通信的机器。以下章节描述了控制平面组件。

Etcd

Etcd 是一个快速、分布式且一致的键值存储,用作持久存储 Kubernetes 对象数据(如 Pod、复制控制器、密钥和服务)的后备存储。Etcd 是 Kubernetes 存储集群状态和元数据的唯一位置。唯一直接与 etcd 通信的组件是 Kubernetes API 服务器。所有其他组件都通过 API 服务器间接读取和写入 etcd 数据。

Etcd 还实现了监视功能,该功能为异步监视密钥更改提供了基于事件的接口。一旦您更改密钥,其监视器就会收到通知。API 服务器组件严重依赖此功能来获得通知,并将 etcd 的当前状态移向所需状态。

为什么 etcd 实例的数量应该是奇数?

您通常会在高可用性 (HA) 环境中运行三个、五个或七个 etcd 实例,但为什么呢?因为 etcd 是一个分布式数据存储。它可以水平扩展,但您也需要确保每个实例中的数据是一致的,为此,您的系统需要就状态达成共识。Etcd 使用 RAFT 共识算法 来实现这一点。

该算法需要大多数(或法定人数)才能使集群进入下一个状态。如果您只有两个 ectd 实例,并且其中任何一个实例发生故障,则 etcd 集群无法转换到新状态,因为不存在多数。如果您有三个 ectd 实例,则一个实例可能会发生故障,但仍然有多数实例可用于达到法定人数。

API 服务器

API 服务器是 Kubernetes 中唯一直接与 etcd 交互的组件。Kubernetes 中的所有其他组件都必须通过 API 服务器才能处理集群状态,包括客户端 (kubectl)。API 服务器具有以下功能

  • 提供了一种在 etcd 中存储对象的一致方法。
  • 执行这些对象的验证,以便客户端无法存储配置不正确的对象(如果它们直接写入 etcd 数据存储,则可能会发生这种情况)。
  • 提供 RESTful API 以创建、更新、修改或删除资源。
  • 提供 乐观并发锁定,因此在发生并发更新时,其他客户端永远不会覆盖对对象的更改。
  • 执行客户端发送的请求的身份验证和授权。它使用插件来提取客户端的用户名、用户 ID、用户所属的组,并确定经过身份验证的用户是否可以对请求的资源执行请求的操作。
  • 如果请求尝试创建、修改或删除资源,则负责 准入控制。例如,AlwaysPullImages、DefaultStorageClass 和 ResourceQuota。
  • 实现监视机制(类似于 etcd),供客户端监视更改。这允许 Scheduler 和 Controller Manager 等组件以松散耦合的方式与 API 服务器交互。

控制器管理器

在 Kubernetes 中,控制器是控制循环,用于监视集群的状态,然后在需要时进行或请求更改。每个控制器都尝试使当前集群状态更接近所需状态。控制器跟踪至少一种 Kubernetes 资源类型,这些对象具有表示所需状态的 spec 字段。

控制器示例

  • 复制管理器(ReplicationController 资源的控制器)
  • ReplicaSet、DaemonSet 和 Job 控制器
  • Deployment 控制器
  • StatefulSet 控制器
  • 节点控制器
  • 服务控制器
  • 端点控制器
  • 命名空间控制器
  • PersistentVolume 控制器

控制器使用监视机制来获取更改通知。它们监视 API 服务器以了解资源更改,并为每个更改执行操作,无论是创建新对象还是更新或删除现有对象。大多数时候,这些操作包括创建其他资源或更新被监视的资源本身。尽管如此,由于使用监视并不能保证控制器不会错过事件,因此它们还会定期执行重新列出操作,以确保它们没有错过任何内容。

Controller Manager 还执行生命周期功能,例如命名空间创建和生命周期、事件垃圾回收、已终止 Pod 垃圾回收、级联删除垃圾回收 和节点垃圾回收。有关更多信息,请参阅 云控制器管理器

调度器

调度器是一个控制平面进程,用于将 Pod 分配给节点。它监视新创建的且未分配节点的 Pod。对于调度器发现的每个 Pod,调度器都负责为该 Pod 找到最佳运行节点。

满足 Pod 调度要求的节点称为可行节点。如果没有合适的节点,则 Pod 将保持未调度状态,直到调度器可以放置它为止。一旦找到可行的节点,它就会运行一组函数来对节点进行评分,得分最高的节点将被选中。然后,它会将选定的节点通知 API 服务器。他们称此过程为绑定。

节点选择是一个两步过程

  1. 过滤所有节点的列表以获得您可以调度 Pod 的可接受节点列表(例如,PodFitsResources 过滤器检查候选节点是否具有足够的可用资源来满足 Pod 的特定资源请求)。
  2. 对从第一步获得的节点列表进行评分并对其进行排名以选择最佳节点。如果多个节点具有最高分,则循环轮询过程可确保 Pod 均匀地部署在所有节点上。

调度决策要考虑的因素包括

  • Pod 是否请求硬件/软件资源?节点是否报告内存或磁盘压力状况?
  • 节点是否具有与 Pod 规范中的节点选择器匹配的标签?
  • 如果 Pod 请求绑定到特定主机端口,该端口是否可用?
  • Pod 是否容忍节点的污点?
  • Pod 是否指定节点亲和性或反亲和性规则?

调度器不指示选定的节点运行 Pod。调度器所做的只是通过 API 服务器更新 Pod 定义。然后,API 服务器通过监视机制通知 kubelet Pod 已调度。然后,目标节点上的 kubelet 服务看到 Pod 已调度到其节点,它会创建并运行 Pod 的容器。

[ 阅读下一篇:Kubernetes 如何创建和运行容器:图解指南 ]

工作节点组件

工作节点运行 kubelet 代理,这使其能够被控制平面招募以处理作业。与控制平面类似,工作节点使用几个不同的组件来实现这一点。以下章节描述了工作节点组件。

Kubelet

Kubelet 是在集群中每个节点上运行的代理,负责在工作节点上运行的所有内容。它确保容器在 Pod 中运行。

kubelet 服务的主要功能是

  • 通过在 API 服务器中创建节点资源来注册其运行所在的节点。
  • 持续监视 API 服务器中已调度到该节点的 Pod。
  • 通过使用配置的容器运行时来启动 Pod 的容器。
  • 持续监视正在运行的容器,并将它们的状态、事件和资源消耗报告给 API 服务器。
  • 运行容器活跃度探测、当探测失败时重新启动容器,并在从 API 服务器中删除 Pod 时终止容器(将 Pod 终止通知服务器)。

服务代理

服务代理 (kube-proxy) 在每个节点上运行,并确保一个 Pod 可以与另一个 Pod 通信,一个节点可以与另一个节点通信,一个容器可以与另一个容器通信。它负责监视 API 服务器上服务和 Pod 定义的更改,以保持整个网络配置是最新的。当一个服务由多个 Pod 支持时,代理会在这些 Pod 之间执行负载均衡。

kube-proxy 得名是因为它最初是一个实际的代理服务器,用于接受连接并将它们代理到 Pod。当前的实现使用 iptables 规则将数据包重定向到随机选择的后端 Pod,而无需通过实际的代理服务器。

工作原理的高级视图

  • 当您创建服务时,会立即分配一个虚拟 IP 地址。
  • API 服务器通知在工作节点上运行的 kube-proxy 代理,新服务已存在。
  • 每个 kube-proxy 通过设置 iptables 规则使服务可寻址,确保每个服务 IP/端口对都被拦截,并且目标地址被修改为支持该服务的 Pod 之一。
  • 监视 API 服务器中服务或其端点对象的更改。

容器运行时

容器运行时分为两类

  • 较低级别的容器运行时: 这些运行时专注于运行容器并为容器设置命名空间和 cgroup。
  • 较高级别的容器运行时(容器引擎): 这些运行时专注于格式、解包、管理、镜像共享以及为开发人员提供 API。

容器运行时负责

  • 如果本地不可用,则从镜像注册表拉取所需的容器镜像。
  • 将镜像提取到写时复制文件系统上,并且所有容器层叠加以创建合并的文件系统。
  • 准备容器挂载点。
  • 设置来自容器镜像的元数据,例如覆盖用户输入的 CMD、ENTRYPOINT,并设置 SECCOMP 规则,确保容器按预期运行。
  • 更改内核以为此容器分配进程、网络和文件系统等隔离。
  • 提醒内核分配一些资源限制,如 CPU 或内存限制。
  • 将系统调用 (syscall) 传递给内核以启动容器。
  • 确保 SElinux/AppArmor 设置正确。

协同工作

系统级组件协同工作,以确保 Kubernetes 集群的每个部分都可以实现其目的并执行其功能。有时,当您深入编辑 YAML 文件 时,理解您的请求如何在集群内传递可能会让人感到不知所措。现在您有了一张关于各个部分如何组合在一起的地图,您可以更好地了解 Kubernetes 内部发生的事情,这有助于您诊断问题、维护健康的集群并优化您自己的工作流程。

接下来阅读什么
标签
User profile image.
我是一名解决方案架构师,管理着 200 多个战略客户,拥有 5 年以上使用 Linux、Ansible、Docker、Kubernetes 和 OpenShift 等开源技术的经验。我通过使用定制的开源解决方案,帮助企业解决他们在混合云环境中的自动化和容器化等 IT 挑战。

评论已关闭。

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 许可。
© 2025 open-source.net.cn. All rights reserved.