概述

Kubelet是运行在每个节点上面,接收Api server 发来的pod修改/新增/删除等操作,并且监听节点状态、pod的状态、管理镜像等等。

按照上面描述,那我们看一下节点上kubelet监听的端口。

 netstat -anp | grep kubelet

kubesphere接口设计_kubernetes

可以看到kubelet是监听了10250和10248端口。

图解

下面图片展示了Kubelet管理的对象。

kubesphere接口设计_kubernetes_02

ProbeManager

介绍摘自官网配置存活、就绪和启动探针 | Kubernetes

kubelet 使用存活探针来确定什么时候要重启容器。 例如,存活探针可以探测到应用死锁(应用程序在运行,但是无法继续执行后面的步骤)情况。 重启这种状态下的容器有助于提高应用的可用性,即使其中存在缺陷。

kubelet 使用就绪探针可以知道容器何时准备好接受请求流量,当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。 这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。 若 Pod 尚未就绪,会被从 Service 的负载均衡器中剔除。

kubelet 使用启动探针来了解应用容器何时启动。 如果配置了这类探针,你就可以控制容器在启动成功后再进行存活性和就绪态检查, 确保这些存活、就绪探针不会影响应用的启动。 启动探针可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉。

1、通过HTTP方式做健康探测

2、通过exec方式做健康探测

3、通过TCP方式做探针

4、定义 gRPC 存活探针 1.24beta版新增

下面演示用HTTP方式

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: registry.k8s.io/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 5

在这个配置文件中,你可以看到 Pod 也只有一个容器。 periodSeconds 字段指定了 kubelet 每隔 3 秒执行一次存活探测。 initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 3 秒。 kubelet 会向容器内运行的服务(服务在监听 8080 端口)发送一个 HTTP GET 请求来执行探测。 如果服务器上 /healthz 路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。 如果处理程序返回失败代码,则 kubelet 会杀死这个容器并将其重启。

这里就不做详细介绍,官网的用法讲的很清晰。

OOMWatcher

从cadvisor监听事件,如果出现了oom则记录一个event事件。 对于容器的oom状态,k8s使用docker的状态State.OOMKilled判断是否经历oom事件。

cAdvisor

集成在 Kubelet 中的容器监控工具,用于收集本节点和容器的监控信息。

如下图所示,我们可以查看一下Kubernetes源码,cAdvisor是google的包。

kubesphere接口设计_kubernetes_03

Promethues里的metrics也是cAdvisor收集的数据。 

 

kubesphere接口设计_kubernetes_04

DiskSpaceManager

监听节点的硬盘容量

StatusManager

StatusManager 的主要功能是将 pod 状态信息同步到 apiserver,statusManage 并不会主动监控 pod 的状态,而是提供接口供其他 manager 进行调用。比如 probeManager。probeManager 会定时去监控 pod 中容器的健康状况,一旦发现状态发生变化,就调用 statusManager 提供的方法更新 pod 的状态。

kubesphere接口设计_Pod_05

EvictionManager

EvictionManager 会监控资源的使用情况(Memory、Disk、PID),对Pod进行驱逐。

具体规则可参考官网节点压力驱逐 | Kubernetes

kubesphere接口设计_Pod_06

VolumnManager

存储卷挂载,查找PV和PVC对象,或者通过storageClass进行关联。volumeManager的创建发生在创建Kubelet时,函数NewMainKubelet用于创建kubelet。里面调用 NewVolumeManager 来创建一个mgr。

