Kubernetes整体架构与核心组件

一、整体架构

  一个 Kubernetes 集群的机器节点有两种角色—— Master 和 Node,都可由一个或多个节点组成,且同一个节点可以既是 Master 也是 Node。其中 Master 节点负责全局决策、资源调度、Node 与 Pod 管理,等等,属于管控节点;Node 节点为工作机器,负责运行容器化应用。

1. Master 节点组件

(1)kube-apiserver

  kube-apiserver 负责公开 Kubernetes API,负责处理接受请求的工作。 API 服务器是 Kubernetes 控制平面的前端。

(2)etcd

  一致且高度可用的键值存储,用作 Kubernetes 的所有集群数据的后台数据库。

(3)kube-scheduler

  kube-scheduler 负责监视新创建的、未指定运行节点(node)的 Pods, 并选择节点来让 Pod 在上面运行。

(4)kube-controller-manager

  kube-controller-manager 负责运行控制器进程。

(5)cloud-controller-manager

  一个 Kubernetes 控制平面组件, 嵌入了特定于云平台的控制逻辑。 云控制器管理器(Cloud Controller Manager)允许你将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来。

2. Node 节点组件

(1)kubelet

  kubelet 会在集群中每个 Node 节点上运行。 它保证容器(containers)都运行在 Pod 中。

(2)kube-proxy

  kube-proxy 是集群中每个 Node 节点上运行的网络代理, 实现 Kubernetes 服务(Service)概念的一部分。
 
 
 
 

二、核心组件——Kubernetes API Server

1. 功能作用

(1)提供 Kubernetes 各类资源对象的增、删、改、查及 Watch 等 HTTP REST 接口,成为集群内各个功能模块之间数据交互和通信的中心枢纽,是整个系统的数据总线和数据中心。
(2)集群管理的 API 入口。
(3)资源配额控制的入口。
(4)提供了完备的集群安全机制。

2. 架构解析

  API Server 架构分层:
(1)API 层:Kubernetes 资源对象的 CRUD、Watch 等主要API,健康检查、UI、日志、性能等运维监控相关API。(监控:Metrics Server)
(2)访问控制层:鉴权,验明用户身份,核准用户对 Kubernetes 资源对象的访问权限。
(3)注册表层:Kubernetes 把所有资源对象都保存在注册表中,并定义了它们的类型、如何创建、如何转换资源的不同版本,以及如何编码与解码。
(4)etcd 数据库:用于持久化存储 Kubernetes 资源对象的 KV 数据库。

3. 服务解析

(1)服务本质

  Kubernetes API Server 本身也是一个 Service,它的名称就是 Kubernetes,并且它的 ClusterIP 地址是 ClusterIP 地址池里的第 1 个地址。

(2)服务端口

HTTP 端口:配置参数 --insecure-port,默认 8080。
HTTPS 端口:配置参数 --secure-port,默认 6443。
  可通过端口直接访问:

(3)通过 kubectl proxy 代理访问

  kubectl proxy 可在 8001 端口启动代理访问 API Server,提供简单有效的安全机制,比如:
<1>拒绝客户端访问某些资源的 API
<2>采用白名单限制非法客户端访问

(4)Kubectl Proxy API

  Kubernets API Server 还提供了一类很特殊的 REST 接口——Kubernetes Proxy API 接口,这类接口的作用是代理 REST 请求,即 Kubernets API Server 把收到的 REST 请求转发到某个 Node 上的 kubelet 守护进程的 REST 端口,由该 Kubelet 进程负责响应。
  例如,当前 Node 的名称为 k8s-node-1,用以下命令即可获取在该节点上运行的所有 Pod:
  这里获取的 Pod 的信息数据来自 Node 而非 etcd 数据库,所以两者可能在某些时间点有所偏差。
  此外,如果 Kubelet 进程在启动时包含 --enable-debugging-handlers=true 参数,那么 Kubernetes Proxy API 还会增加一些 debug 接口,比如:列出在该 Node 上运行的 Pod 信息、该 Node 上的 CPU 占用情况和内存使用情况等。
  另外,还能通过 Kubernetes Proxy API 在集群外访问某个 Pod 容器的服务:(可用于逐一排查 Service 的 Pod 副本)

