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

k8s——Pod进阶(资源限制和探针)

一、资源限制

  1.1 资源限制的定义

    当定义Pod时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是CPU和内存大小,以及其他类型的资源。

    当为Pod中的容器指定了request资源时,调度器就使用该信息来决定将Pod调度到哪个节点上。当还为容器指定了limit资源时,kubelet就会确保运行的容器不会使用超出所设的limit资源量。kubelet还会为容器预留所设的request资源量, 供该容器使用。

    如果Pod运行所在的节点具有足够的可用资源,容器可以使用超出所设置的request资源量。不过,容器不可以使用超出所设置的limit资源量。

    如果给容器设置了内存的limit值,但未设置内存的request值,Kubernetes会自动为其设置与内存limit相匹配的request值。 类似的,如果给容器设置了CPU的 limit值但未设置CPU的request 值,则Kubernetes自动为其设置CPU的request值并使之与CPU的limit值匹配。

  官方示例:https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/icon-default.png?t=N7T8https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/

  1.2 Pod和容器的资源请求和限制

spec.containers[].resources.requests.cpu定义创建容器时预分配的CPU资源
spec.containers[].resources.requests.memory定义创建容器时预分配的内存资源
spec.containers[].resources.limits.cpu定义 cpu 的资源上限 
spec.containers[].resources.limits.memory定义内存的资源上限

  1.3 CPU资源单位

    CPU资源的request和limit以cpu为单位。Kubernetes中的一个cpu相当于1个vCPU(1个超线程)。
    Kubernetes也支持带小数 CPU 的请求。spec.containers[].resources.requests.cpu为0.5的容器能够获得一个cpu的  、一半CPU资源(类似于Cgroup对CPU资源的时间分片)。表达式0.1等价于表达式100m(毫核),表示每1000毫秒内容器可以使用的CPU时间总量为 0.1*1000 毫秒。
    Kubernetes不允许设置精度小于1m的CPU资源。 

  1.4 内存资源单位

    内存的request和limit以字节为单位。可以以整数表示,或者以10为底数的指数的单位(E、P、T、G、M、K)来表示, 或者以2为底数的指数的单位(Ei、Pi、Ti、Gi、Mi、Ki)来表示。

  1.5 实验操作

  1.5.1 OOM资源不足被干掉

apiVersion: v1
kind: Pod
metadata:name: ky-web-db
spec:containers:- name: webimage: nginxenv:- name: WEB_ROOT_PASSWORDvalue: "password"resources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"- name: dbimage: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalue: "abc123"resources:requests:memory: "64Mi"cpu: "0.25"limits:memory: "128Mi"cpu: "500m"

资源不足第一个进程被杀死,注意如果节点上有资源会拉取节点资源创建,可先把节点关闭

查看日志信息,db因资源不足被干掉

    1.5.2 资源充足

apiVersion: v1
kind: Pod
metadata:name: ky-web-db
spec:containers:- name: webimage: nginxenv:- name: WEB_ROOT_PASSWORDvalue: "password"resources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"- name: dbimage: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalue: "abc123"resources:requests:memory: "64Mi"cpu: "0.5"limits:memory: "1Gi"cpu: "1"

给足资源后,状态为running 

查看日志信息后,调度给了node01

  查看node01详细信息,可以看到资源详细情况 

二、探针

  2.1 探针的定义

    健康检查:又称为探针(Probe) ,探针是由kubelet对容器执行的定期诊断。 

  2.2 探针的规则

  • 存活探针(livenessProbe):判断容器是否运行正常,如果探测失败则杀死容器(不是pod),容器根据容器策略决定是否重启
  • 就绪探针(readinessProbe):判断pod是否能进入ready状态,做好接受请求的准备。如果探针失败会进入not ready状态且从service自愿的endpoints中剔除,service将不会再把访问请求转发给pod
  • 启动探针(startupProbe):判断容器内的应用是否启动成功,在检测成功状态为success真会玩,其他的探针都会处于失效状态

  2.3 Probe三种检查方式

  • exec:通过command设置,执行在容器内执行的linux命令来进行探测,如果返回码为0,则为探测成功,非0就为探测失败
  • httpget:通过http get请求访问制定容器端口和url路径,如果访问状态吗为>=200且<=400(2xx 300),则认为探测成功
  • tcpsocket:通过制定的端口发送TCP连接,如果端口无误且三次握手成功(TCP连接成功),则认为探测成功

  2.4 探测的结果

  • 成功:容器通过了诊断。
  • 失败:容器未通过诊断。
  • 未知:诊断失败,因此不会采取任何行动

  2.5 实验部署

  2.5.1 exec方式——liveness

