背景
我们的额监控方案为:Kubernetes(K8S)+cAdvisor+Prometheus+Grafana。
然后,用cAdivor监控容器信息,其实,cAdivor其实到现在的主流K8S版本中,Kubelet进程已经将其内置了,但是我们没有这么用,因为没有必要因为让Prometheus定期去Kubelet上采集容器信息,平白增添对Kubelet的压力。相反,我觉得,还是应该还是应该单独部署cAdvisor,这样一来,不论是定制化cAdvisor,还是版本更新,都会更方面。所以,我使用DaemonSet部署了cAdvisor。
问题
用DaemonSet的方式部署cAdvisor,本质上,就是每个K8S的宿主机都启动了一个pod,实际观测,发现这些Pod的状态,会随着时间的推移,开始频繁出现Crash。这个问题,势必会导致cAdvisor无法正常监控容器信息。下面是具体的排查过程。
排查初探
首先,Pod Crash 必然有其原因,所以,一开始是通过下面的方式,看cAdvisor到底为何会Crash,通过
kubectl describe pod -n monitoring pod-xxxxx
找到Last State部分,发现其为:
State: OOMKilled
这说明,这个 Pod,是因为内存不够,cAdvisor在运行过程,超出了Pod的资源限制,被OOM杀掉了。既然资源不够,那么首先,就是调大其内存限制。
一开始为这个Pod设置的上限资源为1核CPU+1G内存,既然内存无法满足,那么调大为2G,继续观测,发现依然会OOM。然后又调整为3G、4G、10G、20G(机器内存大,土豪),发现虽然内存变大了会有一些缓解,但实际上,即使内存上限设置为20G,还是会有Crash的情况,那么,这时候就需要反思一下几个问题了:
- 是否是cAdvisor存在bug?
- 哪个机器上的cAdvisor Pod总是重启?
排查是否是cAdvisor版本问题
针对第一点,我们升级了cAdivor镜像为最新版,问题依旧。
排查是否是cAdvisor参数配置问题
google一些文章,有人提过类似的问题,官方issue的解释中,有人提到可能配置不对,可能采集的指标过多等,于是,我review了一下我的配置,调整后的完整配置如下:
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
labels:
name: cadvisor
name: cadvisor
namespace: monitoring
spec:
revisionHistoryLimit: 10
selector:
matchLabels:
name: cadvisor
template:
metadata:
annotations:
prometheus.io/port: "28762"
prometheus.io/scrape: "true"
creationTimestamp: null
labels:
name: cadvisor
spec:
automountServiceAccountToken: false
containers:
- args:
- -allow_dynamic_housekeeping=true
- -global_housekeeping_interval=1m0s
- -housekeeping_interval=3s
- -disable_metrics=udp,tcp,percpu,sched
- -storage_duration=15s
- -profiling=true