Docker部署Prometheus v2.1.0容器持续崩溃重启排障
故障根因
该崩溃和虚拟机资源配置无关,是版本兼容性bug导致的:
- 你使用的
prom/prometheus:v2.1.0是2017年发布的极旧版本,其依赖的github.com/miekg/dns库存在未做边界校验的代码缺陷:ClientConfigFromFile方法解析/etc/resolv.conf文件时,遇到空行、无有效内容的注释行、参数值不符合旧库预期的配置行时,会直接对长度为0的字符串做切片截取操作,触发slice bounds out of range运行时panic。 - Ubuntu 20.04默认由systemd-resolved生成的
/etc/resolv.conf,普遍存在末尾带空行、默认配置options ndots:0的情况,刚好命中上述旧库的解析bug。 - 该解析逻辑仅在Prometheus执行
dns_sd_configs类型的服务发现刷新流程时才会被调用,因此你会观察到Prometheus完成TSDB启动、加载完主配置文件后才崩溃,同栈下不依赖该DNS解析逻辑的Grafana、Alertmanager、node-exporter、cAdvisor服务均能正常运行,这也是两套独立环境都能稳定复现问题的核心原因。
修复方案
按推荐优先级从高到低选择即可:
- 升级Prometheus版本(最推荐,无后遗症)
将docker compose配置中Prometheus服务的镜像tag从v2.1.0替换为v2.2.0及以上的稳定版本(比如长期维护的v2.45.x系列),重新执行docker compose up -d重建容器即可。新版本Prometheus已经合入了dns依赖库的修复补丁,且完全向下兼容你当前使用的prometheus.yml配置语法,不需要额外调整其他规则。 - 调整DNS配置规避解析bug(适合暂时不能升级版本的场景)
二选一操作即可:- 在Prometheus服务的docker compose配置段增加
dns: <你常用的DNS服务器地址,比如8.8.8.8、223.5.5.5>参数,让容器直接使用指定DNS服务,不挂载宿主机存在兼容问题的resolv.conf,修改后重建容器即可恢复 - 手动编辑宿主机
/etc/resolv.conf文件,删除文件末尾所有空行、无意义注释,将options ndots参数调整为大于0的常规值(比如通用配置options ndots:5),保存后重启Prometheus容器即可
- 在Prometheus服务的docker compose配置段增加
- 移除DNS服务发现规则(临时应急方案,不推荐长期用)
删除prometheus.yml中所有dns_sd_configs相关的服务发现配置,替换为static_configs静态写死所有抓取目标地址,重启容器后Prometheus不会触发DNS服务发现流程,自然不会走到有bug的解析逻辑,但会失去动态服务发现能力,仅适合临时应急使用。
内容的提问来源于stack exchange,提问作者okapetanios
相关产品推荐
相关产品推荐

