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

kubernetes-Pod基于污点、容忍度、亲和性的多种调度策略(二)

Pod调度策略

  • 一.污点-Taint
  • 二.容忍度-Tolerations
  • 三.Pod常见状态和重启策略
    • 1.Pod常见状态
    • 2.Pod的重启策略
      • 2.1测试Always重启策略
      • 2.2测试Never重启策略
      • 2.3测试OnFailure重启策略(生产环境中常用)

一.污点-Taint

在 Kubernetes 中,污点(Taint)是一种标记,用于标识一个Node节点上的某些资源或条件不可用或不可接受。当一个节点被标记了污点后,只有那些能够容忍该污点的 Pod 才能被调度到该节点上。

污点常用与以下场景:

  • 将某些节点标记为“故障”,以防止新的 Pod 被调度到这些节点上;
  • 将某些节点标记为“高负载”,以防止过多的 Pod 被调度到这些节点上,导致节点过载;
  • 将某些节点标记为“专用”,以保证只有特定的 Pod 能够被调度到这些节点上。

pod亲和性是pod属性;但是污点是节点的属性,污点定义在k8s集群的节点上的一个字段。

# 查看控住节点定义的污点
[root@master1]# kubectl describe nodes master1 | grep Taints
Taints:             node-role.kubernetes.io/control-plane:NoSchedule# 两个工作节点是没有定义污点
[root@node1]# kubectl describe nodes node1 | grep Taints
Taints:             <none>[root@node2]# kubectl describe nodes node2 | grep Taints
Taints:             <none>

1.查看定义taint的信息

# 查看帮助命令
[root@master1]# kubectl explain node.spec
······taints	<[]Object>If specified, the node's taints.
[root@master1]# kubectl explain node.spec.taints
KIND:     Node
VERSION:  v1
RESOURCE: taints <[]Object>
DESCRIPTION:If specified, the node's taints.The node this Taint is attached to has the "effect" on any pod that doesnot tolerate the Taint.FIELDS:effect	<string> -required-Required. The effect of the taint on pods that do not tolerate the taint.Valid effects are NoSchedule, PreferNoSchedule and NoExecute.Possible enum values:- `"NoExecute"` Evict any already-running pods that do not tolerate thetaint. Currently enforced by NodeController.- `"NoSchedule"` Do not allow new pods to schedule onto the node unlessthey tolerate the taint, but allow all pods submitted to Kubelet withoutgoing through the scheduler to start, and allow all already-running pods tocontinue running. Enforced by the scheduler.- `"PreferNoSchedule"` Like TaintEffectNoSchedule, but the scheduler triesnot to schedule new pods onto the node, rather than prohibiting new podsfrom scheduling onto the node entirely. Enforced by the scheduler.key	<string> -required-Required. The taint key to be applied to a node.timeAdded	<string>TimeAdded represents the time at which the taint was added. It is onlywritten for NoExecute taints.value	<string>The taint value corresponding to the taint key.

污点排斥等级:

  • NoSchedule:表示Pod不会被调度到具有该污点的节点上,不影响已经存在的Pod
  • PreferNoSchedule:表示调度器会尽量避免将Pod调度到具有该污点的节点上。(但是Pod没有定义容忍度,依然会被调度到这两个节点上)
  • NoExecute:既影响Pod调度过程,又影响现存Pod对象,如果现存Pod不能容忍节点加的污点,那么这个Pod就会被驱逐

2.定义污点

kubectl taint nodes node1 node-type=dev:NoSchedule

3.查看污点

kubectl describe nodes node1 | grep Taint

4.删除污点

kubectl taint nodes node1 node-type=dev:NoSchedule-

二.容忍度-Tolerations

当我们节点定义污点后,如果我们不定义对应的容忍度,那么Pod将不会调度到此Node节点。

方便下面实验,我把所有node节点全部定义上污点

kubectl taint nodes node1 node-type=dev:NoSchedule
kubectl taint nodes node2 node-type=dev:NoSchedule

查看容忍度的帮助:

kubectl explain pod.spec.tolerations

1.定义Pod容忍度,容忍node-type=dev,且排斥等级等于NoExecute,使用了operator=Equal这三点必须同时能满足。

cat pod1.yml 
---
apiVersion: v1
kind: Pod
metadata:name: pod1namespace: defaultlabels:app: nginxenv: devspec:tolerations:- effect: "NoExecute"   # 指定排斥等级key: "node-type"      # 污点keyoperator: "Equal"     # Equal表示等于value: "dev"          # 污点valuetolerationSeconds: 3600 # 删除Pod前等待时间,默认30scontainers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80

执行文件

kubectl  apply  -f pod1.yaml

查看状态,因为没有任何节点满足该Pod容忍,所以该Pod处于Pending状态

kubectl get pods pod1NAME    READY   STATUS    RESTARTS   AGE
pod1    0/1     Pending   0          10m

2.定义Pod容忍度,将排斥等级改为 NoSchedule,这样我们污点key,value,排斥等级都满足了,Pod才会调度 Pod资源清单文件如下:

cat pod2.yml 
---
apiVersion: v1
kind: Pod
metadata:name: pod2namespace: defaultlabels:app: nginxenv: devspec:tolerations:- effect: "NoSchedule"  # 指定排斥等级key: "node-type"      # 污点keyoperator: "Equal"     # Equal表示等于value: "dev"          # 污点valuecontainers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80

执行文件

kubectl apply -f pod2.yaml

查看状态,Pod成功调度,且状态为 Running

kubectl get pods pod2NAME    READY   STATUS    RESTARTS   AGE
pod2    1/1     Running   0          5m32s

3.定义Pod容忍度,将 operator=Exists表示满足其中一项即可容忍,下面Pod没有定义key,value,表示没有key,value方面限制,容忍排斥等级=NoSchedule的节点。

cat pod3.yml 
---
apiVersion: v1
kind: Pod
metadata:name: pod3namespace: defaultlabels:app: nginxenv: devspec:tolerations:- effect: "NoSchedule"  # 指定排斥等级 operator: "Exists"    # Exists表示满足一项即可containers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80

执行文件

kubectl  apply -f pod3.yaml

查看状态,Pod调度成功,且状态为Running

kubectl get pods pod-3NAME    READY   STATUS    RESTARTS   AGE
pod3   1/1     Running   0          5m16s

三.Pod常见状态和重启策略

1.Pod常见状态

在这里插入图片描述
第一阶段:

  • 挂起(Pending):
    • 正在创建Pod,但是Pod中的容器还没有全部被创建完成,处于此状态的Pod应该检查Pod依赖的存储是否有权限挂载、镜像是否可以下载、调度是否正常等;
    • 我们在请求创建pod时,条件不满足,调度没有完成,没有任何一个节点能满足调度条件,已经创建了pod但是没有适合它运行的节点叫做挂起,调度没有完成。
  • 失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
  • 未知(Unknown):未知状态,所谓pod是什么状态是apiserver和运行在pod节点的kubelet进行通信获取状态信息的,如果节点之上的kubelet本身出故障,那么apiserver就连不上kubelet,得不到信息了,就会看Unknown,通常是由于与pod所在的node节点通信错误。
  • Error 状态:Pod 启动过程中发生了错误
  • 成功(Succeeded):Pod中的所有容器都被成功终止,即pod里所有的containers均已terminated。

第二阶段:

  • Unschedulable:Pod不能被调度, scheduler没有匹配到合适的node节点PodScheduled:pod正处于调度中,在scheduler刚开始调度的时候,还没有将pod分配到指定的node,在筛选出合适的节点后就会更新etcd数据,将pod分配到指定的node
  • Initialized:所有pod中的初始化容器已经完成了
  • ImagePullBackOff:Pod所在的node节点下载镜像失败
  • Running:Pod内部的容器已经被创建并且启动。

扩展:还有其他状态,如下:

  • Evicted状态:出现这种情况,多见于系统内存或硬盘资源不足,可df-h查看docker存储所在目录的资源使用情况,如果百分比大于85%,就要及时清理下资源,尤其是一些大文件、docker镜像。
  • CrashLoopBackOff:容器曾经启动了,但可能又异常退出了。如pod一直在重启

2.Pod的重启策略

Pod的重启策略(RestartPolicy)应用于Pod内的所有容器,当某个容器异常退出或者健康检查失败时,kubelet将根据 重启策略来进行相应的操作。

    Pod 的 spec 中包含一个 restartPolicy 字段,其可能取值包括 Always、OnFailure 和 Never。默认值是 Always。
  • Always:只要容器异常退出,kubelet就会自动重启该容器。(这个是默认的重启策略)
  • OnFailure:当容器终止运行且退出码不为0时,由kubelet自动重启该容器。(生产环境中常用)
  • Never:不论容器运行状态如何,kubelet都不会重启该容器。

2.1测试Always重启策略

[root@master1]# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:name: demo-podnamespace: defaultlabels:app: myapp
spec:restartPolicy: Alwayscontainers:- name:  tomcatports:- containerPort: 8080image: tomcat:latestimagePullPolicy: IfNotPresent[root@master1]# kubectl apply -f pod.yaml 
pod/demo-pod created
[root@master1]# kubectl get pods -o wide 
NAME       READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
demo-pod   1/1     Running   0          10s   10.244.169.153     node2      <none>           <none># 动态显示pod状态信息
[root@master1]# kubectl get pods -o wide -w
NAME       READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
demo-pod   1/1     Running   0          22s   10.244.169.153   node2       <none>           <none># 另起一个终端会话,进入pod内部容器,正常停止 tomcat 容器服务。-c 指定容器名称。
[root@master1]# kubectl exec -it demo-pod -c tomcat -- /bin/bash
root@demo-pod:/usr/local/tomcat# ls
root@demo-pod:/usr/local/tomcat# bin/shutdown.sh 

