prometheus基于主机的自动发现(promcr)

2023年 7月 15日 120.0k 0

prometheus自动发现(scrape them)在官网中方式有很多,我这里介绍的是使用consul_sd_config配合registrator来做,registrator作为node节点端,发现容器,且将发现信息注册给consul。拓扑如下:拓扑

而prometheus中使用consul_sd_config进行重新标记,可以使用的元标签如下:

  • __meta_consul_address:目标的地址
  • __meta_consul_dc:目标的数据中心名称
  • __meta_consul_metadata_<key>:目标的每个节点元数据键值
  • __meta_consul_node:为目标定义的节点名称
  • __meta_consul_service_address:目标的服务地址
  • __meta_consul_service_id:目标的服务ID
  • __meta_consul_service_metadata_<key>:目标的每个服务元数据键值
  • __meta_consul_service_port:目标的服务端口
  • __meta_consul_service:目标所属服务的名称
  • __meta_consul_tags:由标记分隔符连接的目标的标记列表

其中目标的IP编号和端口组装为 <__meta_consul_address>:<__meta_consul_service_port>。但是,在一些Consul设置中,相关地址在__meta_consul_service_address。在这些情况下,可以使用relabel 功能替换特殊__address__标签。

pcr

为了方便使用,我在git创建了一个pcr项目,地址如下

https://github.com/marksugar/pcr

在此简单说明如何进行基于主机做自动发现,具体可见github说明

registrator

registrator运行在每一个node节点,要注册给consul必须是有独立的IP地址,这个ip可能必须是宿主机的ip地址。我们要做的事就是获取每个宿主机的ip地址,并且自动获取。

为此,重新封装gliderlabs/registrator:v7容器是很有必要的。

  • 添加脚本获取
#!/bin/sh
# maintainer="linuxea.com"
NDIP=`ip a s ${NETWORK_DEVIDE:-eth0}|awk '/inet/{print $2}'|sed -r 's//[0-9]{1,}//')`
exec /bin/registrator -ip="${NDIP}" ${ND_CMD:--internal=false} consul://${NDIPSERVER_IP:-consul}:8500

需要传递几个变量才能使用这个镜象

NETWORK_DEVIDE: 网卡名称
NDIPSERVER_IP:consul server ip
ND_CMD: 参数

Example:

    environment:
    - REGISTRATOR_BIND_INTERFACE=eth0
    - NETWORK_DEVIDE=eth0 
    - NDIPSERVER_IP=172.25.250.249
    - ND_CMD=-internal=false

而在模板中,这里的参数是这样的:

- ND_CMD=-internal=false -retry-interval=30 -resync=180

-retry-interval=30会在三分钟后自动重新联系CONSUL_SERVER

  • compose
  registrator:
    container_name: registrator
    image: marksugar/registrator:v7.1
    network_mode: "host"
    depends_on:
      - consul
      - cadvisor
      - node_exporter
      - alertmanager
      - grafana
      - prometheus
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock
    environment:
    - REGISTRATOR_BIND_INTERFACE=eth0
    - NETWORK_DEVIDE=eth0 
    - NDIPSERVER_IP=172.25.250.249
    - ND_CMD=-internal=false -retry-interval=30 -resync=360
    cpu_shares: 14
    mem_limit: 50m
    logging:
      driver: "json-file"
      options:
        max-size: "200M"    
    labels:
      SERVICE_TAGS: prometheus

consul

consul可以是一个集群,也可以说单点,这里已单点的方式运行

其中,需要注意绑定的网卡端口

-bind '{{ GetInterfaceIP "eth0" }}'

如果你不是eth0,请修改,如下:

  consul:
    container_name: consul
    image: consul:1.4.0
    network_mode: "host"
    ports:
      - 8500:8500
    command: "agent -server -ui -client=0.0.0.0 -dev -node=node0 -bind '{{ GetInterfaceIP "eth0" }}' -bootstrap-expect=1 -data-dir=/consul/data"
    labels:
      SERVICE_IGNORE: 'true'
    environment:
    - CONSUL_CLIENT_INTERFACE=eth0
    cpu_shares: 30
    mem_limit: 1024m
    logging:
      driver: "json-file"
      options:
        max-size: "200M"
    volumes:
      - ./consul/config:/consul/config
      - ./consul/data:/consul/data
    labels:
      SERVICE_TAGS: prometheus

注册的机器都会在web接口中显示,大致像这样1227.png

系统与容器

在prom/node-exporter:v0.16.0中,选择prom/node-exporter:v0.16.0是有原因的,prom/node-exporter:v0.16.0是可以发现出磁盘,而在prom/node-exporter:v0.17.0经测试,是发现不了的

