基于EC2的服务发现

假设你使用了AWS的自动伸缩组(ASG)或spot实例来部署服务,每时每刻EC2都有可能被创建或销毁,在这种场景下,使用static_configfile_config的方式来进行服务发现是不现实的。AWS提供了API,可以获取帐号下的EC2信息,此时应使用基于EC2的服务发现。

创建AWS新用户

创建一个AWS新用户,此用户可以通过AK/SK访问AWS, 且具有EC2ReadOnlyAccess权限(可通过以下命令进行测试)。

image-20210516222958782

配置基于EC2服务发现

prometheus.yml中增加下面配置, AK/SK、region根据实际情况进行替换:

  - job_name: 'ec2'
    ec2_sd_configs:
      - access_key: AIADFxxxxxxLVDF1B6U  
        secret_key: H5cIdfGzbxxxxx64h65u5nd6rfy5ZbiXZ/JjgA82 
        region: us-west-2  # ec2运行的region

重启prometheus服务,访问Service Discovery页面:

image-20210516215359898 获取到AWS帐号下的EC2信息:

image-20210516215345449

EC2 安装并运行node exporter

创建一台EC2,登录后安装并运行node exporter:

wget https://github.com/prometheus/node_exporter/releases/download/v1.1.2/node_exporter-1.1.2.linux-amd64.tar.gz
tar -zxvf node_exporter-1.1.2.linux-amd64.tar.gz
cd node_exporter-1.1.2.linux-amd64
./node_exporter

注意EC2安全组要放开prometheus sever的IP:

image-20210516225955597

EC2 relabel

访问targets页面,发现状态全部是down。因为prometheus server默认访问的是EC2 私有IP,且是80端口。而上一步启动的node exporter是运行在9100端口。

image-20210516230137562 现在,我们需要拉取EC2的公有IP地址 + 9100端口

Relabel是Prometheus强大的功能,可以在爬取目标之前重写目标的标签。参考 https://prometheus.io/docs/prometheus/latest/configuration/configuration/

更新后的prometheus.yml配置如下:

  - job_name: 'ec2'
    ec2_sd_configs:
      - access_key: AIADFxxxxxxLVDF1B6U  
        secret_key: H5cIdfGzbxxxxx64h65u5nd6rfy5ZbiXZ/JjgA82 
        region: us-west-2  # ec2运行的region
    relabel_configs:
      - source_labels: [__meta_ec2_public_ip]
        regex: '(.*)'
        replacement: '${1}:9100'
        target_label: __address__

relabel配置详解:

  • source_labels匹配 __meta_ec2_public_ip , 表示查询EC2的公网地址<img src="https://pingfan.s3.amazonaws.com/pic3/jnty1.png" alt="image-20210516230909624">
  • regex: ‘(.*)' 对上面的source_labels的值做匹配,提取出来是上一步查询到的public ip的全部内容
  • replacement基于上一步提取的public ip在后面添加 :9100 ,表示爬取54.245.213.233:9100地址。
  • __address__是promtheus内置的标签,表示要爬取目标的地址,现在这个目标被替换为公网地址+9100端口。

重新启动prometheus服务,此时Endpoint全部被替换成 {public ip} + {9100 port} 的形式,而上一步运行的node exporter也被成功发现:

image-20210516231707476

Keep & Drop

在生产环境中可能运行着大量的ec2,我们不想抓取所有的ec2 —— 一来不是所有的服务器上都运行着exporter,二来每次访问所有的ec2对prometheus也可能产生巨大的压力。

我们想仅拉取一部分EC2的metric,比如给一部分ec2打标签,service_type=node_exporter,只有携带这些特定标签的,才进行拉取。


给运行node exporter的EC2添加标签:service_type=node_exporter

image-20210516232650801 更新prometheus.yml配置如下:

  - job_name: 'ec2'
    ec2_sd_configs:
      - access_key: AIADFxxxxxxLVDF1B6U  
        secret_key: H5cIdfGzbxxxxx64h65u5nd6rfy5ZbiXZ/JjgA82 
        region: us-west-2  # ec2运行的region
    relabel_configs:
      - source_labels: [__meta_ec2_public_ip]
        regex: '(.*)'
        replacement: '${1}:9100'
        target_label: __address__
      - source_labels: [__meta_ec2_tag_service_type]
        regex: node_exporter
        action: keep

配置详解:

  • source_labels匹配 __meta_ec2_tag_service_type , 表示查询EC2 tag为service_type的值。
  • regex: node_exporter 表示上面匹配tag后,值为node_exporter。当然也可以使用正则其他强大的功能(例如node_exp.* 或 node_exporter| node_export111)。
  • action: keep, 表示对匹配成功的结果进行保留,其他的结果全部丢弃(prometheus不再爬取这部分)

重启prometheus服务,Targets中只显示携带对应标签的EC2:

image-20210516232829055

如果改成action: drop, 则表示对匹配到的结果进行丢弃,其余的结果保留。