Kubelet原理

在 Kubernetes 集群中,在每个 Node(又称 Minion)上都会启动一个 kubelet 服务进程 。 该进程用于处理 Master 下发到 本节点的 任务, 管理 Pod 及 Pod 中的 容器 。 每个 kubelet 进 程都会在 API Server 上注册节点自身的信息,定期向 Master 汇报节点资源的使用情况, 并通过 cAdvisor 监控容器和节点资源 。

节点管理

节点通过设置 kubelet 的启动参数” –register-node” ,来决定是否向 API Server 注册自 已。如果该参数的值为 true, 那么 kubelet将试着通过 API Server 注册自己 。 在自注册时, kubelet 启动时还包含下列参数 。

  • –api-servers: API Server 的 位置 。
  • –kubeconfig: kubeconfig 文件,用于访问 API Server 的 安全配置文件 。
  • –cloud-provider: 云服务 商 (IaaS ) 地址,仅用千公有云环境中 。

Kubernetes 限制了 kubelet 的权限,仅允许它修改和创建其所在节点的权限 。 如 果在集群运行过程中遇到集群资源不足的情况,用户就很容易通过添加机器及运用 kubelet 的自注册模式来实现扩容。在某些情况下, Kubernetes 集群中的某些 kubelet 没有选择自 注册模式 ,用户 需要自己去配置 Node 的资源信息, 同时告知 Node 上 kubelet API Server 的位置。集群管理者能够创建和修改节点信息,如果其希望手动创建节点信息,则通过设 置 kubelet 的启 动参数 ”–register- node=false” 即可完成 。

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

Pod管理

kubelet 通过以下方式获取在自身 Node 上要运行的 Pod 清单 。

静态Pod配置文件

kubelet通过启动参数–config指定目录下的PodYAML文件 ( 默认目录为 /etc/kubernetes/manifests/), kubelet会持续监控指定目录下的文件变化,以创 建或删除 Pod。 这种类型的 Pod 没有通过 kube-controller-manager 进行管理,被称为“静 态 Pod”。 另外 ,可以 通过启动参数–file-check-frequency 设置检查该目录的时间间隔,默 认为 20s。

HTTP 端点 (URL )

通过–manifest-ur] 参数设置,通过–http-check-frequency 设 置检查该 HTTP 端点数据的时间间隔,默 认为 20s。

APIServer

kubelet通过APIServer监听etcd目录,同步Pod列表。

所有以非 API Server 方式创建的 Pod 都叫 作 Static Pod。kubelet 将 Static Pod 的状态汇 报给 API Server , API Server 为该 Static Pod 创 建一个 Mirror Pod 与 其匹配 。 Mirror Pod 的 状态将真实反映 StaticPod的状态。 当 StaticPod被删除时,与之相对应的 MirrorPod也会 被删除 。 在本章 中只讨论 通过 API Server 获得 Pod 清单的方式 。 kubelet 通过 API Server Client使用 Watch 加 List 的方式监听/registry/nodes/$当前节点的名称和 /registry/pods 目 录 , 将获取的信息同步到本地缓存中 。

kubelet 读取监听到的信息,如果是创建和修改 Pod 任务

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

容器健康检查

LivenessProbe 探针

LivenessProbe 探针探测到容器不健康,则 kubelet 将 删除该容器,并根据容器的重启策略做相应的处理

一个容器不包含 LivenessProbe 探针,则 kubelet 会认为该容器的 LivenessProbe 探针返回的值永远是 Success

ReadinessProbe 探针

ReadinessProbe 探针检测到容器启动失败,则 Pod 的状态将被修改, Endpoint Controller 将从 Service 的 Endpoint 中删除包含该容器所在 Pod 的 IP 地址的 Endpoint 条目 。

容器运行时

kubelet 负责本节点上所有 Pod 的全生命周期管理,其中就包括相关容器的创建和销毁 这种基本操作 。 容器的创建和销毁等操作的代码不屈于 Kubemetes 的代码范畴

