当前位置: 首页 > news >正文

Kubernetes控制平面组件:Kubelet

文章目录

  • 一、介绍
    • 1、节点管理
    • 2、获取 Pod 清单方式
  • 二、kubelet架构
  • 三、kubelet管理Pod的核心流程
  • 四、pod启动流程(全是重点)
    • 1、启动pod全流程(从kubectl create到得到pod)
    • 2、SandboxContainer
    • 3、kubelet部分启动pod流程(更详细函数描述)

一、介绍

kubelet是node的守护神,维护了node上应用的生命周期,让node可以正常运行。

每个节点上都运行一个 kubelet 服务进程,默认监听 10250 端口。

  • 接收并执行 master 发来的指令;
  • 管理 Pod 及 Pod 中的容器;
  • 每个 kubelet 进程会在 API Server 上注册节点自身信息,定期向 master 节点汇报节点的资源使用情况,并通过cAdvisor监控节点和容器的资源。

1、节点管理

节点管理主要是节点自注册节点状态更新

  • kubelet 可以通过设置启动参数 --register-node 来确定是否向 API Server 注册自己自注册模式;
  • 如果 kubelet 没有选择自注册模式,则需要用户自己配置 Node 资源信息,同时需要告知 kubelet集群上的 APIServer 的位置;
  • kubelet 在启动时通过 API Server 注册节点信息,并定时向 API Server 发送节点新消息,APIServer在接收到新消息后,将信息写入 etcd

2、获取 Pod 清单方式

  • 文件:启动参数 --config 指定的配置目录下的文件即static pod。(默认/etc/Kubernetes/manifests/)。该文件每20秒重新检查一次(可配置)。
  • HTTP endpoint (URL):启动参数–manifest-url 设置。每20 秒检查一次这个endpoint(可配置)。
  • API Server:通过 API Server 监听 etcd 目录,同步 Pod 清单。
  • HTTP Server:kubelet 侦听 HTTP 请求,并响应简单的 API 以提交新的 Pod 清单。

二、kubelet架构

在这里插入图片描述

  • API:10250负责和客户端交互,10255负责只读,10248负责自身的探活。
    在这里插入图片描述
  • ProbeManager:livenessProbe,readnessProbe,startupProbe,由kubelet发起负责node上的pod的探活。
  • OOMWatcher:监听进程是否触发了OOM并上报给kubelet。
  • GPUManager:管理node上的GPU。
  • CAdvisor:内嵌于kubelet,基于cgroup获取node上运行的应用资源情况。
  • DiskSpaceManager:检测pod的磁盘空间大小。
  • StatusManager:管理node的状态。
  • EvictionManager:检测node资源使用情况,当到达一定水位时,它会按照既定策略把低优先级的pod驱逐掉。
  • Volume Manager:负责pod的存储。
  • Image GC:扫描node上不活跃的镜像,把这些镜像删除掉。
  • Container GC:清除Exited状态的容器。
  • ImageManager:负责镜像管理。
  • CertificateManager:kubelet是可以签证书的,负责证书管理。
  • syncLoop:watch api对象。
  • PodWorker:当syncLoop接收到pod变更通知,PodWorker就会去处理这些事件。比如看pod是否启动,如果没有就会把pod通过CRI启动。
  • CRI:容器运行时接口。可以通过kubelet的启动命令指定。
    🔥 docker shim(kubelet内置):基于docker,目前1.20版本之后已被k8s废弃,不再内置。
    🔥 remote container runtime:基于containerd或者cri-o。

三、kubelet管理Pod的核心流程

在这里插入图片描述

  • 通过apiserevr监听pod的状态变化即 pod update或者add事件。
  • sycnLoop接收到事件后,会把事件存到UpdatePodOptions中。
  • 不同的worker都会从队列中获取pod变更事件的清单
  • 针对每一个pod都会进行syncPod,然后会执行computePodActions,即对于这个pod需要执行什么行为。它会对比node上已经启动的容器进程,如果pod是新的,就会create,如果已经存在了,就会delete或者update。
  • 通过CRI启动或者删除pod。
  • PLEG上报pod的状态信息。维护了一个本地的pod cache,定期的向CRI发起一个relist的操作来获取当前node上的正在运行的pod清单。最后再通过pod lifecycle events上报给apiserver。

注意:
这里可以清晰的看到,如果runtime挂了,relist操作就会失败,pod状态无法上报,k8s就会认为这个node挂了,导致pod驱逐

如果node上的容器进程过多,比如exited状态容器过多,relist就会一直遍历这些容器,导致耗时过长,没有在规定的时间内返回pod状态信息,PLEG就会超时,导致node状态变为Unknown,pod驱逐。

四、pod启动流程(全是重点)

1、启动pod全流程(从kubectl create到得到pod)