4. 设计与实现

(1)API Server 设计与实现的核心目标

  由于 API Server 是 Kubernetes 集群数据的唯一访问入口,因此安全性与高性能成为 API Server 设计和实现的两大核心目标。
  安全性:
<1>采用 HTTPS 安全传输通道与 CA 签名数字证书强制双向认证。
<2>启用 RBAC 访问控制策略。
  高性能:
<1>拥有大量高性能的底层代码,使用协程+队列,使得单进程的 API Server 具备快速处理大量请求的能力。
<2>普通 List 接口结合异步 Watch 接口,解决了 Kubernetes 各种资源对象的高性能同步问题,提升了 Kubernetes 集群实时响应各种事件的灵敏度。
<3>采用了高性能的 etcd 数据库,解决了数据的可靠性问题,提升了 API Server 数据访问层的性能。

(2)List-Watch 机制

  Pod 调度过程中的 List-Watch 机制:
<1>API Server 监听(Watch)在 etcd 上发生的数据操作事件。
<2>API Server 模仿 etcd 的 Watch API 提供了自己的 Watch 接口,Kubernetes 的其他组件通过调用 API Server 的 Watch 接口间接监听 etcd 上发生的数据操作事件。(相当于 API Server 代理了其他组件对 etcd 的访问,降低了 etcd 的压力)
<3>Kubernetes 其他组件先调用 API Server 的 List 接口获取相关资源对象的全量数据并将其缓存到内存中,然后启动对应资源对象的 Watch 协程,根据 Watch 事件实时增量同步数据。(Kubernetes 其他组件在某些情况下不直接访问 API Server,而是通过访问缓存数据来间接访问 API Server,缓解了 API Server 的压力)

(3)不同版本资源对象的转换

  为了便捷解决多个不同版本之间资源对象的转换,API Server 针对每种资源对象都引入了一个相对不变的 internal 版本,每个版本只要支持转换为 internal 版本,就能够与其他版本进行间接转换。

(4)API Server 网络隔离的设计

  公有云提供商提供 Kubernetes 服务时,考虑到安全问题,会要求以 API Server 为核心的 Master 节点的网络与承载客户应用的 Node 节点的网络实现某种程度的“安全隔离”。
  API Server Network Proxy 特性的核心设计思想是将 API Server 放置在一个独立的网络中,与 Node 节点的网络相互隔离,然后增加独立的 Network Proxy 进程来解决这两个网络直连的连通性问题。在 Master 节点的网络里部署 Konnectivity server,在 Node 节点的网络里部署 Konnectivity Agent,两者之间建立起安全连接,采用 HTTP 或 gRPC 进行通信。

 

 

 

 

三、核心组件——Controller Manager

1. 功能作用

  一般来说,智能系统和自动系统通常都会通过一个“操作系统”不断修正系统的工作状态。在 Kubernetes 集群中,每个 Controller 都是这样的一个“操作系统”,它们通过 API Server 提供的(List-Watch)接口实时监控集群中特定资源的状态变化,当发生各种故障导致某资源对象的状态变化时,Controller 会尝试将其状态调整为期望的状态。
  Controller Manager 是 Kubernetes 中各种“操作系统”的管理者,是集群内部的管理控制中心,也是 Kubernetes 自动化功能的核心。

2. 架构解析

  每种 Controller 都负责一种特定资源的控制流程,而 Controller Manager 正是这些 Controller 的核心管理者。

3. 版本控制调度器

  在 Kubernetes 中存在两个功能相似的副本控制器:Replication Controller 和 Deployment Controller。

(1)Replication Controller

  Replication Controller 的核心作用是确保集群中某个 RC(Replication Controller)关联的 Pod 副本数量在任何时候都保持预设值。
注意:
  只有当 Pod 的重启策略是 Always(RestartPolicy=Always) 时,Replication Controller 才会管理该 Pod 的操作。

