Kubernetes架构详解

2,528 阅读20分钟

Kubernetes 架构详解通过插图详细解释每个 kubernetes 组件。

所以,如果你想,

  1. 了解 kubernetes 架构
  2. 了解 Kubernetes 核心组件的工作流程

那么您一定会喜欢本指南。

其他Kubernetes相关文章:

目录
  1. Kubernetes 架构
    1. 控制平面
    2. 工作节点
  2. Kubernetes 控制平面组件
    1. 1. kube-apiserver
    2. 2. etcd
    3. 3.kube调度器
    4. 4. Kube控制器管理器
    5. 5.云控制器管理器(CCM)
  3. Kubernetes 工作节点组件
    1. 1. Kubelet
    2. 2.kube代理
    3. 3. 容器运行时
  4. Kubernetes 集群插件组件
    1. 1.CNI插件
  5. Kubernetes 架构常见问题解答
    1. Kubernetes 控制平面的主要用途是什么?
    2. Kubernetes 集群中工作节点的用途是什么?
    3. Kubernetes 中控制平面和工作节点之间的通信是如何保护的?
    4. Kubernetes 中 etcd 键值存储的用途是什么?
    5. 如果 etcd 出现故障,Kubernetes 应用程序会发生什么情况?
  6. 结论

注意:为了更好地理解 Kubernetes 架构,有一些先决条件请查看kubernetes 学习指南中的先决条件以了解更多信息。

下面的 Kubernetes 架构图展示了 Kubernetes 集群的所有组件以及外部系统如何连接到 Kubernetes 集群。

image.png

关于 Kubernetes,您首先应该了解的是,它是一个分布式系统。意思是,它有多个组件分布在网络上的不同服务器上。这些服务器可以是虚拟机或裸机服务器。我们称之为 Kubernetes 集群。

Kubernetes 集群由控制平面节点和工作节点组成。

控制平面

控制平面负责容器编排和维护集群的所需状态。它具有以下组件。

  1. kube-apiserver
  2. etcd
  3. kube-调度程序
  4. kube-controller-manager
  5. 云控制器管理器

工作节点

工作节点负责运行容器化应用程序。工作节点具有以下组件。

  1. kubelet
  2. kube-代理
  3. 容器运行时

Kubernetes 控制平面组件

首先,让我们看一下每个控制平面组件以及每个组件背后的重要概念。

1. kube-apiserver

kube-api 服务器是公开 Kubernetes API 的 Kubernetes 集群的中心枢纽。

最终用户和其他集群组件通过 API 服务器与集群对话。很少有监控系统和第三方服务会与 API 服务器通信以与集群交互。

所以当你使用 kubectl 来管理集群时,在后端你实际上是通过HTTP REST APIs与 API 服务器通信。然而,调度程序、控制器等内部集群组件使用gRPC与 API 服务器通信。

API 服务器与集群中其他组件之间的通信通过 TLS 进行,以防止对集群进行未经授权的访问。

image.png

Kubernetes api-server负责以下工作

  1. API 管理:公开集群 API 端点并处理所有 API 请求。
  2. 身份验证(使用客户端证书、承载令牌和 HTTP 基本身份验证)和授权(ABAC 和 RBAC 评估)
  3. 处理 API 请求并验证 API 对象(如 pod、services等)的数据(验证和变更准入控制器)
  4. 它是唯一与 etcd 通信的组件。
  5. api-server 协调控制平面和工作节点组件之间的所有进程。
  6. api-server 有一个内置的 bastion apiserver 代理。它是 API 服务器进程的一部分。它主要用于允许从集群外部访问 ClusterIP 服务,即使这些服务通常只能在集群内部访问。

2. Etcd

Kubernetes 是一个分布式系统,它需要像 etcd 这样支持其分布式特性的高效分布式数据库。它既充当后端服务发现又充当数据库。你可以称它为 Kubernetes 集群的大脑。

etcd是一个开源的强一致性分布式键值存储。那是什么意思呢?

  1. **强一致性:**如果对节点进行更新,强一致性将确保它立即更新到集群中的所有其他节点。此外,如果您查看CAP 定理,实现 100% 可用性和强一致性和分区容错是不可能的。
  2. 分布式:etcd 被设计为在不牺牲一致性的情况下作为集群在多个节点上运行。
  3. **键值存储:**将数据存储为键和值的非关系数据库。它还公开了一个键值 API。数据存储建立在BboltDB之上,BboltDB 是 BoltDB 的一个分支。