我环境用的是containerd,这里也以containerd为例介绍pod的启动流程。
在这里插入图片描述

  • 用户发送创建pod请求到apiserver。
  • apiserver收到请求后会把对象存储到etcd中。存储完成后会返回给apiserver。
  • scheduler 是watch apiserver的,watch到这个pod创建事件,找到一个合适的node完成调度,绑定pod。
  • apiserver再把pod的信息存储到etcd中。
  • kubelet watch到node上绑定的pod,首先会去启动SandboxContainer。
  • containerd调用cni的插件去创建pod,即配置网络。
  • cni插件把pod的ip返回给containerd,再返回给kubelet。
  • kubelet调用containerd拉取镜像,创建主容器,启动主容器。
  • kubelet上报pod状态给apiserver。
  • apiserver再把pod状态存储到etcd中。

2、SandboxContainer

kubelet启动容器的时候,启动的是多个容器进程。

比如这里的nginx pod,不仅有一个nginx主容器,还有一个pause容器,这个pause容器,在k8s中就叫做SandboxContainer。pause是一个永远sleep,不会退出,不消耗任何资源的进程

为什么要有SandboxContainer?
1、容器技术依靠的是namespace,cgroup,rootfs。容器启动后可以和某个网络namespace关联,就可以有独立的网络配置。业务容器本身进程可能不稳定,如果每一次容器退出都需要重新配置网络,就会对系统产生一定的压力,效率也不高。SandboxContainer就可以提供一个稳定的底座,网络就基于这个容器来做的,这样其他容器退出也不会更改其网络存储等配置。

2、某些容器进程启动是需要网络就绪的,比如java进程,或者某些需要获取第三方token的进程。这样就需要一个额外的容器来提前启动网络。把主容器的网络namespace挂载在这个sandbox即可。

3、kubelet部分启动pod流程(更详细函数描述)

这里是更详细的pod启动流程图。

  • 首先会做一个准入:看pod的资源需求是否满足node上的资源状况。
  • 检查网络插件状态:如果cni挂了,pod是起不来的。
  • 配置pod的cgroup。
  • 创建pod数据目录。
  • 等待pod存储就绪,这里就通过CSI来attach and mount pod的存储目录。
  • syncPod:计算sandbox和容器的变化,如果发生了变化,就需要重新启动容器了。即上文中的ComputePodActions。
  • 如果是创建pod:首先会生成sandbox的配置文件,然后创建数据目录,然后再创建sandbox。
  • sandbox通过grpc接口调用CRI创建pod,过程中再调用CNI创建网络。
    其他流程都是一致的。
    在这里插入图片描述

相关文章:

  • 忘记背后,努力面前【开学季flag】
  • 2022-09-04 瞒春 学习笔记
  • 谷歌?亲斤手不推荐 选它就对了
  • Ubuntu20.04下载opencv3.4--未完善
  • (待修改)PyG安装步骤
  • vue2中vant适配-把px都换算成rem
  • 猿创征文|Spring5梦开始的地方:入门必看
  • [中秋特别定制版本]绝美登录页面搭配[登录数据存储到服务器](服务器宝塔数据库开通+短信服务开通+后端redis验证码缓存)
  • 【笔记】文献阅读[YOLOV1]-You_only_look_once_Unified_real-time_object_detection
  • 基于STM32与ESP8266的太空人WiFi天气时钟(代码开源)
  • leetcode 83. Remove Duplicates from Sorted List 删除排序链表中的重复元素(简单)
  • Java环境安装配置步骤介绍
  • 基于Asp.Net Mvc开发的个人博客系统
  • 猿创征文|【C++之友元函数与友元类】输出年龄
  • 猿创征文 |【C++】面向对象之微观部分——类的组成(上)
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • Android单元测试 - 几个重要问题
  • ES6--对象的扩展
  • es6要点
  • Go 语言编译器的 //go: 详解
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • javascript从右向左截取指定位数字符的3种方法
  • Making An Indicator With Pure CSS
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • 安卓应用性能调试和优化经验分享
  • 笨办法学C 练习34:动态数组
  • 从tcpdump抓包看TCP/IP协议
  • 简单实现一个textarea自适应高度
  • 深度解析利用ES6进行Promise封装总结
  • 世界上最简单的无等待算法(getAndIncrement)
  • 原生JS动态加载JS、CSS文件及代码脚本
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • # C++之functional库用法整理
  • #mysql 8.0 踩坑日记
  • #控制台大学课堂点名问题_课堂随机点名
  • #数学建模# 线性规划问题的Matlab求解
  • $(function(){})与(function($){....})(jQuery)的区别
  • (70min)字节暑假实习二面(已挂)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • ***详解账号泄露:全球约1亿用户已泄露
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .net 后台导出excel ,word
  • .net 微服务 服务保护 自动重试 Polly
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
  • [ C++ ] STL---string类的模拟实现
  • []AT 指令 收发短信和GPRS上网 SIM508/548
  • [17]JAVAEE-HTTP协议
  • [20190401]关于semtimedop函数调用.txt
  • [2669]2-2 Time类的定义
  • [AI]ChatGPT4 与 ChatGPT3.5 区别有多大
  • [Angular] 笔记 7:模块
  • [C语言]——分支和循环(4)