(2)Deployment Controller

  随着 Kubernetes 的不断升级,旧的 RC(Replication Controller)已不能满足需求,所以有了 Deployment。Deployment 可被视为 RC(Replication Controller)的替代者,RC 及其对应的 Replication Controller 已不再升级、维护。
  Deployment Controller 在工作过程中实际上是在控制两类相关的资源对象:Deployment 及 ReplicaSet。在创建 Deployment 资源对象以后,Deployment Controller 也默默创建了对应的 ReplicaSet,Deployment 的滚动升级也是 Deployment Controller 通过自动创建新的 ReplicaSet 来支持的。
  Deployment Controller 的作用:
<1>确保在当前集群中有且仅有 N 个 Pod 实例,N 是在 Deployment 中定义的 Pod 副本数量。
<2>通过调整 spec.replicas 属性的值来实现系统扩容或缩容。
<3>通过改变 Pod 模板(主要是镜像版本)来实现系统的滚动升级。

4. Node Controller

  kubelet 进程在启动时通过 API Server 注册自身节点信息,并定时向 API Server 汇报状态信息,API Server 在接收到这些信息后,会将这些信息更新到 etcd 中。
Node Controller 的核心工作流程:
  节点健康状态包括就绪(True)、未就绪(False)、未知(Unknown)。

5. ResourceQuota Controller

  ResourceQuota Controller 即资源配额管理,它确保指定的资源对象在任何时候都不会超量占用系统物理资源。

(1)配额管理级别

  目前 Kubernetes 支持如下三个层次的资源配额管理:
<1>容器级别,可以对 CPU 和 Memory 进行限制。
<2>Pod 级别,可以对一个 Pod 内所有容器的可用资源进行限制。
<3>Namespace 级别,为 Namespace(多租户)级别的资源限制,包括:Pod 数量、Replication Controller 数量、Service 数量、ResourceQuota 数量、Secret 数量和可持有的 PV 数量。

(2)配额管理方式

  Kubernetes 的配额管理是通过 Admission Control(准入控制)来控制的,Admission Control 当前提供了两种方式的配额约束:
<1>LimitRanger:作用于 Pod 和 Container。
<2>ResourceQuota:作用于 Namespace,限定一个 Namespace 里各类资源的使用总额。

(3)配额管理流程

<1>如果在 Pod 定义中同时声明了 LimitRanger,则通过 API Server 请求创建或修改资源时,Admission Control 会计算当前配额的使用情况,如果不符合配额约束,则操作失败。
<2>对于定义了 ResourceQuota 的 Namespace,ResourceQuota Controller 会定期统计和生成该 Namespace 下各类对象的资源使用总量,然后将这些统计结果写入 etcd 的 resourceQuotaStatusStorage 目录(resourceQuotas/status)下,随后这些统计信息被 Admission Control 使用,以确保相关 Namespace 下的资源配额总量不会超过 ResourceQuota 中的限定值。

6. Namespace Controller

  通过 API Server 可以创建新的 Namespace 并将其保存在 etcd 中,Namespace Controller 定时通过 API Server 读取这些 Namespace 信息。
  可通过 API Server 将 Namespace 标识为优雅删除(设置删除期限,即 DeletionTimestamp 属性),处理过程如下:
(1)Namespace Controller 将该 Namespace 的状态设置成 Terminating 并保存在 etcd 中。
(2)Admission Controller 的 NamespaceLifeCycle 插件阻止为该 Namespace 创建新的资源。
(3)Namespace Controller 删除该 Namespace 下的所有资源对象。
(4)Namespace Controller 对该 Namespace 执行 finalize 操作,删除 Namespace 的 spec.finalizers 域中的信息。
(5)Namespace Controller 通过 API Server 删除该 Namespace 资源。

7. Service Controller 与 Endpoints Controller

(1)Service、Endpoints 与 Pod 的关系

  Endpoints 表示一个 Service 对应的所有 Pod 副本的访问地址,Node 上的 kube-proxy 进程会获取每个 Service 的 Endpoints,实现 Service 的负载均衡功能。

