Prometheus配置IPv6链路本地地址报错connect: invalid argument求助
我之前也碰到过一模一样的情况——Link-local IPv6(就是fe80::开头的地址)必须绑定网络接口才能通信,但直接在Prometheus配置里加接口标识会被URL编码导致失败,给你一步步说怎么搞定:
问题根源
Link-local IPv6地址是和物理/虚拟网络接口绑定的,系统必须知道从哪个网卡发送请求才能找到目标机器。你用curl加%ens17能通是因为curl直接识别了这个接口标识,但Prometheus的HTTP客户端会把URL里的%自动编码成%25,所以配置里的[fe80::3086:7bff:fed8:f402%ens17]:9100会被转成[fe80::3086:7bff:fed8:f402%25ens17]:9100,这就导致连接失败了。
解决方案:用Relabel规则添加接口标识
最可靠的办法是通过Prometheus的relabel_configs来动态给目标地址加上接口标识,避免URL编码的问题。修改你的scrape配置如下:
scrape_configs: - job_name: 'node-exporter-ipv6-linklocal' static_configs: # 先写不带接口标识的基础地址 - targets: ['[fe80::3086:7bff:fed8:f402]:9100'] relabel_configs: # 提取IPv6地址部分和端口,拼接上接口标识 - source_labels: [__address__] regex: '(\[.*\]):(.*)' replacement: '${1}%ens17:${2}' target_label: __address__
配置说明
source_labels: [__address__]:读取当前的目标地址regex: '(\[.*\]):(.*)':把地址拆成两部分——括号里的IPv6地址,和后面的端口replacement: '${1}%ens17:${2}':把第一部分(IPv6地址)加上%ens17接口标识,再拼回端口target_label: __address__:用修改后的地址替换原来的目标地址
验证配置
重启Prometheus后,进入Prometheus的Targets页面(默认是http://<prometheus-ip>:9090/targets),查看这个job的目标地址,应该显示为[fe80::3086:7bff:fed8:f402%ens17]:9100,如果状态变成UP就说明成功了。
额外建议
Link-local地址的接口绑定特性会带来维护成本——如果Prometheus服务器的网卡名称变更(比如从ens17改成ens18),配置就得跟着改。如果条件允许,建议给内部监控的机器分配Unique Local IPv6地址(fc00::/7开头的),这类地址不需要绑定接口,配置起来更稳定。
内容的提问来源于stack exchange,提问作者FabianTe