etcd 使用raft 一致性算法 来实现强一致性和可用性。它以领导成员方式工作,以实现高可用性并承受节点故障。

那么 etcd 如何与 Kubernetes 协同工作呢?

简单来说,当你使用 kubectl 获取 kubernetes 对象详细信息时,你是从 etcd 获取它。此外,当您部署像 pod 这样的对象时,会在 etcd 中创建一个条目。

简而言之,以下是您需要了解的有关 etcd 的信息。

  1. etcd 存储 Kubernetes 对象(pod、secrets、daemonsets、 deployments、configmaps、statefulsets 等)的所有配置、状态和元数据。
  2. etcd 允许客户端使用 API 订阅事件Watch() 。Kubernetes api-server 使用 etcd 的监视功能来跟踪对象状态的变化。
  3. etcd使用 gRPC公开键值 API 。此外,gRPC 网关是一个 RESTful 代理,可将所有 HTTP API 调用转换为 gRPC 消息。它使它成为 Kubernetes 的理想数据库。
  4. etcd以key-value格式存储**/registry目录key下的所有对象。例如,可以在/registry/pods/default/nginx下找到 default 命名空间中名为 Nginx 的 pod 的信息**

image.png

此外,etcd 是控制平面中唯一的Statefulset组件。

3.kube调度器

kube-scheduler 负责在工作节点上调度 pod

当您部署一个 pod 时,您指定 pod 的要求,例如 CPU、内存、亲和力、污点或容忍度、优先级、持久卷 (PV) 等。调度程序的主要任务是识别创建请求并为创建请求选择最佳节点满足要求的pod。

下图显示了调度程序如何工作的高级概述。

image.png

在一个 Kubernetes 集群中,会有多个工作节点。那么调度器是如何从所有工作节点中选出节点的呢?

以下是调度程序的工作原理。

  1. 为了选择最佳节点,Kube-scheduler 使用过滤和评分操作。
  2. filtering中,调度程序会找到最适合调度 pod 的节点。例如,如果有五个工作节点具有运行 pod 的资源可用性,它会选择所有五个节点。如果没有节点,则 pod 不可调度并移至调度队列。如果它是一个大型集群,假设有 100 个工作节点,并且调度程序不会遍历所有节点。有一个名为 的调度程序配置参数**percentageOfNodesToScore**。默认值通常为50%。因此它尝试以循环方式迭代超过 50% 的节点。如果工作节点分布在多个区域中,则调度程序会迭代不同区域中的节点。对于非常大的集群,默认值为**percentageOfNodesToScore**5%。
  3. 评分阶段,调度程序通过为过滤后的工作节点分配分数来对节点进行排名。调度器通过调用多个调度插件进行评分。最后,将选择排名最高的工作节点来调度 Pod。如果所有节点的排名相同,则将随机选择一个节点。
  4. 选择节点后,调度程序会在 API 服务器中创建一个绑定事件。表示绑定 pod 和节点的事件。

关于调度程序的事情应该知道。

  1. 它是一个控制器,用于监听 API 服务器中的 Pod 创建事件。
  2. 调度程序有两个阶段。调度周期绑定周期。它一起被称为调度上下文。 调度 周期选择一个工作节点,绑定周期将该更改应用到集群。
  3. 调度器总是将高优先级的 pod 放在低优先级的 pod 之前进行调度。此外,在某些情况下,在 Pod 开始在选定节点中运行后,Pod 可能会被逐出或移动到其他节点。如果您想了解更多,请阅读Kubernetes pod 优先级指南
  4. 您可以创建自定义调度程序并在集群中与本机调度程序一起运行多个调度程序。部署 pod 时,您可以在 pod 清单中指定自定义调度程序。因此,将根据自定义调度程序逻辑做出调度决策。
  5. 调度器有一个可插入的调度框架。意思是,您可以将自定义插件添加到计划工作流程中。

4. Kube Controller Manager

什么是控制器?控制器是运行无限控制循环的程序。这意味着它持续运行并观察对象的实际和期望状态。如果实际状态和期望状态存在差异,它会确保 kubernetes 资源/对象处于期望状态。

根据官方文档,

在 Kubernetes 中,控制器是监视集群状态的控制循环,然后在需要时进行更改或请求更改。每个控制器都试图将当前集群状态移动到更接近所需状态。