(2)Endpoints Controller

  Endpoints Controller 是负责生成和维护所有 Endpoints 对象的控制器。Endpoints Controller 监听 Service 和对应的 Pod 副本的变化,更新对应的 Service 的 Endpoints 对象。(新的 Service 被创建时,根据其 Pod 列表创建 Endpoints 对象)

(3)Service Controller

  Service Controller 其实是 Kubernetes 集群与外部的云平台之间的一个接口控制器。Service Controller 监听 Service 的变化,如果该 Service 是一个 LoadBalancer 类型的 Service(externalLoadBalancers=true),则 Service Controller 确保该 Service 对应的 LoadBalancer 实例在外部的云平台上被相应地创建、删除及更新路由转发表(根据 Endpoints 的条目)。
 
 
 
 

四、核心组件——Scheduler

1. 功能作用

  Kubernetes Scheduler 是负责 Pod 调度的组件。
  随着 Pod 调度变得越来越复杂,Kubernetes Scheduler 内部的实现机制也从最初的两阶段调度机制(Predicates & Priorities)发展到后来的调度框架(Scheduling Framework)。

2. 调度流程

(1)Controller Manager 调用 API Server 将新创建的 Pod 信息写入 etcd。
(2)Scheduler 通过 API Server 监听到 Pod 新建事件,将新创建的 Pod 按照特定的调度算法和调度策略绑定到集群中某个合适的 Node 上,并将绑定信息通过 API Server 写入 etcd 中。
(3)目标 Node 上的 kubelet 通过 API Server 监听到 Scheduler 产生的 Pod 绑定事件,获取对应的 Pod 清单,下载 Image 镜像并启动容器。

3. 两阶段调度

  旧版本的 Kubernetes Scheduler 的调度总体上包括两个阶段:过滤+打分,随后就是绑定目标节点,完成调度。
(1)过滤阶段(Filtering):遍历所有目标 Node,筛选出符合要求的候选节点。此阶段中使用的 Predicates 是一系列过滤器。
(2)打分阶段(Scoring):在过滤阶段的基础上,采用优选策略计算出每个候选节点的积分,积分最高者胜出。此阶段用到的 Priotities 用来对满足条件的 Node 节点进行打分。

4. Scheduler Framework

  从整个调度流程来看,新的 Scheduler Framework 是在旧流程的基础上增加了一些扩展点(基于调度 Stage 的扩展点),同时支持用户以插件的方式(Plugin)进行扩展。
新的调度流程如下:
  Kubernetes 1.18 版本中引入了全新的 Scheduler 配置特性——Scheduling Profiles。
  通过编写一个 Profiles 配置文件,定义在调度的什么阶段开启或关闭哪些插件,然后通过 --config 参数传递到 kube-scheduler 服务中,即可实现对 Scheduler 进行自定义配置。
  此外,Scheduling Profiles 特性还使得多调度器特性更易实现。只要针对不同的调度规则编写不同的 Profile 配置文件,并给它们起一个自定义 Scheduler 的名称,然后把这个配置文件传递给 Kubernetes Scheduler 加载、生效,就立即实现了多调度器支持的“多重影分身”特效。(通过一个 Scheduler 进程加上多个配置文件的方式来实现全新的多调度器特效)
  profiles 文件示例如下:
  其中 default-scheduler 为系统默认的 Scheduler 名称,而 no-scoring-scheduler 则为自定义的 Scheduler 名称。在自定义的 Scheduler 中可以根据自己的需求开启或关闭指定的插件。
  使用多个调度器时,由 Pod 选择是用默认的调度器还是用某个自定义的调度器进行调度。
 
 
 
 

五、核心组件——kubelet

  在 Kubernetes 集群中,在每个 Node 上都会启动一个 kubelet 服务进程。

1. 功能作用

(1)处理 Master 下发到当前 Node 的任务,管理 Pod 及 Pod 中的容器。
(2)每个 kubelet 进程都会在 API Server 上注册节点自身的信息,定期向 Master 汇报节点资源的使用情况。
(3)通过 cAdvisor 监控容器和节点资源。

