Kubernetes 1.7.8集群kube-apiserver CPU占用过高及请求异常求助
你的集群核心问题很明确:kube-apiserver被大量WATCH请求压垮了,结合Prometheus给出的请求分布数据,我来一步步帮你定位和解决这个问题:
一、先定位WATCH请求的来源
要解决问题,首先得搞清楚是谁在发起这么多WATCH请求,这是关键。你可以通过两种方式排查:
查看kube-apiserver日志:登录任意master节点,执行命令过滤WATCH相关日志(Kops部署的日志路径通常是
/var/log/kube-apiserver.log):grep "WATCH" /var/log/kube-apiserver.log | head -100日志里的
User-Agent字段会告诉你发起请求的客户端——大概率是heapster、prometheus、ELK这类监控/日志组件,也可能是自定义的业务客户端。利用apiserver的metrics接口统计:通过curl获取请求分类数据,快速定位高频WATCH的资源类型和客户端:
curl -k https://localhost:6443/metrics | grep "apiserver_request_total.*WATCH"
二、针对性优化方案
根据常见的WATCH过载场景,给你几个具体的优化方向:
1. 优化监控组件的请求逻辑
你的集群部署了heapster和prometheus,这两个是WATCH请求的高发区:
- Heapster:K8s 1.7版本的heapster默认会WATCH大量非核心资源,你可以调整
--source参数,只保留pod、node这类核心监控对象,避免WATCH events、services等不必要的资源。 - Prometheus:检查
prometheus.yml里的kubernetes服务发现配置和relabel规则,避免重复监控目标;同时确保使用的kube-state-metrics是适配K8s 1.7的版本,减少无效的WATCH重试请求。
2. 收紧ELK的日志采集范围
虽然你说ELK只采集部分Pod日志,但采集组件(filebeat/fluentd)通常会通过WATCH Pod资源来发现新实例,容易出现范围过大的问题:
- 给采集组件配置精准的label selector,只匹配需要采集日志的Pod,避免WATCH整个集群的Pod资源。
- 如果用的是fluentd,调整
kubernetes_metadata插件的配置,关闭不必要的元数据同步,减少WATCH请求量。
3. 调整apiserver的WATCH相关参数
针对K8s 1.7的特性,调整以下参数缓解压力:
- 适当提高
--max-requests-inflight(默认400)和--max-mutating-requests-inflight(默认200)的值,建议先试600/300,注意不要过高导致apiserver崩溃。 - 启用
--enable-garbage-collection,自动清理过期的WATCH连接,避免资源泄漏。 - 调整
--watch-cache-sizes,给pods这类高频WATCH的资源分配更大的缓存,减少apiserver从etcd拉取数据的次数。
4. 集群版本升级(长期根治方案)
Kubernetes 1.7是2017年的老旧版本,后续版本(比如1.10+)对WATCH机制做了大量优化——包括连接复用、超时管理、缓存策略升级等。如果业务允许,建议逐步升级到较新的稳定版本,从根本上解决这类资源占用问题。
三、临时缓解措施
如果当前apiserver已经濒临过载,可以先做这些临时操作救急:
- 重启过载的kube-apiserver进程,清理无效的WATCH连接:
sudo systemctl restart kube-apiserver - 暂时停止非核心的监控组件(比如heapster),先降低apiserver压力,等定位到具体问题后再恢复。
内容的提问来源于stack exchange,提问作者Carlos Fau