可以看到容器服务停止后被重启了一次,Pod又恢复正常
在这里插入图片描述

# 非正常停止容器里的tomcat服务
[root@master1]# kubectl exec -it demo-pod -c tomcat -- bash
root@demo-pod:/usr/local/tomcat# ps -ef | grep tomcat
root@demo-pod:/usr/local/tomcat# kill 1

容器被终止,再一次重启,重启次数加一
在这里插入图片描述

2.2测试Never重启策略

# 修改 pod.yaml,把 Always 改为 Never
[root@master1]# kubectl delete pods demo-pod 
pod "demo-pod" deleted
[root@master1]# kubectl apply -f pod.yaml 
pod/demo-pod created
[root@master1]# kubectl get pods -o wide -w# 在另一个终端进入容器,正常停止服务
[root@master1]# kubectl exec -it demo-pod -c tomcat-pod-java -- /bin/bash
root@demo-pod:/usr/local/tomcat# bin/shutdown.sh 

查看Pod状态,发现正常停止tomcat服务,Pod正常运行,但是容器没有重启
在这里插入图片描述

# 非正常停止容器里的tomcat服务
[root@master1]# kubectl delete pods demo-pod 
pod "demo-pod" deleted
[root@master1]# kubectl apply -f pod.yaml 
pod/demo-pod created
[root@master1]# kubectl get pods -o wide -w# 在另一终端进入容器内容
[root@master1]# kubectl exec -it demo-pod -c tomcat-pod-java -- bash
root@demo-pod:/usr/local/tomcat# kill 1

看到容器的状态时Pod的状态是Error,并且没有重启,说明重启策略是Never,那么Pod里容器服务无论如何终止,都不会重启
在这里插入图片描述

2.3测试OnFailure重启策略(生产环境中常用)

# 修改 pod.yaml 文件,把 Never 改为 OnFailure
[root@master1]# kubectl delete pods demo-pod 
pod "demo-pod" deleted
[root@-master1]# kubectl apply -f pod.yaml 
pod/demo-pod created
[root@master1]# kubectl get pods -o wide -w# 在另一终端进入容器内部,正常停止服务
[root@master1]# kubectl exec -it demo-pod -c tomcat-pod-java -- bash
root@demo-pod:/usr/local/tomcat# bin/shutdown.sh

发现正常通知容器,退出码时0,容器不会重启
在这里插入图片描述

# 非正常停止容器里的tomcat服务
[root@master1]# kubectl delete pods demo-pod 
pod "demo-pod" deleted
[root@master1]# kubectl apply -f pod.yaml 
pod/demo-pod created
[root@master1]# kubectl get pods -o wide -w# 在另一终端进入容器内部
[root@master1]# kubectl exec -it demo-pod -c tomcat-pod-java -- bash
root@demo-pod:/usr/local/tomcat# kill 1

看到非正常停止的pod里的容器,容器退出码不是0,容器会被重启。
在这里插入图片描述

http://www.lryc.cn/news/329810.html

相关文章:

  • 数码管时钟--LABVIEW编程
  • linux安装指定版本docker
  • C++刷题篇——05静态扫描
  • Unity AI Navigation自动寻路
  • HarmonyOS实战开发-如何实现一个简单的健康生活应用(上)
  • React中使用antDesign框架
  • Electron安全防护实战:应对常见安全问题及权限控制措施
  • StringBuffer与StringBuilder
  • HCIP综合实验拓扑
  • nuxt学习
  • VS学习建议
  • java汇总区间
  • 【笔记】OpenHarmony设备开发:搭建开发环境(Ubuntu 20.04,VirtualBox 7.0.14)
  • 计算机视觉新巅峰,微软牛津联合提出MVSplat登顶3D重建
  • halcon图像腐蚀
  • neo4j使用详解(六、cypher即时时间函数语法——最全参考)
  • Web 前端性能优化之一:性能模型及网页原理
  • 常用的主流好用的WEB自动化测试工具强烈推荐
  • 分享几个非常不错嵌入式开源项目,一定不要错过
  • Golang基础-4
  • 2024软件设计师备考讲义——UML(统一建模语言)
  • HTML——1.简介、基础、元素
  • Rust 标准库:std::env::args() 函数简介
  • 【Blockchain】GameFi | NFT
  • 【Docker】搭建安全可控的自定义通知推送服务 - Bark
  • 国内IP代理软件电脑版:深入解析与应用指南
  • 面向对象设计之开闭原则
  • 【项目技术介绍篇】若依项目代码文件结构介绍
  • 实现DevOps需要什么?
  • Linux小程序: 手写自己的shell