2. 节点管理

(1)节点注册

<1>自动注册:设置 kubelet 自动参数 --register-node=true,kubelet 将自动向 API Server 注册自己。
<2>手动注册:设置 kubelet 自动参数 --register-node=false,用户需要自己去配置 Node 的资源信息,同时将 API Server 的位置告知 Node 上的 kubelet。

(2)节点信息同步

  kubelet 会定时向 API Server 发送节点的新消息,API Server 在接收到这些信息后,会将其写入 etcd 中。通过 kubelet 的启动参数 --node-status-update-frequency 可设置 kubelet 每隔多长时间向 API Server 报告节点的状态,默认为 10s。

3. Pod 管理

(1)kubelet 获取当前 Node 上的 Pod 清单的方式

<1>静态 Pod 配置文件:kubelet 通过启动参数 --config 指定目录下的 Pod YAML 文件(默认目录为 /etc/kubernetes/manifests/),kubelet 会持续监控指定目录下的文件变化,以创建或删除 Pod。
静态 Pod 以非 API Server 方式创建,没有通过 kube-controller-manager 进行管理。API Server 会为每个静态 Pod 创建一个 Mirror Pod 与其匹配,Mirror Pod 的状态将真实反映静态 Pod 的状态。
<2>HTTP 端点(URL):通过 --manifest-url 参数设置,通过 --http-check-frequency 设置检查该 HTTP 端点数据的时间间隔,默认为 20s。
<3>API Server:kubelet 通过 API Server 监听 etcd 目录(/regitstry/nodes/$当前节点名称、/regitstry/pods),同步 Pod 列表。

(2)kubelet 创建和修改 Pod 的过程

<1>为该 Pod 创建一个数据目录。
<2> 从 API Server 中读取该 Pod 清单。
<3>为该 Pod 挂载外部卷(Externa Volume)。
<4>下载 Pod 用到的 Secret。
<5>检查已经运行在节点上的 Pod,如果该 Pod 没有容器或 Pause 容器(kubernetes/pause 镜像创建的容器)没有启动,则先停止 Pod 里所有容器的进程。如果在 Pod 中有需要删除的容器,则删除这些容器。
<6>用 kubernetes/pause 镜像为每个 Pod 都创建一个容器 。该 Pause 容器用于接管 Pod 中所有其他容器的网络。每创建一个新的 Pod,kubelet 都会先创建一个 Pause 容器,然后创建其他容器。kubernetes/pause 镜像大概有 200KB,是个非常小的容器镜像。
<7>为 Pod 中的每个容器都做如下处理:
  为容器计算一个哈希值,然后用容器的名称去查询对应 Docker 容器的哈希值。若查找到容器,且二者的哈希值不同,则停止 Docker 中容器的进程,并停止与之关联的 Pause 容器的进程;若二者相同,则不做任何处理。
  如果容器被终止,且容器没有指定的 restartPolicy(重启策略),则不做任何处理。
  调用 Docker Client 下载容器镜像,调用 Docker Client 行容器。

4. 容器健康检查

  Pod 通过两类探针来检查容器的健康状态:

(1)LivenessProbe

  用于判断容器是否健康并反馈给 kubelet。如果检测到容器不健康,kubelet 将删除该容器,并根据容器的重启策略做相应的处理。
  kubelet 定期调用容器中的 LivenessProbe 探针来诊断容器的健康状况。LivenessProbe 包含以下 3 种实现方式:
<1>ExecAction:在容器内部运行一个命令,如果该命令的退出状态码为 0,则表明容器健康。
<2>TCPSocketAction:通过容器的 IP 地址和端口号执行 TCP 检查,如果端口能够被访问,则表明容器健康。
<3>HTTPGetAction:通过容器的 IP 地址和端口号及路径调用 HTTP Get 方法,如果响应的状态码大于或等于200且小于或等于400,则认为容器状态健康。

