工作负载异常:实例调度失败-九游平台
问题定位
当pod状态为“pending”,事件中出现“实例调度失败”的信息时,可根据具体事件信息确定具体问题原因。事件查看方法请参见。
排查思路
根据具体事件信息确定具体问题原因,如表1所示。
事件信息 |
问题原因与九游平台的解决方案 |
---|---|
no nodes available to schedule pods. |
集群中没有可用的节点。 |
0/2 nodes are available: 2 insufficient cpu. 0/2 nodes are available: 2 insufficient memory. |
节点资源(cpu、内存)不足。 |
0/2 nodes are available: 1 node(s) didn't match node selector, 1 node(s) didn't match pod affinity rules, 1 node(s) didn't match pod affinity/anti-affinity. |
节点与pod亲和性配置互斥,没有满足pod要求的节点。 |
0/2 nodes are available: 2 node(s) had volume node affinity conflict. |
pod挂载云硬盘存储卷与节点不在同一个可用区。 |
0/1 nodes are available: 1 node(s) had taints that the pod didn't tolerate. |
节点存在污点tanits,而pod不能容忍这些污点,所以不可调度。 |
0/7 nodes are available: 7 insufficient ephemeral-storage. |
节点临时存储不足。 |
0/1 nodes are available: 1 everest driver not found at node |
节点上everest-csi-driver不在running状态。 |
failed to create pod sandbox: ... create more free space in thin pool or use dm.min_free_space option to change behavior |
节点thinpool空间不足。 |
0/1 nodes are available: 1 too many pods. |
该节点调度的pod超出上限。 |
排查项一:集群内是否无可用节点
登录cce控制台,检查节点状态是否为可用。或使用如下命令查看节点状态是否为ready。
$ kubectl get node name status roles age version 192.168.0.37 ready21d v1.19.10-r1.0.0-source-121-gb9675686c54267 192.168.0.71 ready 21d v1.19.10-r1.0.0-source-121-gb9675686c54267
如果状态都为不可用(not ready),则说明集群中无可用节点。
九游平台的解决方案:
- 新增节点,若工作负载未设置亲和策略,pod将自动迁移至新增的可用节点,确保业务正常。
- 排查不可用节点问题并修复,排查修复方法请参见。
- 重置不可用的节点,详情请参见。
排查项二:节点资源(cpu、内存等)是否充足
0/2 nodes are available: 2 insufficient cpu. cpu不足。
0/2 nodes are available: 2 insufficient memory. 内存不足。
当“实例资源的申请量”超过了“实例所在节点的可分配资源总量”时,节点无法满足实例所需资源要求导致调度失败。
如果节点可分配资源小于pod的申请量,则节点无法满足实例所需资源要求导致调度失败。
九游平台的解决方案:
资源不足的情况主要解决办法是扩容,建议在集群中增加节点数量。
排查项三:检查工作负载的亲和性配置
当亲和性配置出现如下互斥情况时,也会导致实例调度失败:
例如:
workload1、workload2设置了工作负载间的反亲和,如workload1部署在node1,workload2部署在node2。
workload3部署上线时,既希望与workload2亲和,又希望可以部署在不同节点如node1上,这就造成了工作负载亲和与节点亲和间的互斥,导致最终工作负载部署失败。
0/2 nodes are available: 1 node(s) didn't match node selector, 1 node(s) didn't match pod affinity rules, 1 node(s) didn't match pod affinity/anti-affinity.
- node selector 表示节点亲和不满足。
- pod affinity rules 表示pod亲和不满足。
- pod affinity/anti-affinity 表示pod亲和/反亲和不满足。
九游平台的解决方案:
- 在设置“工作负载间的亲和性”和“工作负载和节点的亲和性”时,需确保不要出现互斥情况,否则工作负载会部署失败。
- 若工作负载配置了节点亲和性,需确保亲和的节点标签中supportcontainer设置为true,否则会导致pod无法调动到节点上,查看事件提示如下错误信息:
no nodes are available that match all of the following predicates: matchnode selector, nodenotsupportscontainer
节点标签为false时将会调度失败。
排查项四:挂载的存储卷与节点是否处于同一可用区
0/2 nodes are available: 2 node(s) had volume node affinity conflict. 存储卷与节点之间存在亲和性冲突,导致无法调度。
这是因为云硬盘不能跨可用区挂载到节点。例如云硬盘存储卷在可用区1,节点在可用区2,则会导致无法调度。
cce中创建云硬盘存储卷,默认带有亲和性设置,如下所示:
kind: persistentvolume apiversion: v1 metadata: name: pvc-c29bfac7-efa3-40e6-b8d6-229d8a5372ac spec: ... nodeaffinity: required: nodeselectorterms: - matchexpressions: - key: failure-domain.beta.kubernetes.io/zone operator: in values: - cn-east-3a
九游平台的解决方案:
重新创建存储卷,可用区选择与节点同一分区,或重新创建工作负载,存储卷选择自动分配。
排查项五:检查pod污点容忍情况
0/1 nodes are available: 1 node(s) had taints that the pod didn't tolerate. 是因为节点打上了污点,不允许pod调度到节点上。
查看节点的上污点的情况。如下则说明节点上存在污点。
$ kubectl describe node 192.168.0.37
name: 192.168.0.37
...
taints: key1=value1:noschedule
...
在某些情况下,系统会自动给节点添加一个污点。当前内置的污点包括:
- node.kubernetes.io/not-ready:节点未准备好。
- node.kubernetes.io/unreachable:节点控制器访问不到节点。
- node.kubernetes.io/memory-pressure:节点存在内存压力。
- node.kubernetes.io/disk-pressure:节点存在磁盘压力,此情况下您可通过的方案进行解决。
- node.kubernetes.io/pid-pressure:节点的 pid 压力,此情况下您可通过进行解决。
- node.kubernetes.io/network-unavailable:节点网络不可用。
- node.kubernetes.io/unschedulable:节点不可调度。
- node.cloudprovider.kubernetes.io/uninitialized:如果kubelet启动时指定了一个“外部”云平台驱动, 它将给当前节点添加一个污点将其标志为不可用。在cloud-controller-manager初始化这个节点后,kubelet将删除这个污点。
九游平台的解决方案:
要想把pod调度到这个节点上,有两种方法:
- 若该污点为用户自行添加,可考虑删除节点上的污点。若该污点为系统自动添加,解决相应问题后污点会自动删除。
- pod的定义中容忍这个污点,如下所示。详细内容请参见。
apiversion: v1 kind: pod metadata: name: nginx spec: containers: - name: nginx image: nginx:alpine tolerations: - key: "key1" operator: "equal" value: "value1" effect: "noschedule"
排查项六:检查临时卷使用量
0/7 nodes are available: 7 insufficient ephemeral-storage. 节点临时存储不足。
检查pod是否限制了临时卷的大小,如下所示,当应用程序需要使用的量超过节点已有容量时会导致无法调度,修改临时卷限制或扩容节点磁盘可解决此问题。
apiversion: v1 kind: pod metadata: name: frontend spec: containers: - name: app image: images.my-company.example/app:v4 resources: requests: ephemeral-storage: "2gi" limits: ephemeral-storage: "4gi" volumemounts: - name: ephemeral mountpath: "/tmp" volumes: - name: ephemeral emptydir: {}
您可以通过kubectl describe node命令查询节点临时卷的容量(capacity)和可使用量(allocatable),并可查询节点已分配的临时卷申请值和限制值。
返回示例如下:
... capacity: cpu: 4 ephemeral-storage: 61607776ki hugepages-1gi: 0 hugepages-2mi: 0 localssd: 0 localvolume: 0 memory: 7614352ki pods: 40 allocatable: cpu: 3920m ephemeral-storage: 56777726268 hugepages-1gi: 0 hugepages-2mi: 0 localssd: 0 localvolume: 0 memory: 6180752ki pods: 40 ... allocated resources: (total limits may be over 100 percent, i.e., overcommitted.) resource requests limits -------- -------- ------ cpu 1605m (40%) 6530m (166%) memory 2625mi (43%) 5612mi (92%) ephemeral-storage 0 (0%) 0 (0%) hugepages-1gi 0 (0%) 0 (0%) hugepages-2mi 0 (0%) 0 (0%) localssd 0 0 localvolume 0 0 events:
排查项七:检查everest插件是否工作正常
0/1 nodes are available: 1 everest driver not found at node。集群everest插件的everest-csi-driver 在节点上未正常启动。
检查kube-system命名空间下名为everest-csi-driver的守护进程,查看对应pod是否正常启动,若未正常启动,删除该pod,守护进程会重新拉起该pod。
排查项八:检查节点thinpool空间是否充足
节点在创建时会绑定一个供kubelet及容器引擎使用的专用数据盘,详情请参见。若数据盘空间不足,将导致实例无法正常创建。
方案一:清理镜像
- 使用containerd容器引擎的节点:
- 查看节点上的本地镜像。
crictl images -v
- 确认镜像无需使用,并通过镜像id删除无需使用的镜像。
crictl rmi {镜像id}
- 查看节点上的本地镜像。
- 使用docker容器引擎的节点:
- 查看节点上的本地镜像。
docker images
- 确认镜像无需使用,并通过镜像id删除无需使用的镜像。
docker rmi {镜像id}
- 查看节点上的本地镜像。
请勿删除cce-pause等系统镜像,否则可能导致无法正常创建容器。
方案二:扩容磁盘
扩容磁盘的操作步骤如下:
- 在evs控制台扩容数据盘。详情请参见。
在evs控制台扩容成功后,仅扩大了云硬盘的存储容量,还需要执行后续步骤扩容逻辑卷和文件系统。
- 登录cce控制台,进入集群,在左侧选择“节点管理”,单击节点后的“同步云服务器”。
- 登录目标节点。
- 使用lsblk命令查看节点块设备信息。
这里存在两种情况,根据容器存储rootfs而不同。
检查项九:检查节点上调度的pod是否过多
0/1 nodes are available: 1 too many pods.表示节点上调度的pod过多,超出可调度的最大实例数。
创建节点时,在“高级配置”中可选择设置“最大实例数”参数,设置节点上可以正常运行的容器 pod 的数目上限。该数值的默认值随节点规格浮动,您也可以手动设置。
您可以在“节点管理”页面,查看节点的“容器组(已分配/总额度)”参数列,检查节点已调度的容器是否达到上限。若已达到上限,可通过添加节点或修改最大实例数的方式解决。
您可通过以下方式修改“最大实例数”参数:
- 默认节点池中的节点:通过重置节点时修改“最大实例数”。
- 自定义节点池中的节点:可修改节点池配置参数中的max-pods参数。详情请参见。
相关文档
意见反馈
文档内容是否对您有帮助?
如您有其它疑问,您也可以通过华为云社区问答频道来与我们联系探讨