0x00 上下文
最近在开发时,我们开发环境的k8s环境经常不稳定。初步分析发现是pod在9台机器上调度不均匀导致的。
项目k8s的简单概要如下:
- Java8 SpringBoot容器,Skywalking sidecar进行调用链追踪。
- 开发环境除去前端共51个pod(曾经缩减过一次,QA环境每个服务只有一个pod)
- 在不设置limit的情况下,每个后端pod需要占用300m至600m的内存。
- 使用APIG + NodePort直接访问服务,没有使用Ingress或LoadBalancer(其实我们使用另外的方式达到了类似于LoadBalancer的效果,没有使用LB可能是历史遗留原因)
- 在Node上使用了标签来区分不同node的职责。usage=frontend的用于部署前端、usage=bff用于部署bff、usage=backend用于部署service。
- 开发环境一共有9个节点,不同的节点的配置不同:从2C8G到4C16G不等。
- 大部分Container没有使用Limit,也没有指定LimitRange。
0x01 开发环境资源告急
表现
因为后端微服务日渐增多,在集群总体内存使用率只有60%左右的情况下,经常发生dev或者qa环境崩溃,导致网站不能访问,阻碍开发和测试进度。
排查过程
查询9个节点的资源占用情况,发现有节点存在内存压力(MemeryPressure)
持续关注节点监控,在存在内存压力的节点上发现偶尔会CPU占用飙升的问题。这个可能和k8s的GC与JVM的频繁GC有关系,没有深究。
原因分析
在k8s的机制下,为了保证node的稳定持续运行,存在内存压力的节点可能会驱逐(Evicted)Pod。
在正确的实践下,驱逐pod并不会导致服务不可用。在我们的场景下导致服务不可用是因为以下几个原因: