news 2026/5/26 17:28:30

k8s之POD资源限制和健康监测

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
k8s之POD资源限制和健康监测

写在前面

本文一起看下POD的资源限制配置和健康监测的相关内容。

1:资源限制

如果是不对POD设置资源限制的话,若任由其占用系统资源,可能会造成非常严重的后果,所以我们需要根据具体情况来设置资源限制,如使用多少内存,多少CPU,多少IOPS等,实现这些限制使用的是cgroup技术,而配置这些限制使用到属性是resources。在看具体的例子之前需要先来看下cpu资源的表示方法,cpu标识的最小单位是0.001m,这里的m是milli的意思,1000m就代表使用一个cpu,500m就代表0.5cpu,具体配置cpu限制的话使用XmX这种,后者是直接指定使用CPU的个数。如下yaml:

apiVersion: v1 kind: Pod metadata: name: ngx-pod-resources spec: containers: - image: nginx:alpine name: ngx resources: requests: cpu: 10m memory: 100Mi limits: cpu: 20m memory: 200Mi

通过requests配置初始时需要0.01cpu,100MB内存,通过limits配置最多只能申请0.02cpu,200MB内存,如果超过最大限制则会被强制停止。配置了资源限制后,k8s会根据每个Node的剩余资源情况来将POD分配到合适的Node上,尽量的将Node的资源榨取干净。这个过程有些类似于俄罗斯方块,每个方块是分配到某Node上的POD,如下图:

如果我们申请的资源集群中所有的Node都无法满足会发生什么呢?比如定义如下申请10个CPU的yaml:

dongyunqi@mongodaddy:~/k8s$ cat appy-10-cpu.yml apiVersion: v1 kind: Pod metadata: name: ngx-pod-resources spec: tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule operator: Exists containers: - image: nginx:alpine name: ngx resources: requests: cpu: 10 memory: 100Mi limits: cpu: 20 memory: 200Mi

apply后查看:

dongyunqi@mongodaddy:~/k8s$ kubectl get pod | egrep 'NAME|ngx-pod-resources' NAME READY STATUS RESTARTS AGE ngx-pod-resources 0/1 Pending 0 52s

可以看到其处于PENDING状态,describe查看:

dongyunqi@mongodaddy:~/k8s$ kubectl describe pod ngx-pod-resources ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 22s default-scheduler 0/2 nodes are available: 2 Insufficient cpu.

0/2 nodes are available: 2 Insufficient cpu.的意思是2个node中有0个可用,2个都是因为没有足够的CPU资源导致不可用。

2:健康监测

对于k8s来说,应用就像是一个黑盒子,只能知道其启动了,运行中,停止了,但是到底是不是能够正常的对外提供服务,k8s是不知道的,因此应用就不能是一个黑盒子,要是一个灰盒子,必须能够让k8s获取应用的一些信息,为此应用需要预留一些口子给k8s使用,这个过程有点类似于核酸检测,护士姐姐使用棉签从我们的口腔中蘸取唾液。这个k8s从预留的口子中获取信息的过程,我们叫做是探针 probe,或者叫做探测器,但我觉得叫做探针则更加形象准确。当前k8s定义了3中探针,如下:

startup:加载各种配置文件后启动成功,如spring加载器配置文件后启动 liveness:startup之后进入的状态,但此时可能因为一些初始化工作还没有完成,还不能对外服务,如加载MySQL中的数据到缓存中 ready:liveness之后的状态,进入该状态,则应用就可以正常的对外提供服务了

可以看到k8s对于探针的定义还是比较细的,参考下图:

三种探针在失败时k8s的处理方式也不尽相同,如下:

startup失败:重启容器,不会启动后续的探针检测 liveness失败:重启容器,不会进行后的探针检测 ready失败:认为POD无法对外提供服务,会将其排除在集群之外

如下图:

那么该如何使用探针呢?3中探针的定义都是一样的,主要的属性如下:

