K8S Pod持续Pending(Message: 0/5 nodes are available/Insufficient cpu)

问题

K8S节点CPU资源不足导致容器部署失败,Pod持续Pending。具体报错如下:

Message: 0/5 nodes are available: 2 node(s) had untolerated taint {node-role.kubernetes.io/master: }, 3 Insufficient cpu. preemption: 0/5 nodes are available: 2 Preemption is not helpful for scheduling, 3 No preemption victims found for incoming pod. 

K8S Pod持续Pending(Message: 0/5 nodes are available/Insufficient cpu)_第1张图片

背景描述

K8S集群已投入测试使用,除了kubes-ystem命名空间内的系统容器之外,已正常运行着70余个Pod。今日开发突然告知:新部署的Pod持续Pending,多次重新部署也无法解决。

  • 集群信息
    – 5节点集群:2主3从 ,主节点8C16G,从节点8C24G ,使用docker,运行在KylinOSV10-SP2上。
  • 资源使用情况:
    –CPU使用率7%,内存使用率49%
    K8S Pod持续Pending(Message: 0/5 nodes are available/Insufficient cpu)_第2张图片
  • 推断:实际资源仍有盈余,但可能存在类似于VMware虚拟机资源分配的机制,在不允许超分的情况下,CPU资源被已有容器已经分配完。导致新创建的容器没有足够的CPU资源使用。

参考文章

【OpenStack论坛的解决:Pod in pending state due to Insufficient CPU [closed]】
【利用limitrange限制容器资源,增加可部署的Pod数量:kubernetes中LimitRange的理解】

问题排查及原因

问题表现

  1. Pod持续pending,不管重新部署deployment,还是重建Pod,也都持续pending。
  2. K8S日志显示节点不可用: 2 node(s) had untolerated taint {node-role.kubernetes.io/master: }, 3 Insufficient cpu. (此处报错符合集群情况,2个主节点带有taint因此不可用,3个从节点被划分了太多cpu因此不可用)。
  3. 删除已有的某个Pod后,新部署的pod从pending状态变为正常running状态。说明node上运行的pod已经到达某个阈值,只有释放部分资源才能保证新的pod正常运行。印证了上文中的推断。
  4. 检查Pod内容器对资源的使用情况:分别检查“仅包含1个容器的Pod”和“使用了sidecar容器的Pod”,查看容器的资源使用情况。
    K8S Pod持续Pending(Message: 0/5 nodes are available/Insufficient cpu)_第3张图片
    K8S Pod持续Pending(Message: 0/5 nodes are available/Insufficient cpu)_第4张图片
  5. 查看K8S集群是否存在资源限制配置:是否存在limitrange
[sysma@prod-k8s-0001 ~]$ kubectl get limits
No resources found in default namespace.

[sysma@prod-k8s-0001 ~]$ kubectl get limits -A
No resources found

[sysma@prod-k8s-0001 ~]$ kubectl get limitrange -o=yaml
apiVersion: v1
items: []
kind: List
metadata:
  resourceVersion: ""

[sysma@prod-k8s-0001 ~]$ 

在K8Smaster节点上运行上述命令,此处结果显示当前K8S集群没有对资源使用做出任何限制。因此容器的资源限制均以对应的deploy控制器中的配置为主。

解决

根本解决:要么减少已有Pod使用的计算资源(CPU和memory),要么新增K8S节点和计算资源。此处选择前者,双管齐下解决问题。

创建全局limitrange配置文件,限制容器使用的计算资源。

全局limitrange可以限制未来新创建的容器,或重新创建的容器,但不能限制正在运行的容器(如果不是生产业务,重启一下Pod就能被限制)。
参考【利用limitrange限制容器资源,增加可部署的Pod数量:kubernetes中LimitRange的理解】先理解limitrange然后再创建。
基本操作顺序:

  1. 检查是否存在全局limitrange配置文件,有则修改,无则创建。
  2. 根据实际情况编写全局limitrange配置文件limit.yml。
  3. 在K8S-master节点上应用配置文件:kubectl apply -f limit.yml
  4. 新建Pod验证资源使用情况。
  5. 重启已有Pod验证资源使用情况。

此处我是用的limitrange配置文件为:

apiVersion: v1
kind: LimitRange
metadata:
  name: limits-all
spec:
  limits:
  - max:
      cpu: "600m"
      memory: 400Mi
    min:
      cpu: 200m
      memory: 200Mi
    maxLimitRequestRatio:
      cpu: 3
      memory: 2
    type: Pod
  - default:
      cpu: 200m
      memory: 100Mi
    defaultRequest:
      cpu: 200m
      memory: 100Mi
    max:
      cpu: "200m"
      memory: 200Mi
    min:
      cpu: 100m
      memory: 100Mi
    maxLimitRequestRatio:
      cpu: 2
      memory: 2
    type: Container

修改自定义对象sidecar配置,限制sidecar容器使用的计算资源

全局limitrange配置文件不会对自定义对象sidecar容器生效,需单独修改sidecar容器的配置。
K8S Pod持续Pending(Message: 0/5 nodes are available/Insufficient cpu)_第5张图片
K8S Pod持续Pending(Message: 0/5 nodes are available/Insufficient cpu)_第6张图片

注意:上述修改的配置需要重启Pod后才能生效。重启docker服务、重启kubelet服务并不会让sidercar容器配置生效。

解决的验证

完成上述操作后验证了以下结果:

  1. 仅新增了limitrange配置后,新部署的Pod可以成功running。但部署更多Pod时,仍然出现了相同问题(原因是sidecar容器划分了过多资源)。
  2. 在limitrange基础上修改了sidecar容器配置后,新部署的Pod不再pending,可成功running。此时重启前后的Pod,其中用到的sidecar容器的计算资源从500m 500Mi变成了200m 100Mi。

其它相关截图

K8S Pod持续Pending(Message: 0/5 nodes are available/Insufficient cpu)_第7张图片
在这里插入图片描述

你可能感兴趣的:(运维,kubernetes,容器,云原生)