负载均衡后方EC2实例作为Prometheus目标的注册问题咨询
问题背景
环境配置
- 在M1机器上部署了Prometheus和Grafana
- AWS负载均衡器(LB1)监听HTTPS:443,负责SSL处理,请求转发至包含2台EC2实例(I1、I2)的目标组(TG1)
- 每台EC2实例上运行Nginx
请求生命周期
浏览器请求 https://api.example.com 的流程:
- 请求到达LB1
- LB1将请求转发至TG1中的某台EC2实例
- 实例上的Nginx转发请求至应用工作进程
遇到的问题
已在I1、I2上安装并运行node exporter,但不知道如何在prometheus.yml中正确注册这两台实例作为监控目标,尝试了两种方案但都有问题:
尝试的方案1:通过负载均衡器采集
配置方式
每台实例的node exporter运行在9100端口,通过Nginx将LB1发来的请求转发至localhost:9100/metrics,prometheus.yml配置如下:
- job_name: "node_exporter" scheme: "https" metrics_path: "/node-exporter/metrics" static_configs: - targets: ["api.example.com:443"] basic_auth: username: 'username' password: 'password'
问题
Prometheus仅识别到一个监控目标,无法区分两台EC2实例的指标。
疑问
- 能否通过端口指定LB1转发到目标组中的特定实例?这样可以让不同实例的node exporter用不同端口,通过端口区分目标
- 能否通过URL中的IP指定LB1转发到特定实例?这样所有实例的node exporter可以用相同端口,通过URL中的IP定位目标
尝试的方案2:直接通过EC2实例IP采集
配置方式
将两台EC2实例的IP直接注册为Prometheus目标,prometheus.yml配置如下:
- job_name: "node_exporter" scheme: "http" metrics_path: "/node-exporter/metrics" static_configs: - targets: ["162.x.y.1:9100", "162.x.y.2:9100"] basic_auth: username: 'username' password: 'password'
问题
当前用的是HTTP协议,想改成HTTPS但不知道怎么配置。
疑问
- 如何给EC2实例的IP配置SSL,并且支持向非443端口发送HTTPS请求?是否可行?
核心问题总结
如何正确配置Prometheus,使其能从AWS负载均衡器后方同一目标组内的EC2实例收集node exporter指标?该场景下应该如何注册监控目标?
解决方案
针对你的场景,推荐两种可行的配置方式,按优先级排序:
方式一:直接通过EC2实例IP+HTTPS采集(推荐)
这是最直接且易维护的方案,可解决方案2的HTTPS问题:
- 给EC2实例配置SSL证书
- 可使用Let's Encrypt免费证书,或AWS ACM证书(注意ACM不直接支持IP证书,需导入第三方签发的IP证书)
- 在EC2实例的Nginx上配置HTTPS监听(比如9101端口),将请求转发到
localhost:9100/metrics,同时配置SSL证书和密钥。示例配置:server { listen 9101 ssl; server_name _; # 适配IP访问场景 ssl_certificate /path/to/your/cert.pem; ssl_certificate_key /path/to/your/key.pem; location /node-exporter/metrics { proxy_pass http://localhost:9100/metrics; auth_basic "Prometheus Auth"; auth_basic_user_file /path/to/.htpasswd; } }
- 更新Prometheus配置
修改prometheus.yml,将协议改为HTTPS,端口改为9101:- job_name: "node_exporter" scheme: "https" metrics_path: "/node-exporter/metrics" static_configs: - targets: ["162.x.y.1:9101", "162.x.y.2:9101"] basic_auth: username: 'username' password: 'password' # 若使用自签名证书,可添加以下配置跳过验证(生产环境不推荐) # tls_config: # insecure_skip_verify: true - 安全组配置
确保EC2实例的安全组允许Prometheus所在的M1机器访问9101端口
方式二:通过负载均衡器+目标组规则区分实例
如果必须通过LB1采集,可通过配置LB1的路径路由规则区分不同实例:
- 配置Nginx路径区分
在I1的Nginx上配置路径/node-exporter-i1/metrics转发到localhost:9100/metrics,I2的Nginx配置/node-exporter-i2/metrics转发到本地node exporter - 配置LB1的目标组规则
在LB1的HTTPS监听器上添加两条路由规则:- 请求路径匹配
/node-exporter-i1/*时,转发到仅包含I1的目标组TG1-I1 - 请求路径匹配
/node-exporter-i2/*时,转发到仅包含I2的目标组TG1-I2
- 请求路径匹配
- 更新Prometheus配置
在prometheus.yml中添加两个子Job,分别对应两个路径:
这种方式需要维护额外的目标组和路由规则,适合无法直接访问EC2实例IP的场景- job_name: "node_exporter_i1" scheme: "https" metrics_path: "/node-exporter-i1/metrics" static_configs: - targets: ["api.example.com:443"] basic_auth: username: 'username' password: 'password' - job_name: "node_exporter_i2" scheme: "https" metrics_path: "/node-exporter-i2/metrics" static_configs: - targets: ["api.example.com:443"] basic_auth: username: 'username' password: 'password'
疑问解答
- 方案1疑问1:LB1的端口转发基于监听器配置,一个端口只能关联一个目标组,无法通过不同端口直接转发到同一目标组的不同实例,除非给每个实例创建单独的监听器和目标组,成本较高
- 方案1疑问2:LB1基于域名、路径、端口等规则转发,无法通过URL中的IP指定特定实例——因为请求的IP是LB1的IP,而非实例IP
- 方案2疑问1:完全可行,通过Nginx监听非443端口并配置SSL证书即可,证书需支持IP或绑定对应的域名
内容的提问来源于stack exchange,提问作者Ankit Sharma
相关产品推荐
相关产品推荐