apiVersion: v1
kind: Pod
metadata:labels:test: livenessname: liveness-exec
spec:containers:- name: livenessimage: busyboximagePullPolicy: IfNotPresentargs:             ###启动容器参数- /bin/sh- -c- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60livenessProbe:     #定义了容器的就绪探针exec:            #在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功。command:       #指定了执行的命令- cat- /tmp/healthyfailureThreshold: 1            #就绪探针在连续失败一次后被视为失败initialDelaySeconds: 5         #延迟5秒启动容器periodSeconds: 5               #每隔5秒探测一次

- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60

创建一个名为 /tmp/healthy 的文件,暂停执行脚本,等待 30 秒钟,删除后,再次暂停执行脚本,等待额外的 60 秒钟

initialDelaySeconds:指定kubelet在执行第一次探测前应该等待5秒,即第一次探测是在容器启动后的第6秒才开始执行。默认是0秒,最小值是0。


periodSeconds:指定了kubelet应该每5秒执行一次存活探测。默认是10秒。最小值是1。


failureThreshold: 当探测失败时,Kubernetes将在放弃之前重试的次数。 存活探测情况下的放弃就意味着重新启动容器。就绪探测情况下的放弃Pod会被打上未就绪的标签。默认值是 3。最小值是1。


timeoutSeconds:探测的超时后等待多少秒。默认值是1秒。最小值是1。(在Kubernetes 1.20版本之前,exec探针会忽略timeoutSeconds探针会无限期地持续运行,甚至可能超过所配置的限期,直到返回结果为止。)

总结:可以看到Pod中只有一个容器。kubelet在执行第一次探测前需要等待5秒,kubelet会每5秒执行一次存活探测。kubelet 在容器内执行命令cat /tmp/healthy来进行探测。如果命令执行成功并且返回值为0,kubelet 就会认为这个容器是健康存活的。 当到达第31秒时,这个命令返回非0值,kubelet会杀死这个容器并重新启动它。

探针失败 

/tmp/healthy文件不存在,探测失败 

  2.5.2 httpGet方式

apiVersion: v1
kind: Pod
metadata:name: liveness-httpgetnamespace: default
spec:containers:- name: liveness-httpget-containerimage: soscscs/myapp:v1           #soscscs:nginx1.12imagePullPolicy: IfNotPresent      #拉取策略ports:- name: httpcontainerPort: 80livenessProbe:              #探针httpGet:port: httppath: /index.htmlinitialDelaySeconds: 1     #延迟1秒开始探测periodSeconds: 3          #每3秒探测一次timeoutSeconds: 10         #超时时间10秒

删除index.html页面,报错404,探针失败

httpget:通过http get请求访问制定容器端口和url路径,如果访问状态吗为>=200且<=400(2xx 300),则认为探测成功

当我们删除页面后会404报错,然后就会探测失败,最后会重启 

  2.5.3 tcpSocket方式

apiVersion: v1
kind: Pod
metadata:name: xzq-tcp-live
spec:containers:- name: nginximage: soscscs/myapp:v1livenessProbe:initialDelaySeconds: 5  #第一次探测延迟5秒,第6秒开始timeoutSeconds: 1tcpSocket:port: 8080periodSeconds: 10     #每10秒探测一次failureThreshold: 2   #允许2次失败

  2.5.4 就绪检测——readiness

apiVersion: v1
kind: Pod
metadata:name: readiness-httpgetnamespace: default
spec:containers:- name: readiness-httpget-containerimage: soscscs/myapp:v1imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index1.htmlinitialDelaySeconds: 1periodSeconds: 3livenessProbe:httpGet:port: httppath: /index.htmlinitialDelaySeconds: 1periodSeconds: 3timeoutSeconds: 10

有实例在运行,但是就绪失败

 探针http,404报错

bash可能是权限不足,用sh进入写一个页面

kubectl describe pod readiness-httpget

   2.5.5 就绪检测2——readiness