所以 kubelet 需要通过某种进程间的 调用方式如 gRPC 来实现与 Docker 容器引擎之间的调用控制功能 。 在说明其原理和工作 机制之前,我们首先要理解一个重要的概念一ContainerRuntime (容器运行时)。

containerd 底 层驱动 rune 来 实现底层的容器运行时 , 对外则提供了镜像拉取及基于 gRPC 接口的容器 CRUD 封装接口 。 发展至今, containerd 已经从 Docker 里的一个内部组件,变成一个流行的、工业级的开源容器运行时,已经支

持容器镜像的获取和存储、容器的执行和管理、存储和网络等相关功能。在 containerd 和 rune 成为标准化容器服务的基石后,上层应用就可以直接建立在 containerd 和 rune 之上。

CRI 顾名思义 ,就是容器运行时接口规 范 ,这个规范 也是 Kubernetes 顺应容器技术标准化发展潮流的一个 重要历史产物,早在 Kubernetes 1.5 版本中就引入了 CRI 接口规范 。 如图 5.15 所示,引入了 CRI 接口规范 后, kubelet 就可以通过 CRI 插件来实现容器的全生命周期控制了,不同厂家的 Container Runtime 只需实现对应的 CRI 插件代码即可, Kubernetes 无须重新编译 就 可以使用更 多 的 容器运行时。

CRI 接口规范主要定义了两个 gRPC 接口服务: ImageService 和 RuntimeService。 其中, ImageService 提供了从仓库拉取镜像 、 查看和移除镜像的功能; RuntimeService 则负责实现 Pod 和容器的生命周期管理,以及与容器 的交互 (exec/attach/ port-forward )。

Pod 由一组应用容器组成,其中包含共有的 环境和资源约束, 这个环境在 CRI 里被称为 Pod Sandbox。 Container Runtime 可以根据自己的内部 实现来解 释和实现自己的 Pod Sandbox,比如对于 Hypervisor 这种容器运行时引 擎,会把 PodSandbox 具体实现为一个虚拟机。所以 , RuntimeService 服务接 口除了提供了针对 Container 的相关 操作,也提供了针对 Pod Sandbox 的相关操作以供 kubelet 调用 。 在启动 Pod 之前, kubelet 调用 RuntimeService.RunPodSandbox 来创建 Pod 环境,这 一 过程也包括为 Pod 设置网络资 源(分配 IP 等操作), Pod Sandbox 在被激活之后,就可以独立地创 建、启动、停止和删 除用户业务相关的 Container了,当 Pod销毁时, kubelet会在停止和删除 Pod Sandbox之 前首先停止和删除其中的 Container。

RuntirneClass

随着 CRI 机制的成熟及第三方 Container Runtime 的不断涌现,用户有了新的需求 : 在 一 个 Kubernetes 集群中配置并启用多种 Container Runtime, 不同类型的 Pod 可以选择不 同特性的 ContainerRuntime来运行,以实现资源占用或者性能、稳定性等方面的优化,这 就是 RuntimeClass 出现的背景和动力 , Kubernetes 从 1.12 版本开始引入 RuntimeClass, 用

于在启动容器时选择特定的容器运行时,目前为 Beta 阶段 。

cAdvisor

cAdvisor 是 一 个开源的分析容器资源使用率和性能特性的代理工具,它是因为容器而 产生的,因此自然支持 Docker 容器。在 Kubernetes 项目中, cAdvisor 被集成到 Kubernetes 代码中, kubelet 则通过 cAdvisor 获取其所在节点及容器上的数据 。 cAdvisor 自动查找其 所在 Node 上的所有容器,自动采集 CPU、内存、文件系统和网络使用的统计信息 。 在大 部分 Kubemetes 集群中, cAdvisor 都通过它所在 Node 的 4194 端口暴露一个简单的 UI。

在新的 Kubernetes 监控体系中, Metrics Server 用于提供 Core Metrics (核心指标), 包括 Node 和 Pod 的 CPU 和内存使用数据 。 其他 Custom Metrics ( 自定义指标)则由第三 方组件(如 Prometheus) 采集和存储 。

坚持原创技术分享,您的支持将鼓励我继续创作!