假设您要创建一个部署,您在清单 YAML 文件中指定所需的状态(声明式方法)。例如,2 个副本、1 个卷挂载、configmap 等。内置部署控制器可确保部署始终处于所需状态。如果用户使用 5 个副本更新部署,则部署控制器会识别它并确保所需状态为 5 个副本。

Kube 控制器管理器是管理所有 Kubernetes 控制器的组件。Kubernetes 资源/对象,如 pod、命名空间、作业、副本集,由各自的控制器管理。此外,kube scheduler 也是一个由 Kube controller manager 管理的控制器。

以下是重要的内置 Kubernetes 控制器列表。

  1. Deployment控制器
  2. Replicaset控制器
  3. DaemonSet 控制器
  4. Job控制器
  5. CronJob 控制器
  6. Endpoints控制器
  7. Namespace控制器
  8. Service accounts控制器。
  9. Node控制器

image.png 以下是您应该了解的有关 Kube 控制器管理器的信息。

  1. 它管理着所有的控制器,而控制器试图将集群保持在期望的状态。
  2. 您可以使用与自定义资源定义关联的自定义控制器来扩展 kubernetes 。

5. Cloud Controller Manager(CCM)

当 kubernetes 部署在云环境中时,云控制器管理器充当 Cloud Platform API 和 Kubernetes 集群之间的桥梁。

这样,核心 kubernetes 核心组件可以独立工作,并允许云提供商使用插件与 kubernetes 集成。(比如kubernetes集群和AWS云API的接口)

云控制器集成允许 Kubernetes 集群提供云资源,如实例(用于节点)、负载均衡器(用于服务)和存储卷(用于持久卷)。

image.png

Cloud Controller Manager 包含一组特定于云平台的控制器,可确保特定于云的组件(节点、负载均衡器、存储等)处于所需状态。以下是云控制器管理器的三个主要控制器。

  1. **节点控制器:**该控制器通过与云提供商 API 对话来更新节点相关信息。例如,节点标签和注释、获取主机名、CPU 和内存可用性、节点健康状况等。
  2. **路由控制器:**负责在云平台配置联网路由。这样不同节点中的 Pod 就可以相互通信。
  3. 服务控制器:它负责为 kubernetes 服务部署负载均衡器、分配 IP 地址等。

以下是云控制器管理器的一些经典示例。

  1. 部署负载均衡器类型的 Kubernetes 服务。在这里,Kubernetes 提供了一个特定于云的 Loadbalancer 并与 Kubernetes 服务集成。
  2. 为云存储解决方案支持的 pod 供应存储卷 (PV)。

总体Cloud Controller Manager 管理kubernetes 使用的特定于云的资源的生命周期。

Kubernetes Worker Node Components

现在让我们看看每个工作节点组件。

1. Kubelet

Kubelet 是一个代理组件,运行在集群中的每个节点上。t 不作为容器运行,而是作为守护进程运行,由 systemd 管理。

它负责向 API 服务器注册工作节点并使用主要来自 API 服务器的 podSpec(Pod 规范 - YAML 或 JSON)。podSpec 定义应在 pod 内运行的容器、它们的资源(例如 CPU 和内存限制)以及环境变量、卷和标签等其他设置。

然后它通过创建容器将 podSpec 带到所需的状态。

简单来说,kubelet 负责以下工作。

  1. 创建、修改和删除容器的容器。
  2. 负责处理 liveliness、readiness 和 startup 探测。
  3. 负责通过读取 pod 配置并在主机上为卷挂载创建相应目录来挂载卷。
  4. 通过调用 API 服务器收集和报告节点和 pod 状态。

Kubelet 也是一个控制器,它监视 pod 的变化并利用节点的容器运行时来拉取图像、运行容器等。

除了来自 API 服务器的 PodSpecs,kubelet 可以接受来自文件、HTTP 端点和 HTTP 服务器的 podSpec。“来自文件的 podSpec”的一个很好的例子是 Kubernetes 静态 pod。

静态 pod 由 kubelet 控制,而不是 API 服务器。

这意味着您可以通过向 Kubelet 组件提供 pod YAML 位置来创建 pod。但是,Kubelet 创建的静态 Pod 不受 API 服务器管理。

这是静态 pod 的真实示例用例。

在引导控制平面时,kubelet 将 api-server、调度程序和控制器管理器作为静态 pod 从位于/etc/kubernetes/manifests