// volumeManager implements the VolumeManager interface
type volumeManager struct {
	// kubeClient is the kube API client used by DesiredStateOfWorldPopulator to
	// communicate with the API server to fetch PV and PVC objects
	kubeClient clientset.Interface

	// volumePluginMgr is the volume plugin manager used to access volume
	// plugins. It must be pre-initialized.
	volumePluginMgr *volume.VolumePluginMgr

	// desiredStateOfWorld is a data structure containing the desired state of
	// the world according to the volume manager: i.e. what volumes should be
	// attached and which pods are referencing the volumes).
	// The data structure is populated by the desired state of the world
	// populator using the kubelet pod manager.
	desiredStateOfWorld cache.DesiredStateOfWorld

	// actualStateOfWorld is a data structure containing the actual state of
	// the world according to the manager: i.e. which volumes are attached to
	// this node and what pods the volumes are mounted to.
	// The data structure is populated upon successful completion of attach,
	// detach, mount, and unmount actions triggered by the reconciler.
	actualStateOfWorld cache.ActualStateOfWorld

	// operationExecutor is used to start asynchronous attach, detach, mount,
	// and unmount operations.
	operationExecutor operationexecutor.OperationExecutor

	// reconciler runs an asynchronous periodic loop to reconcile the
	// desiredStateOfWorld with the actualStateOfWorld by triggering attach,
	// detach, mount, and unmount operations using the operationExecutor.
	reconciler reconciler.Reconciler

	// desiredStateOfWorldPopulator runs an asynchronous periodic loop to
	// populate the desiredStateOfWorld using the kubelet PodManager.
	desiredStateOfWorldPopulator populator.DesiredStateOfWorldPopulator

	// csiMigratedPluginManager keeps track of CSI migration status of plugins
	csiMigratedPluginManager csimigration.PluginManager

	// intreeToCSITranslator translates in-tree volume specs to CSI
	intreeToCSITranslator csimigration.InTreeToCSITranslator
}

kubeClient clientset.Interface     // DesiredStateOfWorldPopulator用来与API服务器通信以获取PV和PVC对象的kube API客户端

volumePluginMgr *volume.VolumePluginMgr     // 实现初始化好的插件管理对象

desiredStateOfWorld cache.DesiredStateOfWorld      // 它包含了vm想要达成的一个状态:那些卷应该被连接,那个pods会引用这些卷。从 podManager获取数据

actualStateOfWorld cache.ActualStateOfWorld      // 它包含了实际的vm状态。在  attach,  detach, mount, and unmount  操作的时候记录这些信息

operationExecutor operationexecutor.OperationExecutor      // 异步执行 attach, detach, mount,unmount操作

reconciler reconciler.Reconciler         // 运行异步定期循环,通过使用operationExecutor 来协调desiredStateOfWorld与actualStateOfWorld

desiredStateOfWorldPopulator populator.DesiredStateOfWorldPopulator          //  运行异步定期循环,使用 PodManager 填充 desiredStateOfWorld

ImageGC

镜像的垃圾清理。

kubelet每5分钟对ImageGC进行一次清理,清除未被使用的镜像。 

kubesphere接口设计_java_07

ContainerGC

kubelet默认每一分钟执行一次容器的垃圾清理。清除未被使用的容器。

kubesphere接口设计_kubelet_08

 

CertificationManager

证书管理

kubesphere接口设计_kubernetes_09

介绍完所有对象之后还剩下

Syncloop和podWorker

首先我们先了解一下PLEG(PodLifecycleEventGenerator) 

它维护着存储Pod 信息的cache,从运行时获取容器的信息,并根据前后两次信息对比,生成对应的PodLifecycleEvent,通过eventChannel发送到kubelet syncLoop进行消费,最终由kubelet syncPod完成Pod的同步,维护着用户的“期望”。

pod的核心流程如下图:

kubesphere接口设计_kubesphere接口设计_10

 

废弃Docker Shim 原因

下面摘自弃用 Dockershim 的常见问题 | Kubernetes

为什么弃用 dockershim

维护 dockershim 已经成为 Kubernetes 维护者肩头一个沉重的负担。 创建 CRI 标准就是为了减轻这个负担,同时也可以增加不同容器运行时之间平滑的互操作性。 但反观 Docker 却至今也没有实现 CRI,所以麻烦就来了。

Dockershim 向来都是一个临时解决方案(因此得名:shim)。 你可以进一步阅读 移除 Dockershim 这一 Kubernetes 增强方案 以了解相关的社区讨论和计划。

此外,与 dockershim 不兼容的一些特性,例如:控制组(cgoups)v2 和用户名字空间(user namespace),已经在新的 CRI 运行时中被实现。 移除对 dockershim 的支持将加速这些领域的发展。


在Kubernetes 1.24,Docker shim组件正式从kubelet中移除。从Kubernetes 1.24开始,默认将无法使用  Docker Engine作为容器运行。从下图的架构可以看出,Docker shim处于一个非常尴尬的地位,它扮演着Docker、containerd 和CRI之间的翻译官或代理角色,但事实上新版本的containerd 兼容CRI接口标准,可以绕开Docker直接与CRI对接。

kubesphere接口设计_kubernetes_11