前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >图解K8s源码 - kubelet 篇

图解K8s源码 - kubelet 篇

作者头像
才浅Coding攻略
发布2022-12-12 18:19:51
7770
发布2022-12-12 18:19:51
举报
文章被收录于专栏:才浅coding攻略才浅coding攻略

我们在之前的文章中介绍了 Master 控制平面中的三大组件:kube-apiserver、kube-controller-manager、kube-scheduler,它们分别负责 k8s 集群的资源访问入口、集群状态管理、集群调度。

本篇将介绍Node 节点上的重要组件之一的 kubelet。kubelet 是在每个 Node 节点上运行的主要 “节点代理”。它接受通过各种机制(主要是kube-apiserver)提供的一组 PodSpec(描述pod 的 YAML 或 JSON对象) 并保证这些 PodSpec 中描述的 pod 正常健康运行。

Kubelet 的工作原理

kubelet的核心是一个控制循环 SyncLoop, 驱动该控制运行的事件包括4种:

  • pod 更新事件;
  • pod 生命周期变化;
  • kubelet 本身设置的执行周期;
  • 定时的清理事件。

说回图中,kubelet 启动时首先是设置 Listers,即注册它关心的各种事件的 Informer,这些 Informer 就是 SyncLoop 需要处理的数据的来源。

另外,在SyncLoop循环上还有许多子控制循环,就是图中右侧的一些Manager。比如 Node Status Manager 就负责响应 Node 的状态变化,然后将 Node 的状态收集起来,通过 Heartbeat 的方式上报给 APIServer。

kubelet 采用 watch 机制监听与自己相关的 pod 的变化,即过滤条件是该 pod 的 nodeName 字段与自己相同。然后将这些pod 信息缓存在自己的内存中。

当一个 pod 完成调度与节点绑定后,kubelet 检查该 pod 在内存中的状态,确定这个是新调度过来的 pod,从而触发Handler中的ADD事件对应的处理逻辑,就是图中 HandlerPods 部分。

在处理过程中,kubelet 单独起一个 名为 Pod Update Worker 的 goroutine 来完成对 pod 的处理工作。如果是 ADD 事件的话,kubelet 就会为这个新的 Pod 生成对应的 Pod Status,检查 Pod 所声明使用的 Volume 是不是已经准备好。然后,调用下层的容器运行时(比如 Docker),开始创建这个 Pod 所定义的容器。而如果是 UPDATE 事件,kubelet 就会根据 Pod 对象具体的变更情况,调用下层容器运行时进行容器的重建工作。

由于 k8s 需要屏蔽下层容器运行时的差异,也是为了解耦 kubelet 与容器运行时,所以 kubelet 调用下层容器运行时的执行过程,并不会直接调用 Docker 的 API,而是通过一组叫作 CRI(Container Runtime Interface,容器运行时接口)的 gRPC 接口来间接执行的。

kubelet 通过 CRI 接口来和第三方容器运行时进行通信,操作容器与镜像。实现了 CRI 接口的容器运行时通常称为 CRI shim, 这是一个 gRPC Server,监听在本地的 unix socket 上。它用于将 CRI 请求,转换成对 containerd 的调用,然后创建出 runC 容器,runC 项目,负责执行设置容器 Namespace、Cgroups 和 chroot 等基础操作的组件的操作。

一般来说CRI接口可以分为两组:

  • ImageService:主要是容器镜像相关操作,比如拉取镜像、删除镜像等。
  • RuntimeService:主要是跟容器相关操作,比如创建、启动、删除Container、Exec等。

Kubelet 中事件处理机制

在之前的文章中提到过,k8s 中的各个组件会将运行时产生的各种事件汇报到 apiserver,使用 kubectl describe 可以看到其相关的 events。

events 在 vendor/k8s.io/api/core/v1/types.go 中进行定义:

代码语言:javascript
复制
type Event struct {
 metav1.TypeMeta `json:",inline"`
 metav1.ObjectMeta `json:"metadata" protobuf:"bytes,1,opt,name=metadata"`
 InvolvedObject ObjectReference `json:"involvedObject" protobuf:"bytes,2,opt,name=involvedObject"`
 Reason string `json:"reason,omitempty" protobuf:"bytes,3,opt,name=reason"`
 Message string `json:"message,omitempty" protobuf:"bytes,4,opt,name=message"`
 Source EventSource `json:"source,omitempty" protobuf:"bytes,5,opt,name=source"`
 FirstTimestamp metav1.Time `json:"firstTimestamp,omitempty" protobuf:"bytes,6,opt,name=firstTimestamp"`
 LastTimestamp metav1.Time `json:"lastTimestamp,omitempty" protobuf:"bytes,7,opt,name=lastTimestamp"`
 Count int32 `json:"count,omitempty" protobuf:"varint,8,opt,name=count"`
 Type string `json:"type,omitempty" protobuf:"bytes,9,opt,name=type"`
 EventTime metav1.MicroTime `json:"eventTime,omitempty" protobuf:"bytes,10,opt,name=eventTime"`
 Series *EventSeries `json:"series,omitempty" protobuf:"bytes,11,opt,name=series"`
 Action string `json:"action,omitempty" protobuf:"bytes,12,opt,name=action"`
 Related *ObjectReference `json:"related,omitempty" protobuf:"bytes,13,opt,name=related"`
 ReportingController string `json:"reportingComponent" protobuf:"bytes,14,opt,name=reportingComponent"`
 ReportingInstance string `json:"reportingInstance" protobuf:"bytes,15,opt,name=reportingInstance"`
}

InvolvedObject 表示和事件关联的对象,Source 表示事件源。使用 kubectl 看到的事件一般包含 Type、Reason、Age、From、Message 几个字段。另外,k8s 中 events 目前只有两种类型:"Normal" 和 "Warning"。

我将event的生成、广播和处理涉及的主要函数做了解析标注并绘制成矢量图,流程如下:

这部分的代码逻辑在 github 上有个精简版的实现 demo,值得一看。

代码请参考:https://github.com/gosoon/k8s-learning-notes/tree/master/k8s-package/events

参考:

《深入剖析 Kubernetes》

https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/kubelet/

https://blog.tianfeiyu.com/source-code-reading-notes/kubernetes/k8s_events.html

k8s系列往期文章列表:

Kubernetes微服务常见概念及应用

图解K8s源码 - 序章 - K8s组件架构

图解K8s源码 - k8s核心数据结构

图解K8s源码 - kube-apiserver篇

图解K8s源码 - kube-apiserver下的RBAC鉴权机制

图解K8s源码 - kube-controller-manager篇

图解K8s源码 - kube-scheduler篇

持续更新中……

END

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 才浅coding攻略 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档