以下是关于 kubelet 的一些关键事项。

  1. Kubelet 使用 CRI(容器运行时接口)gRPC 接口与容器运行时通信。
  2. 它还公开一个 HTTP 端点以流式传输日志并为客户端提供执行会话。
  3. 使用 CSI(容器存储接口)gRPC 配置块卷。
  4. 它使用集群中配置的 CNI 插件来分配 pod IP 地址并为 pod 设置任何必要的网络路由和防火墙规则。

image.png

2.kube代理

要了解 kube 代理,您需要了解 Kubernetes 服务和端点对象的基本知识。

Kubernetes 中的服务是一种在内部或向外部流量公开一组 pod 的方法。当您创建服务对象时,它会获得一个分配给它的虚拟 IP。它被称为 clusterIP。它只能在 Kubernetes 集群中访问。

Endpoint对象包含了一个Service对象下所有pod组的IP地址和端口。端点控制器负责维护 pod IP 地址(端点)的列表。服务控制器负责为服务配置端点。

您无法 ping ClusterIP,因为它仅用于服务发现,这与可 ping 的 pod IP 不同。

现在让我们了解一下 Kube Proxy。

Kube-proxy 是一个守护进程,作为守护进程集运行在每个节点上。它是一个代理组件,为 pod 实现 Kubernetes Services 概念。(一组具有负载平衡的 Pod 的单个 DNS)。它主要代理 UDP、TCP 和 SCTP,不理解 HTTP。

当您使用服务 (ClusterIP) 公开 pod 时,Kube-proxy 会创建网络规则以将流量发送到分组在服务对象下的后端 pod(端点)。也就是说,所有负载均衡和服务发现都由 Kube 代理处理。

那么 Kube-proxy 是如何工作的呢?

Kube 代理与 API 服务器对话以获取有关服务 (ClusterIP) 和各自的 pod IP 和端口(端点)的详细信息。它还监视服务和端点的变化。

Kube-proxy 然后使用以下任何一种模式来创建/更新将流量路由到服务后面的 pod 的规则

  1. IPTables:这是默认模式。在 IPTables 模式下,流量由 IPtable 规则处理。在这种模式下,kube-proxy 随机选择后端 pod 进行负载均衡。建立连接后,请求将转到同一个 pod,直到连接终止。
  2. **IPVS:**对于服务超过 1000 的集群,IPVS 提供性能提升。它支持以下后端负载平衡算法。
    1. rr: round-robin : 这是默认模式。
    2. lc: least connection(最少打开的连接数)
    3. dh: 目的地散列
    4. sh: 源哈希
    5. sed: 最短的预期延迟
    6. nq: 从不排队
  3. 用户空间(遗留和不推荐)
  4. 内核空间:此模式仅适用于 windows 系统。

image.png

如果您想了解 kube-proxy IPtables 和 IPVS 模式之间的性能差异,请阅读这篇文章

此外,您可以通过将 kube-proxy 替换为Cilium来运行没有 kube-proxy 的 Kubernetes 集群。

3. 容器运行时

您可能了解Java 运行时 (JRE)。它是在主机上运行 Java 程序所需的软件。同样,容器运行时是运行容器所需的软件组件。

容器运行时运行在 Kubernetes 集群中的所有节点上。它负责从容器注册表中拉取镜像、运行容器、为容器分配和隔离资源以及管理主机上容器的整个生命周期。

为了更好地理解这一点,让我们看一下两个关键概念:

  1. **容器运行时接口(CRI):**它是一组允许 Kubernetes 与不同容器运行时交互的 API。它允许不同的容器运行时与 Kubernetes 互换使用。CRI 定义了用于创建、启动、停止和删除容器以及管理镜像和容器网络的 API。
  2. **Open Container Initiative (OCI):**它是容器格式和运行时的一组标准

Kubernetes 支持符合容器**运行时接口 (CRI)**的多个容器运行时(CRI-O、Docker 引擎、containerd 等) 。这意味着,所有这些容器运行时都实现了 CRI 接口并公开了 gRPC CRI API(运行时和图像服务端点)。

那么 Kubernetes 是如何利用容器运行时的呢?

正如我们在 Kubelet 部分中了解到的,kubelet 代理负责使用 CRI API 与容器运行时进行交互,以管理容器的生命周期。它还从容器运行时获取所有容器信息,并将其提供给控制平面。

让我们以CRI-O容器运行时接口为例。这是容器运行时如何与 kubernetes 一起工作的高级概述。

image.png

  1. 当 API 服务器有新的 pod 请求时,kubelet 与 CRI-O 守护进程对话,通过 Kubernetes 容器运行时接口启动所需的容器。
  2. CRI-O 使用库从配置的容器注册表中检查并拉取所需的容器镜像**containers/image**。
  3. CRI-O 然后为容器生成 OCI 运行时规范 (JSON)。
  4. CRI-O 然后启动 OCI 兼容运行时 (runc) 以根据运行时规范启动容器进程。

Kubernetes Cluster Addon Components

除了核心组件外,kubernetes 集群还需要附加组件才能完全运行。选择插件取决于项目要求和用例。

以下是您在集群上可能需要的一些流行的插件组件。

  1. CNI 插件(容器网络接口)
  2. CoreDNS(用于 DNS 服务器): CoreDNS 充当 Kubernetes 集群中的 DNS 服务器。通过启用此插件,您可以启用基于 DNS 的服务发现。
  3. **指标服务器(用于资源指标):**此插件可帮助您收集集群中节点和 Pod 的性能数据和资源使用情况。
  4. **Web UI(Kubernetes 仪表板):**此插件启用 Kubernetes 仪表板以通过 Web UI 管理对象。

1.CNI插件

首先,你需要了解**容器网络接口(CNI)**

它是一种基于插件的架构,具有供应商中立的规范和用于为容器创建网络接口的库。

它不特定于 Kubernetes。借助 CNI,容器网络可以跨容器编排工具(如 Kubernetes、Mesos、CloudFoundry、Podman、Docker 等)进行标准化。

对于容器组网,各个公司可能会有不同的要求,例如网络隔离、安全、加密等。随着容器技术的进步,许多网络提供商为具有广泛组网功能的容器创建了基于 CNI 的解决方案。您可以将其称为 CNI-Plugins

这允许用户从不同的提供商那里选择最适合他们需求的网络解决方案。

CNI Plugin 如何与 Kubernetes 协同工作?

  1. Kube-controller-manager 负责为每个节点分配 pod CIDR。每个 pod 从 pod CIDR 获得一个唯一的 IP 地址。
  2. Kubelet 与容器运行时交互以启动计划的 pod。作为容器运行时的一部分的 CRI 插件与 CNI 插件交互以配置 pod 网络。
  3. CNI 插件使用覆盖网络支持分布在相同或不同节点上的 pod 之间的网络连接。

以下是 CNI 插件提供的高级功能。

  1. Pod Networking
  2. Pod 网络安全和隔离使用网络策略来控制 Pod 之间和命名空间之间的流量。

一些流行的 CNI 插件包括:

  1. Calico
  2. Flannel
  3. Weave Net
  4. Cilium(Uses eBPF)
  5. Amazon VPC CNI(适用于 AWS VPC)
  6. Azure CNI(用于 Azure 虚拟网络)Kubernetes 网络是一个大话题,它因托管平台而异。

Kubernetes 架构常见问题解答

Kubernetes 控制平面的主要用途是什么?

控制平面负责维护集群和集群上运行的应用程序的理想状态。它由 API server、etcd、Scheduler 和 controller manager 等组件组成。

Kubernetes 集群中工作节点的用途是什么?

工作节点是在集群中运行容器的服务器(裸机或虚拟)。它们由控制平面管理,并从控制平面接收有关如何运行作为 pod 一部分的容器的指令。

Kubernetes 中控制平面和工作节点之间的通信是如何保护的?

控制平面和工作节点之间的通信使用 PKI 证书进行保护,不同组件之间的通信通过 TLS 进行。这样,只有受信任的组件才能相互通信。

Kubernetes 中 etcd 键值存储的用途是什么?

Etcd主要存储集群的kubernetes对象、集群信息、节点信息和配置数据,例如集群上运行的应用程序的期望状态。

如果 etcd 出现故障,Kubernetes 应用程序会发生什么情况?

虽然如果 etcd 遇到中断,正在运行的应用程序不会受到影响,但如果 etcd 没有正常运行,将无法创建或更新任何对象

结论

了解Kubernetes 架构有助于您进行日常的 Kubernetes 实施和操作。

在实施生产级集群设置时,正确了解 Kubernetes 组件将有助于您运行应用程序并对其进行故障排除。

接下来,您可以从分步kubernetes 教程开始,亲身体验 Kubernetes 对象和资源。