apiVersion: v1
kind: Pod
metadata:name: myapp1labels:app: myapp
spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10 
---
apiVersion: v1
kind: Pod
metadata:name: myapp2labels:app: myapp
spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10 
---
apiVersion: v1
kind: Pod
metadata:name: myapp3labels:app: myapp
spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10 
---
apiVersion: v1
kind: Service
metadata:name: myapp
spec:selector:app: myapptype: ClusterIPports:- name: httpport: 80targetPort: 80

 查看集群中服务、pod和端点的信息

删除页面看效果,readiness探测失败,Pod无法进入READY状态,且端点控制器将从 endpoints中剔除删除该Pod的IP地址

  2.5.6 启动、退出动作

apiVersion: v1
kind: Pod
metadata:name: lifecycle-demo
spec:containers:- name: lifecycle-demo-containerimage: soscscs/myapp:v1lifecycle:   #此为关键字段,定义容器的生命周期postStart:   #容器启动后立即执行的操作exec:          #允许容器启动后执行特定的命令command: ["/bin/sh", "-c", "echo Hello from the postStart handler >> /var/log/nginx/message"]      preStop:    #容器停止后立即执行的命令exec:command: ["/bin/sh", "-c", "echo Hello from the poststop handler >> /var/log/nginx/message"]volumeMounts:       #将存储卷挂载到容器指定路径上- name: message-log      #存储卷名字mountPath: /var/log/nginx/readOnly: false       #可以读和写initContainers:- name: init-myserviceimage: soscscs/myapp:v1command: ["/bin/sh", "-c", "echo 'Hello initContainers'   >> /var/log/nginx/message"]volumeMounts:- name: message-logmountPath: /var/log/nginx/readOnly: falsevolumes:- name: message-loghostPath:   #hostPath类型,将存储卷挂载到主机上path: /data/volumes/nginx/log/      #主机路径type: DirectoryOrCreate      #类型为目录,如无目录,会自动创建

创建后去node01查看日志

进入到日志路径下,日志瞎看到先初始化后才探针 

在node01下删除pod 

关闭探针=关闭生命周期 

cat message

相关文章:

  • 解决 Git commit 或 Git merge 跑到 VIM 里面去了
  • C#中的数组探索
  • C#面:.Net中会存在内存泄漏吗,请简单描述
  • python数据库操作
  • 校园导航系统C++
  • ReDos攻击浅析
  • 【揭秘】如何借助聚道云软件连接器,实现差旅管理新飞跃!
  • 神器!!Python热重载调试【送源码】
  • 【康耐视国产案例】智能AI相机机器视觉精准快速实现包裹标签的智能粘贴
  • 问题排查|记录一次基于mymuduo库开发的服务器错误排查(段错误--Segmentation fault (core dumped))
  • 虚拟现实环境下的远程教育和智能评估系统(一)
  • 头歌数据结构与算法课程设计中-硬币找零
  • vue项目中markdown显示为html
  • MatLab命令行常用命令记录
  • 华为昇腾310 ATC模型转换、CPP推理案例使用
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 【译】理解JavaScript:new 关键字
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • EOS是什么
  • Java 23种设计模式 之单例模式 7种实现方式
  • Java精华积累:初学者都应该搞懂的问题
  • JS变量作用域
  • Spring-boot 启动时碰到的错误
  • 创建一种深思熟虑的文化
  • 基于游标的分页接口实现
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 跨域
  • 一些关于Rust在2019年的思考
  • 正则与JS中的正则
  • # Redis 入门到精通(八)-- 服务器配置-redis.conf配置与高级数据类型
  • #ubuntu# #git# repository git config --global --add safe.directory
  • #知识分享#笔记#学习方法
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (SpringBoot)第二章:Spring创建和使用
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (办公)springboot配置aop处理请求.
  • (十六)、把镜像推送到私有化 Docker 仓库
  • (十七)Flink 容错机制
  • (一)Linux+Windows下安装ffmpeg
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • *2 echo、printf、mkdir命令的应用
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET 表达式计算:Expression Evaluator
  • .NET 读取 JSON格式的数据
  • .vollhavhelp-V-XXXXXXXX勒索病毒的最新威胁:如何恢复您的数据?
  • /usr/bin/perl:bad interpreter:No such file or directory 的解决办法
  • @ComponentScan比较
  • [ CTF ] WriteUp-2022年春秋杯网络安全联赛-冬季赛
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [145] 二叉树的后序遍历 js