cadvisor启动的端口是18880,这个端口不太会被占用

  node_exporter:
    image: prom/node-exporter:v0.16.0
    container_name: node_exporter
    user: root
    privileged: true
    network_mode: "host"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)'
    restart: unless-stopped
    ports:
      - 9100:9100
    cpu_shares: 14
    mem_limit: 50m
    logging:
      driver: "json-file"
      options:
        max-size: "200M"      
    labels:
      - "SERVICE_TAGS=prometheus"

  cadvisor:
    image: google/cadvisor:v0.32.0
    container_name: cadvisor
    network_mode: "host"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    command: --listen_ip="0.0.0.0" --port=18880
    restart: unless-stopped
    ports:
      - 18880:18880
    cpu_shares: 14
    mem_limit: 50m
    logging:
      driver: "json-file"
      options:
        max-size: "200M"      
    labels:
      SERVICE_TAGS: prometheus

prometheus

在prometheus中,我修改了保存的时间,并且配置文件也做了调整

      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--storage.tsdb.retention=45d'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--web.enable-lifecycle'

其中,对于每个容器类型,做了区分,如:cadvisor,如下

  - job_name: 'cadvisor'
    metrics_path: /metrics
    scheme: http
    consul_sd_configs:
      - server: 127.0.0.1:8500
        services: ['cadvisor']
    relabel_configs:
        - source_labels: ['__meta_consul_service']
          regex:         '(.*)'
          target_label:  'job'
          replacement:   '$1'
        - source_labels: [__meta_consul_tags]
          target_label: tags
        - source_labels: ['__meta_consul_service_address']
          regex:         '(.*)'
          target_label:  'instance'
          replacement:   '$1'
        - source_labels: ['__meta_consul_service_address', '__meta_consul_service_port']
          regex:         '(.*);(.*)'
          target_label:  '__address__'
          replacement:   '$1:$2'

        - source_labels: ['__meta_consul_tags']
          regex:         ',(prometheus|app),'
          target_label:  'group'
          replacement:   '$1'

自动发现字段

    relabel_configs:
        - source_labels: ['__meta_consul_service']
          regex:         '(.*)'
          target_label:  'job'
          replacement:   '$1'
        - source_labels: [__meta_consul_tags]
          target_label: tags
        - source_labels: ['__meta_consul_service_address']
          regex:         '(.*)'
          target_label:  'instance'
          replacement:   '$1'
        - source_labels: ['__meta_consul_service_address', '__meta_consul_service_port']
          regex:         '(.*);(.*)'
          target_label:  '__address__'
          replacement:   '$1:$2'

其中:

__meta_consul_service发现的地址会重写成job

__meta_consul_tags的值重写为tags

__meta_consul_service_address获取的ip重写为instance

__meta_consul_service_address', '__meta_consul_service_port'分别是ip和端口

$1和$2分别对应第一个参数和第二个参数。

分组

但是这还不够,当发现后,这些信息必须有一个标签来做区分,否则我们是不能够用来灵活使用的,我们需要一个标签,如下所示

        - source_labels: ['__meta_consul_tags']
          regex:         ',(prometheus|app),'
          target_label:  'group'
          replacement:   '$1'

如果__meta_consul_tags中包含prometheus字段或者app字段,就重新成一个组,就是上面所示的意思

  • 这也说明了为什么在每个容器后都会打上一个标签的原因
    labels:
      SERVICE_TAGS: prometheus

我们可以利用这个标签对项目做分组,灵活的划分

grafana

有了这个标签之后,我们可以对不同的标签进行划分。如下1225.png

在项目组中,是有多个组,在每个组下,有多台机器,这里使用ip划分。

但是,这样还是不够,有一些容器,没有在k8s中,他在宿主机上运行,那么这个模板就不能完美使用,重新编辑后的,就成了这样子。1226.png

根据项目,和项目中的容器类型,根据容器来看对应容器下的主机情况。在github中还有其他的模板以供参考。

对于如何来分组这个问题,我们首先要有一个标签,或者不同的表情,根据标签来分大组,如类型,项目,web等,而后根据每个标签,或者ip,或者容器名称组合一个序列来看

项目地址:https://github.com/marksugar/pcr,这个工具我在使用,逐步更新维护,如果对你有帮助,请移步后顺手点个星星。延伸阅读:https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config延伸阅读:https://prometheus.io/blog/2015/06/01/advanced-service-discovery/

相关文章

对接alertmanager创建钉钉卡片(1)
手把手教你搭建OpenFalcon监控系统
无需任何魔法即可使用 Ansible 的神奇变量“hostvars”
openobseve HA本地单集群模式
基于k8s上loggie/vector/openobserve日志收集
openobseve单节点和查询语法

发布评论