基于Consul完成腾讯云主机监控

基于Consul完成腾讯云主机监控

背景#

  • 腾讯云提供tencent-exporter支持获取CVM主机列表及监控信息。但碍于CVM主机过多,使用Tencent-exporter将导致频繁调用腾讯云API,导致额外费用支持。因此在监控CVM云主机使用Consul自动注册监控方式。但Consul在使用中只是一个注册中心,并不会自动获取到腾讯云CVM实例列表,需要自行调用腾讯云API获取CVM实例列表注册至Consul。

构成#

  • 监控构成:

NodeExporter + 自开发脚本 + Consul + Prometheus

流程#

  1. 获取腾讯云信息存储至数据库

  2. 所有CVM主机通过自主化助手统一部署Node-Exporter

  3. 获取数据库中CVM信息POST至Consul

  4. Prometheus抓取Consul信息

  5. 完成主机自动发现

  • 步骤0和1这里不做展开,主要对步骤2、3、4展开说明
  • 因为Prometheus环境有两套,所以分别部署了两套Conusl,一套测试环境,一套生产环境。根据CVM打标分为dev与prod环境,将归属于不同环境的CVM主机根据标签分别注册至不同环境Consul。

数据POST至Conusl#

Copy
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" "github.com/hashicorp/consul/api" "log" "strings" ) var ( instanceid string Mapping_Ip string ) func ConnMysql() (db *sql.DB) { // mysql 连接信息 username := "!!!!" password := "!!!!" host := "!!!!" port := 3306 Dbname := "!!!!" // 连接mysql dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", username, password, host, port, Dbname) db, err := sql.Open("mysql", dsn) if err != nil { log.Fatal(err) } return db } func ConnConsul(env string) (client *api.Client) { // consul 连接信息 consulAddress := fmt.Sprintf("consul-%s.aaa.com", env) // 连接consul client, err := api.NewClient(&api.Config{Address: consulAddress}) if err != nil { log.Fatal(err) } return client } func ReadCvmDataForConsul(db *sql.DB, client *api.Client, env string) { rows, err := db.Query(fmt.Sprintf("SELECT InstanceId,Mapping_Ip FROM `tencent_cvm` WHERE `Env` = '%s' AND `delete` = '0' AND `InstanceName` NOT LIKE '%%emr%%' AND `instancestatus` = 'Running' ", env)) if err != nil { log.Fatal(err) } defer rows.Close() dbinstanceid := make(map[string]bool) for rows.Next() { rows.Scan(&instanceid, &Mapping_Ip) Mapping_Ip = strings.Trim(Mapping_Ip, "[]") entry := &api.AgentServiceRegistration{ ID: instanceid, Name: "tencent-cvm", Tags: []string{"consul-cvm", "test"}, Port: 9100, Address: Mapping_Ip, } dbinstanceid[instanceid] = true // 将ServiceEntry注册到Consul的Agent中 agent := client.Agent() if err := agent.ServiceRegister(entry); err != nil { log.Fatal(err) } } // 查询consul services中所有的instance services, _, err := client.Catalog().Service("tencent-cvm", "", nil) if err != nil { log.Fatal(err) } // 对比consul中存在但数据库不存在的instance,对销毁主机下线监控 for _, service := range services { if !dbinstanceid[service.ServiceID] { err = client.Agent().ServiceDeregister(service.ServiceID) if err != nil { log.Fatal(err) } fmt.Printf("Service在consul中存在,但是在mysql中已被删除:%s\n", service.ServiceID) } } } func main() { db := ConnMysql() defer db.Close() TencentEnv := []string{"dev", "prod"} for _, ch := range TencentEnv { client := ConnConsul(ch) ReadCvmDataForConsul(db, client, ch) } }

Prometheus抓取Consul注册主机#

Copy
- job_name: "consul-tencent-cvm" # 此处考虑未来如果多云? scrape_interval: 15s consul_sd_configs: - server: 'consul.aaa.com:8500' refresh_interval: 1m services: ["tencent-cvm"] relabel_configs: - source_labels: [__meta_consul_service_id] target_label: "instanceId" - source_labels: [__address__] regex: ([^:]+)(?::\d+)? replacement: "$1" target_label: instance action: replace
posted @   元气少女郭德纲!!  阅读(73)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示
CONTENTS