Please enable Javascript to view the contents

Kubernetes 应用 troubleshooting

 ·  ☕ 2 分钟

设置合理的 Req 和 Limit

  1. 不设置 Req 和 Limit,当应用的 CPU、MEM 暴涨时,会危害同一节点上的其他 Pod,甚至导致集群节点一个接一个被压垮。

  2. Req 和 Limit 一共有四个值,如果只设置部分值,当节点资源使用率达到 Kubelet 预设值时,Kubelet 会驱逐 Pod,驱逐的顺序是 Guaranteed > Burstable > Best-Effort

其中:

  • Guaranteed, 全部容器设置 CPU、MEM 的请求和限制,同时相等
  • Burstable, 至少一个容器具有 CPU、MEM 的请求或限制
  • BestEffort, 容器都没有设置 CPU、MEM 的请求或限制

Req 与 Limit 不应该相差太大,通常 Limit = Req * 1.5 或者根据监控历史进行设置。资源消耗越多的 Pod,Req 和 Limit 应该越相近。

关注应用的 CPU 限流

由于 CPU 是可压缩的资源,在设置了 Limit 之后,即使高负载,应用通常也是可用的。但是会很慢。

这是由于系统对 CPU 的分配是分片的,在一个周期内,如果应用对 CPU 分片的使用达到 Limit 限制,那么应用需要等待下一个周期才能获得 CPU 使用机会。此时,应用处于 CPU 限流状态。

CPU 限流会导致,应用的响应变慢。

需要注意的是不仅仅是 Pod 的 CPU 使用达到 Limit 限制,如果节点的 CPU 负载高,同样也会存在 CPU 限流,应用能使用的资源是除去节点自身消耗的部分。

使用伸缩重启 Prometheus

不要滚动重启,滚动重启会导致,短时间内组件资源消耗加倍,影响集群稳定性。

1
2
kubectl scale deployment prom-prometheus-server --replicas=0
kubectl scale deployment prom-prometheus-server --replicas=1

同时,默认没有开启 --storage.tsdb.no-lockfile 参数下的 Prometheus 无法滚动重启,也只能使用上述方法重启。

否则报错,opening storage failed: lock DB directory: resource temporarily unavailable

一个存储卷,多个 Prometheus 可能会导致脏数据。

运行容器时,exec user process caused: no such file or directory

有两种情况:

  • 基础镜像是 alpine:latest,换其他镜像试试
  • ENTRYPOINT 脚本的编码问题,修改 Windows 下的 CRLF 为 Linux 下的 LF

应用 OOMKilled Exit Code: 137

有两种情况:

  • 容器内存使用量超过 limit 值
  • 节点内存不足

应用 getting the final child’s pid from pipe caused "EOF": unknown

内核版本为 3.x, 需要升级到 5.x 。

应用内存出现突刺

现象:

应用瞬时内存使用量暴涨,然后又恢复正常。有可能会伴随 OOMKilled。

原因:

for 循环拼接字符串导致的内存暴涨。

解决方案:

使用 strings.Builder 代替 + 拼接字符串

应用被驱逐,EmptyDir volume exceeds the limit

现象:

应用状态 Failed,被 Kubelet 驱逐,报错 Usage of EmptyDir volume “tmp” exceeds the limit “50Gi” 。

原因:

Kubelet 默认限制 Pod 临时存储能使用磁盘大小的 10%,inodes 的 5%。一旦超过限制,Kubelet 会驱逐 Pod。

解决方案:

1
2
3
4
5
resources:
  limits:
    ephemeral-storage: 100Gi
  requests:
    ephemeral-storage: 100Gi

可以通过 ephemeral-storage 指定临时存储的大小。


微信公众号
作者
微信公众号