(2)ReadinessProbe

  用于判断容器是否启动完成,且准备接收请求。如果检测到容器启动失败,则 Pod 的状态将被修改,Endpoint Controller 将从 Service 的 Endpoint 中删除包含该容器所在 Pod 的 IP 地址的 Endpoint 条目。

5. cAdvisor 资源监控

  cAdvisor 是一个开源的分析容器资源使用率和性能特性的代理工具,被集成到 Kubernetes 代码中,kubelet 通过 cAdvisor 获取其所在节点及容器上的数据。cAdvisor 自动查找其所在 Node 上的所有容器,自动采集 CPU、内存、文件系统和网络使用的统计信息。在大部分   Kubernetes 集群中,cAdvisor 都通过它所在 Node 的 4194 端口暴露一个简单的 UI。
  在新的 Kubernetes 监控体系中, Metrics Server 用于提供 Core Metrics(核心指标),包括 Node 和 Pod 的 CPU 和内存使用数据。其他 Custom Metrics(自定义指标)则由第三方组件(如 Prometheus)采集和存储。

6. 容器运行时

  containerd 被设计成嵌入一个更大的系统如 Kubernetes 中使用,而不是直接由开发人员或终端用户使用,containerd 底层驱动 runc 来实现底层的容器运行时,对外则提供了镜像拉取及基于 gRPC 接口的容器 CRUD 封装接口。

  RuntimeClass:在一个 Kubernetes 集群中配置并启用多种 Container Runtime,不同类型的 Pod 可以选择不同特性的 Container Runtime 来运行,以实现资源占用或者性能、稳定性方面的优化。
 
 
 
 

六、核心组件——kube-proxy

1. 功能作用

  在 Kubernetes 集群的每个 Node 上都会运行一个 kube-proxy 服务进程,我们可以把这个进程看作 Service 的透明代理兼负载均衡器,其核心功能是将到某个 Service 的访问请求转发到后端的多个 Pod 实例上。

2. 第一代 Proxy

  实现原理——iptables。
  Service 的负载均衡转发规则:
  kube-proxy 工作原理:(userspace 模式)
  Service 的 ClusterIP 与 NodePort 等概念是 kube-proxy 服务通过 iptables 的 NAT 转换实现的,kube-proxy 在运行过程中动态创建与 Service 相关的 iptables 规则,这些规则实现了将访问服务的请求负载均衡分发到后端 Pod 的功能。在 Kubernetes 集群内部,我们可以在任意 Node 上发起对 Service 的访问请求。

3. 第二代 Proxy

  实现原理——iptables。
  工作原理:(iptables 模式)

  iptables 模式下的第二代 kube-proxy 进程不再起到数据层面的 Proxy 的作用,只承担了控制层面的功能,Client 向 Service 的请求流量通过 iptables 的 NAT 机制直接发送到目标 Pod,不经过 kube-proxy 进程的转发,完全工作在内核态,性能更强。

4. 第三代 Proxy

  实现原理——IPVS。
  工作原理:(IPVS 模式)
  iptables 与 IPVS 的异同:
(1)都是基于 Netfilter 实现的。
(2)定位不同:iptables 是为防火墙设计的,IPVS 则专门用于高性能负载均衡。
(3)数据结构不同:iptables 使用线性数据结构,而 IPVS 使用更高效的哈希表结构。
  使用第二代 Proxy 时,在集群中的 Service 和 Pod 大量增加以后,每个 Node 节点上 iptables 中的规则会急速膨胀,导致网络性能显著下降,而使用 IPVS 实现的 Proxy,则几乎可以无限的扩张。
  由于 IPVS 无法提供包过滤、airpin-masquerade tricks(地址伪装)、SNAT 等功能,因此在某些场景(如 NodePort 的实现)下还要与 iptables 搭配使用。在 IPVS 模式下,kube-proxy 又做了重要的升级,即使用 iptables 扩展的 ipset,而不是直接调用 iptables 来生成规则链。(ipset 引入了带索引的数据结构,可以高效查找和匹配)
 
 
 
 
参考:
《kubernetes 权威指南第 5 版》
 
 
posted @   疯一样的狼人  阅读(313)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示