设置合理的 Req 和 Limit
不设置 Req 和 Limit,当应用的 CPU、MEM 暴涨时,会危害同一节点上的其他 Pod,甚至导致集群节点一个接一个被压垮。
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
不要滚动重启,滚动重启会导致,短时间内组件资源消耗加倍,影响集群稳定性。
|
|
同时,默认没有开启 --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。
解决方案:
|
|
可以通过 ephemeral-storage
指定临时存储的大小。