基于Consul完成腾讯云主机监控
目录背景
- 腾讯云提供tencent-exporter支持获取CVM主机列表及监控信息。但碍于CVM主机过多,使用Tencent-exporter将导致频繁调用腾讯云API,导致额外费用支持。因此在监控CVM云主机使用Consul自动注册监控方式。但Consul在使用中只是一个注册中心,并不会自动获取到腾讯云CVM实例列表,需要自行调用腾讯云API获取CVM实例列表注册至Consul。
构成
- 监控构成:
NodeExporter + 自开发脚本 + Consul + Prometheus
流程
获取腾讯云信息存储至数据库
所有CVM主机通过自主化助手统一部署Node-Exporter
获取数据库中CVM信息POST至Consul
Prometheus抓取Consul信息
完成主机自动发现
- 步骤0和1这里不做展开,主要对步骤2、3、4展开说明
- 因为Prometheus环境有两套,所以分别部署了两套Conusl,一套测试环境,一套生产环境。根据CVM打标分为dev与prod环境,将归属于不同环境的CVM主机根据标签分别注册至不同环境Consul。
数据POST至Conusl
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注册主机
- 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
标签:err,主机,Consul,client,CVM,腾讯,consul
From: https://www.cnblogs.com/tcy1/p/17481192.html