periodSeconds,执行探测动作的时间间隔,默认是 10 秒探测一次。 timeoutSeconds,探测动作的超时时间,如果超时就认为探测失败,默认是 1 秒。 successThreshold,连续几次探测成功才认为是正常,对于 startupProbe 和 livenessProbe 来说它只能是 1。 failureThreshold,连续探测失败几次才认为是真正发生了异常,默认是 3 次。

具体探测的方式有shell,tcp socket,http GET 三种,如下:

exec,执行一个 Linux 命令,比如 ps、cat 等等,和 container 的 command 字段很类似。 tcpSocket,使用 TCP 协议尝试连接容器的指定端口。 httpGet,连接端口并发送 HTTP GET 请求。

下面我们以Nginx为例来看具体看下,为了便于试验,先来定义ConfigMap如下:

dongyunqi@mongodaddy:~/k8s$ cat probe-cm.yml apiVersion: v1 kind: ConfigMap metadata: name: ngx-conf data: default.conf: | server { listen 80; location = /ready { return 200 'I am ready'; } }

然后我们定义如下pod分别使用三种探针来进行探针检测,yaml如下:

dongyunqi@mongodaddy:~/k8s$ cat probe-pod.yml apiVersion: v1 kind: Pod metadata: name: ngx-pod-probe spec: volumes: - name: ngx-conf-vol configMap: name: ngx-conf containers: - image: nginx:alpine name: ngx ports: - containerPort: 80 volumeMounts: - mountPath: /etc/nginx/conf.d name: ngx-conf-vol startupProbe: periodSeconds: 1 exec: command: ["cat", "/var/run/nginx.pid"] livenessProbe: periodSeconds: 10 tcpSocket: port: 80 readinessProbe: periodSeconds: 5 httpGet: path: /ready port: 80

startup probe使用了shell探针检测方式,liveness probe使用了tcp socket探针检测方式,ready probe 使用httpGet检测方式,apply后查看如下:

dongyunqi@mongodaddy:~/k8s$ kubectl get pod NAME READY STATUS RESTARTS AGE ngx-pod-probe 1/1 Running 0 18s

kubectl logs查看日志可以看到定期的调用/ready接口,如下:

dongyunqi@mongodaddy:~/k8s$ kubectl logs ngx-pod-probe /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 10-listen-on-ipv6-by-default.sh: info: can not modify /etc/nginx/conf.d/default.conf (read-only file system?) /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh /docker-entrypoint.sh: Configuration complete; ready for start up 2023/01/29 07:54:33 [notice] 1#1: using the "epoll" event method 2023/01/29 07:54:33 [notice] 1#1: nginx/1.21.5 2023/01/29 07:54:33 [notice] 1#1: built by gcc 10.3.1 20211027 (Alpine 10.3.1_git20211027) 2023/01/29 07:54:33 [notice] 1#1: OS: Linux 5.15.0-58-generic 2023/01/29 07:54:33 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576 2023/01/29 07:54:33 [notice] 1#1: start worker processes 2023/01/29 07:54:33 [notice] 1#1: start worker process 23 10.10.4.1 - - [29/Jan/2023:07:54:36 +0000] "GET /ready HTTP/1.1" 200 10 "-" "kube-probe/1.23" "-" 10.10.4.1 - - [29/Jan/2023:07:54:37 +0000] "GET /ready HTTP/1.1" 200 10 "-" "kube-probe/1.23" "-" ...

接下来我们修改startupProbe,让其获取一个不可能存在的文件,即让startup probe失败,看下POD会是什么状态,修改后如下:

apiVersion: v1 kind: Pod metadata: name: ngx-pod-probe spec: volumes: - name: ngx-conf-vol configMap: name: ngx-conf containers: - image: nginx:alpine name: ngx ports: - containerPort: 80 volumeMounts: - mountPath: /etc/nginx/conf.d name: ngx-conf-vol startupProbe: periodSeconds: 1 exec: command: ["cat", "/xxxx/run/nginx.pid"] livenessProbe: periodSeconds: 10 tcpSocket: port: 80 readinessProbe: periodSeconds: 5 httpGet: path: /ready port: 80

apply后查看如下:

dongyunqi@mongodaddy:~/k8s$ kubectl get pod NAME READY STATUS RESTARTS AGE ngx-pod-probe 0/1 Running 2 (3s ago) 13s dongyunqi@mongodaddy:~/k8s$ kubectl get pod NAME READY STATUS RESTARTS AGE ngx-pod-probe 0/1 CrashLoopBackOff 2 (8s ago) 22s dongyunqi@mongodaddy:~/k8s$ kubectl get pod NAME READY STATUS RESTARTS AGE ngx-pod-probe 0/1 CrashLoopBackOff 2 (12s ago) 26s

可以看到POD在不断的重启,最后变为CrashLoopBackOff状态,我们可以通过kuectl describe来查看具体原因,如下:

dongyunqi@mongodaddy:~/k8s$ kubectl describe pod ngx-pod-probe Name: ngx-pod-probe Namespace: default ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 4m33s default-scheduler Successfully assigned default/ngx-pod-probe to mongomongo Normal Pulled 4m23s (x3 over 4m32s) kubelet Container image "nginx:alpine" already present on machine Normal Created 4m23s (x3 over 4m32s) kubelet Created container ngx Normal Started 4m23s (x3 over 4m32s) kubelet Started container ngx Warning Unhealthy 4m19s (x9 over 4m30s) kubelet Startup probe failed: cat: can't open '/xxxx/run/nginx.pid': No such file or directory Normal Killing 4m19s (x3 over 4m27s) kubelet Container ngx failed startup probe, will be restarted Warning BackOff 4m13s (x4 over 4m19s) kubelet Back-off restarting failed container

Startup probe failed: cat: can't open '/xxxx/run/nginx.pid': No such file or directory可以看出来确实是因为startup probe检测失败导致的。

写在后面

小结

本文一起看了对POD的资源限制配置,以及startup,liveness,ready三种探针及其配置,并给出了一个具体的实例。希望本文能够帮助到你。

参考文章列表

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/26 17:28:29

SFC高可用与绿色节能双目标优化:动态冗余与预测检查点实践

1. 项目概述:在可靠与绿色之间寻找平衡的艺术在电信云和边缘计算的世界里,服务功能链(SFC)已经从一个前沿概念,变成了我们构建灵活、敏捷网络服务的基石。简单来说,它就像用软件乐高(虚拟网络功…

作者头像 李华
网站建设 2026/5/26 17:27:10

7.11 云上搭建Python开发环境

本次实战在华为云服务器上搭建Python开发环境。首先安装开发工具套件及依赖库,编译安装Python 3.7.7并配置环境变量。随后编写猜数小游戏,实现随机数生成与智能提示功能。最后安装Flask框架,编写代码创建Web应用,并在华为云安全组…

作者头像 李华
网站建设 2026/5/26 17:23:01

如何快速搭建ESP WiFi中继器:完整配置指南与网络扩展技巧

如何快速搭建ESP WiFi中继器:完整配置指南与网络扩展技巧 【免费下载链接】esp_wifi_repeater A full functional WiFi NAT Router (and now also a WiFi Repeater) 项目地址: https://gitcode.com/gh_mirrors/es/esp_wifi_repeater 想要扩展WiFi信号覆盖范围…

作者头像 李华
网站建设 2026/5/26 17:19:58

C++ cmath库宏常量全解析:从M_PI到M_SQRT2的实战应用指南

1. 揭开cmath库宏常量的神秘面纱 第一次用C做科学计算时,我傻乎乎地自己定义了圆周率π的值。直到某天review同事代码,发现他用了M_PI这个神奇的东西,才意识到原来cmath库里早就藏着这些宝贝。这些预定义的数学宏常量就像工具箱里的瑞士军刀&…

作者头像 李华
网站建设 2026/5/26 17:18:59

SheafAlign:基于层理论的去中心化多模态对齐新范式

1. 项目概述与核心挑战在当今这个数据爆炸的时代,我们获取信息的渠道前所未有的丰富。一个智能驾驶系统可能同时“看”着摄像头画面、“听”着雷达回波、“感受”着毫米波信号;一个环境监测网络则可能整合了图像、声音、温度和无线信号。这种由多种不同类…

作者头像 李华