作者:手机用户2702933733 | 来源:互联网 | 2023-10-11 23:42
kubelet主要功能Pod管理在kubernetes的设计中,最基本的管理单位是pod,而不是container。pod是kubernetes在容器上的一层封装,由一组运行在同一
kubelet 主要功能
Pod 管理
在 kubernetes 的设计中,最基本的管理单位是 pod,而不是 container。pod 是 kubernetes 在容器上的一层封装,由一组运行在同一主机的一个或者多个容器组成。如果把容器比喻成传统机器上的一个进程(它可以执行任务,对外提供某种功能),那么 pod 可以类比为传统的主机:它包含了多个容器,为它们提供共享的一些资源。
之所以费功夫提供这一层封装,主要是因为容器推荐的用法是里面只运行一个进程,而一般情况下某个应用都由多个组件构成的。
pod 中所有的容器最大的特性也是最大的好处就是共享了很多资源,比如网络空间。pod 下所有容器共享网络和端口空间,也就是它们之间可以通过 localhost 访问和通信,对外的通信方式也是一样的,省去了很多容器通信的麻烦。
除了网络之外,定义在 pod 里的 volume 也可以 mount 到多个容器里,以实现共享的目的。
最后,定义在 pod 的资源限制(比如 CPU 和 Memory) 也是所有容器共享的。
容器健康检查
创建了容器之后,kubelet 还要查看容器是否正常运行,如果容器运行出错,就要根据设置的重启策略进行处理。检查容器是否健康主要有三种方式:执行命令,http Get,和tcp连接。
不管用什么方式,如果检测到容器不健康,kubelet 会删除该容器,并根据容器的重启策略进行处理(比如重启,或者什么都不做)。
容器监控
kubelet 还有一个重要的责任,就是监控所在节点的资源使用情况,并定时向 master 报告。知道整个集群所有节点的资源情况,对于 pod 的调度和正常运行至关重要。
kubelet 使用 cAdvisor 进行资源使用率的监控。cAdvisor 是 google 开源的分析容器资源使用和性能特性的工具,在 kubernetes 项目中被集成到 kubelet 里,无需额外配置。默认情况下,你可以在 localhost:4194 地址看到 cAdvisor 的管理界面。
除了系统使用的 CPU,Memory,存储和网络之外,cAdvisor 还记录了每个容器使用的上述资源情况。
kubelet创建pod启动过程
流程图:
流程内容分析
kubelet通过gRPC调用dockershim发起创建容器,CRI即容器运行时接口(container runtime interface),目前dockershim的代码内嵌在kubele中,所以接受创建容器的就是kubelet进程。
dockershim把创建容器的命令转换成docker daemon可以识别的命令,之后发送给docker daemon创建容器。
docker daemon在1.12版本之后就会把创建容器的命令分发给另一个进程: comtainerd。
containerd收到创建容器的命令后,创建另一个进程:containerd-shim进程,由该进程执行具体的创建命令,containerd进程做为父进程存在。
创建容器的时候需要namespace隔离容器启动和创建需要的资源,cgroup限制容器可以使用资源的大小等操作,这些事情该怎么做已经有看公开的规范OCI(open container initivtive 开放容器标准),它的一个参考实现叫做runc。于是containerd--shim在这一步需要调用runc命令,来启动容器。
runc启动容器之后就直接退出,containerd-shim则会成为容器进程的父进程,收集容器进程的状态,上报给contanierd,并在容器种pid为1的进程退出后接管容器中的子进程进行清理,确保不会出现僵尸进程。
pod生命周期:
链接:https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/
- 1.pod生命周期调度只有一次,scheduler调度到node会为pod打上node uid全局唯一,当pod重启时不会改变node。更新后pod名字可以不变uid会改变。
- 2.当节点失效或资源紧缺被驱逐后才会重新调度。
- 3.service-api向kubelet发送停止指令,pod会终止。 #pod停止为优雅停止,在kill之前会给定宽容期,与微服务优雅停止相近都是给容器或服务发送 TERM信号拒绝接受新的请求,并在宽容期后停止容器。
这其中有两个名词概念容易混淆
CRI:容器运行时接口 container runtime interface
其主要的作用:
- 针对容器操作的接口,包括容器的创建、启动和停止等
- 针对镜像的操作,拉去、删除镜像等
- 针对podsandbox(容器沙箱环境)
OCI:开放容器标准 open container initiative
主要作用,制作容器
容器镜像制作内容,即imagespec
容器需要接收哪些指令,即runtimespec
kubelet pod健康检查
kubelet默认对于容器检查非常的简单粗暴,就是对于入口程序pid为1的程序,只要监测是否存活即为容器正常。
kubelet对于容器资源的监控主要使用cAdvisor,cAdvisor是用于针对于docker stats接口的采集工具。kubelet内部集成了cAdvisor,内部函数中定义了定时器及监控采集,1秒钟就会去采集汇报。
- 健康检查三种机制
- 通过命令返回值来判断 (执行命令后返回值非0则为失败)
- 通过tcp端口是否开启来判断容器是否正常
- 通过http rest请求来判断是否正常
#rest简单描述为前后台通讯GET/POST,客户端与服务端通信,用户通过socket发送请求后选择子标签,服务端返回子标签json,客户端在发送请求加上子标签,对应的调用标签对应的接口或功能。rest也是无状态统一接口,客户端负责用户用户状态维持。
基于cmd 健康检查
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-demo
namespace: dev
spec:
selector:
matchLabels:
app: web-demo
replicas: 1
template:
metadata:
labels:
app: web-demo
spec:
containers:
- name: web-demo
image: hub.mooc.com/kubernetes/web:v1
ports:
- containerPort: 8080
livenessProbe:
exec:
command:
- /bin/sh
- -c
- ps -ef|grep java|grep -v grep
initialDelaySeconds: 10 #等待容器启动时间
periodSeconds: 10 #监控检查等待时间间隔
failureThreshold: 2 #健康检查连续失败次数
successThreshold: 1 #健康检查从错误到正常次数
timeoutSeconds: 5 #执行命令超时时间
pod-cmd.yaml
#pod创建后,会在配置文件中添加liveness exec [具体命令及执行时间,判断返回值等]。本质是容器启动时kubelet为容器添加默认执行命令。判断命令执行返回值,echo $? 上次命令执行返回值查看。
基于http健康检查
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-demo
namespace: dev
spec:
selector:
matchLabels:
app: web-demo
replicas: 1
template:
metadata:
labels:
app: web-demo
spec:
containers:
- name: web-demo
image: hub.mooc.com/kubernetes/web:v1
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /examples/index.html
port: 8080
scheme: HTTP
initialDelaySeconds: 10 #等待容器启动时间
periodSeconds: 5 #检查等待时间 间隔
failureThreshold: 1 #健康检查连续失败次数
successThreshold: 1 #从失败到成功的次数
timeoutSeconds: 5 #执行命令超时时间
pod-http.yaml
#http健康检查通过http返回值200来判断,300 400 500等都为失败,使用一定要通过一个稳定静态文件来获取。service添加后端pod时是根据后端pod端口是否启动进行判断,本质是tcp判断。http服务一定要注意。
基于tcp端口健康检查
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-demo
namespace: dev
spec:
selector:
matchLabels:
app: web-demo
replicas: 1
template:
metadata:
labels:
app: web-demo
spec:
containers:
- name: web-demo
image: hub.mooc.com/kubernetes/web:v1
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 20 #等待容器启动时间
periodSeconds: 10 #检查隔间时间
failureThreshold: 2 #连续失败次数
successThreshold: 1 #失败到成功次数
timeoutSeconds: 5 #超时时间
pod-tcp.yaml
基于http状态向service发送就绪状态
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-demo
namespace: dev
spec:
selector:
matchLabels:
app: web-demo
replicas: 1
template:
metadata:
labels:
app: web-demo
spec:
containers:
- name: web-demo
image: hub.mooc.com/kubernetes/web:v1
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
failureThreshold: 2
successThreshold: 1
timeoutSeconds: 5
readlinessProbe: #用于向service发送状态
httpGet:
path: /examples/index.html
port: 8080
scheme: HTTP
initialDelaySeconds: 10 #等待容器启动时间
periodSeconds: 5 #检查等待时间 间隔
failureThreshold: 1 #健康检查连续失败次数
successThreshold: 1 #从失败到成功的次数
timeoutSeconds: 5 #执行命令超时时间
tcp-http.yaml
用tcp去探测启动探针与存活探针,用http返回去向service发送就绪状态值。通过改变容器状态值为read。
###当容器restart,检查时可以将Pod 的 spec
中包含一个 restartPolicy
字段修改,取值包括 Always、OnFailure 和 Never。默认值是 Always。也可以修改探针策略把探针修改为肯定可以成功的值。
Scheduler调度过程
流程图:
1.kubectl向api-service发送创建指令。api-service将创建指令转换为yaml存入etcd中。
2.informer reflector watch api-service 通过pod信息中是否绑定nodename。将请求分配给scheduler。
3.scheduler将pod放入优先级队列中,通过informer store取出node节点信息(node节点信息由kubelet通过定时器定时向apiserver上报 写入etcd中)
4.执行预选策略,查询是否绑定label,端口是否存在,cpu及内存等是否超过resouce限定,挂载文件类型是否匹配,nodeselect规则匹配,节点状态是否正常。筛选出符合的node。
5.执行优选策略,通过cpu及内存平衡性(pod limit总的值剩余量及当前运行状态),node中是否预先存在运行镜像,同一deployment pod是否调度在同一node中等对其进行评分,分值最高的为选中节点。
6.scheduler将该pod绑定node,赋予一个nodename,并生成全局唯一uid,上传到apiservice,写入etcd。
7.informer reflector watch api-service 将pod信息通知node kubelet,kublet通过相应动作策略通过cri指令发送给容器守护进程,容器进程调用cni及oci创建pod(cni及cgroup等分配给pause实现部分资源共享)。
8.kubelet将pod节点信息上传给api-service。informer进行监听同步,通知到controller。