Skip to content

C/S architecture of distributed grid ICMP&HTTP dial test framework, dial test artifact; C/S 架构的分布式网格化 ICMP&HTTP 拨测框架,拨测神器

License

Notifications You must be signed in to change notification settings

resurgence72/ProberMesh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ProberMesh 一款分布式网格化拨测框架

1. 什么是网格化探测?

网格化探测通常是指各region/zone两两探测,形成一张 mesh 网格,通常是icmp探测的高阶需求;


probermesh 项目的优势
0. server/agent 二合一,单二进制部署;
1. 支持内网/公网模式下 icmp 自动发现,agent 一键部署自动加入 mesh 网格,不需要借助 consul 等额外组件;
2. 支持同 region 下的容错性;这块很重要,同 region 下可以部署多 agent,防止由于单台 agent 网络问题造成的探测失败 -> 告警噪音;
   server会对同region下结果agg;同region下agent越多,数据越准确,越稳定,容错率越高;
3. 原生支持 prometheus, server 暴露openMetric数据供 prometheus 拉取;
4. 支持 icmp/http 两种探测形式,icmp mesh 和 http 多点探测 可共存;
5. 丰富的 metric 暴露,可结合 region 做灵活的自定义dashboard和告警策略;
6. agent 支持自升级,运维极简;
7. 集成任务下发功能,网络调试神器;

2. region 概念说明

ICMP 视野落在 Region to Region ;
HTTP 视野落在 Region to URL ;

同 Region 下拨测结果做 agg;

Region 是此项目的核心概念,极其灵活,意义可以自定义。例如(K8s/host环境 prod/test环境 ali/gcp厂商 等)
ICMP 默认会拨测 非 自身region的所有region;如果需要拨测自身,需要在 server 端指定 -server.probe.self 参数

支持 ICMP/HTTP 分阶段耗时:
	HTTP 支持 resolve/connect/tls/processing/transfer 五阶段耗时 (对标blackbox_exporter)
	ICMP 支持 resolve/rtt 分阶段耗时; 支持丢包率, 抖动标准差 等丰富指标

3. 支持的指标

# ping 指标
prober_icmp_failed   # icmp当前拨测失败数  gauge
prober_icmp_duration_seconds  # icmp拨测分阶段耗时 gauge
prober_icmp_packet_loss_rate  # icmp拨测丢包率 gauge
prober_icmp_jitter_stddev_seconds  # icmp拨测标准差 gauge
prober_icmp_duration_seconds_total # icmp拨测耗时分布 histogram

# http 指标
prober_http_failed  # http当前拨测失败数 gauge
prober_http_duration_seconds  # http拨测分阶段耗时 gauge
prober_http_ssl_earliest_cert_expiry  # tls指标
prober_http_status_code # 响应码

# 健康检查
prober_agent_is_alive  # agent存活情况 gauge

# 通用
prober_server_receive_points  # server收到的上报点数 counter

# 管理
prober_server_task_enabled  # 标识是否开启任务下发功能
prober_server_probe_self_enabled  # 标识agent是否允许同region拨测;默认为0,即agent只会拿到非自身region的拨测列表

4. 运维指南

# 项目构建
cd ProberMesh/cmd/probermesh && go build -o probermesh .

# 项目运行
./probermesh -h
Usage of ./probermesh:
    # 通用参数
    -mode string
        服务模式(agent/server) (default "server")
    -v    版本信息
    -h    帮助信息
    
    -log.dir string
      日志目录 (default "/logs/")
    -log.level int
        日志级别;
        PanicLevel 0
        FatalLevel 1
        ErrorLevel 2
        WarnLevel  3
        InfoLevel  4
        DebugLevel 5
        TraceLevel 6
         (default 3)
    
    # agent 端参数
    -agent.icmp.network-type string
        agent ICMP探测agent自身上报IP类型;
        intranet: agent上报内网IP地址,用与构建内网维度icmp网格;
        public: agent上报公网IP地址,用于构建公网维度下icmp网格;
         (default "intranet")
    -agent.probe.interval string
        agent端探测周期 (default "15s")
    -agent.region string
        agent端所属region/zone;不指定默认自动获取regionID (default "icmp-china-shanghai")
    -agent.sync.interval string
        agent端同步targets周期 (default "1m")
    -agent.upgrade
        agent端是否开启自升级功能,默认关闭
    -agent.upgrade.interval string
        agent端检查upgrade周期; 仅在指定 -agent.upgrade 后生效 (default "1m")
    -agent.rpc.report.addr string
        server端RPC地址 (default "localhost:6000")
    
    
    # server 端参数
    -server.aggregation.interval string
        server聚合周期 (default "15s")
    -server.http.listen.addr string
        serverHTTP监听地址 (default "localhost:6001")
    -server.rpc.listen.addr string
        serverRPC监听地址 (default "localhost:6000")
    -server.icmp.discovery string
        server端ICMP探测目标获取模式(static/dynamic);
        static:  各region下icmp探测地址按照配置文件为准;
        dynamic: 各region下icmp探测地址按照agent自上报服务发现为准,且会覆盖掉配置中同region下原icmp列表;
         (default "dynamic")
    -server.probe.file string
        server端探测列表文件路径
    -server.series.cache.ratio int
        server指标缓存时长重置倍率 (default 5)
    -server.task
        server是否开启task任务下发功能
    -server.task.meta.dir string
        server持久化task结果源目录 (default "./task_meta/")
    -server.probe.self
        server控制agent是否允许同region拨测
   
  

# 探测列表文件(可选) -server.probe.file 参数所指定的配置
cat probermesh.yaml
prober_configs:
  - prober_type: http
    region: project-01
    http:                     # http配置端对标 blackbox_exporter,原生适配其http配置段
      valid_status_codes:
        - 200
        - 201
      method: GET
      headers:
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
      fail_if_body_matches_regexp: text.*
    targets:
      - http://www.baidu.com
      - http://www.taobao.com
      - www.ladjflajfl.ccc
  - prober_type: http
    region: cn-chengdu
    targets:
      - www.baidu.com
      - www.taobao.com
  - prober_type: icmp
    region: cn-hangzhou
    targets:
      - 180.101.49.12
      - 8.8.8.8
  - prober_type: icmp
    region: cn-shanghai
    targets:
      - 8.8.8.8



PS: region参数优先级
1. 命令行 -agent.region
2. 环境变量 PROBER_REGION
3. 代码curl云厂商region接口(仅支持aliyun)
4. 使用默认region cn-shanghai

其余参数可根据需要自定义调整


PS: -server.icmp.discovery 参数支持两种icmp发现模式
1. static静态发现:  icmp探测地址从静态配置文件中获取,需指定 -server.probe.file 参数配合使用,否则无icmp和http数据,启动没意义;
2. dynamic动态发现: icmp探测地址由agent动态上报,并且agent 每1m (-agent.sync.interval) 向server同步一次,可自动生成一张icmp Mesh 网格;

http仅支持通过配置文件指定,不支持自动发现模式

5. 效果展示

1. ICMP 面板效果

直接导入 ./build/grafana/probermesh-icmp.json 至 Grafana 即可使用

ICMP 拨测网格

2. HTTP 面板效果

HTTP 拨测

6. ProberMesh最佳实践

ICMP网格化拨测需求下:
- 内网互通环境下,使用
	1. server动态模式 -server.icmp.discovery=dynamic;
    2. agent内网模式 -agent.icmp.netowrk-type=intranet 拿到内网ip,以内网作为ip池上报server;
    
- 公网互通环境下,使用
	1. server动态模式 -server.icmp.discovery=dynamic;
    2. agent公网模式 -agent.icmp.netowrk-type=public 拿到实例出口公网ip,以公网作为ip池上报server;

其余需求下(自定义模式):
使用
	1. server静态模式 -server.icmp.discovery=static
    2. server指定配置文件 -server.probe.file=./probermesh.yaml 自定义互(ping/http)对象;所有agent根据server下发的配置文件做拨测;





具体场景case:
########### 场景一: 公网icmp拨测网格化 ###########
# server 端使用
./probermesh \
-mode server \
-server.rpc.listen.addr=1.1.1.1:6000 \
-server.http.listen.addr=1.1.1.1:6001 \
-server.aggregation.interval=15s \
-server.icmp.discovery=dynamic   # 1. 设置为动态模式

# agent 端使用
./probermesh \
-mode agent \
-agent.region=ali-cn-shanghai \
-agent.probe.interval=15s \
-agent.sync.interval=1m \
-agent.icmp.network-type=public \   # 2. 设置为公网模式
-agent.rpc.report.addr=1.1.1.1:6000



########### 场景二: 内网互通icmp拨测网格化 ###########
# server 端使用
./probermesh \
-mode server \
-server.rpc.listen.addr=1.1.1.1:6000 \
-server.http.listen.addr=1.1.1.1:6001 \
-server.aggregation.interval=15s \
-server.icmp.discovery=dynamic  # 1. 设置为动态模式

# agent 端使用
./probermesh \
-mode agent \
-agent.region=ali-cn-shanghai \
-agent.probe.interval=15s \
-agent.sync.interval=1m \
-agent.icmp.network-type=intranet \  # 2. 设置为内网模式
-agent.rpc.report.addr=1.1.1.1:6000




########### 场景三: 非网格化icmp拨测(一对多或n对多) / 通用http拨测 ###########
# server 端使用
./probermesh \
-mode server \
-server.rpc.listen.addr=1.1.1.1:6000 \
-server.http.listen.addr=1.1.1.1:6001 \
-server.aggregation.interval=15s \
-server.icmp.discovery=static \   # 1. 设置为静态模式
-server.probe.file=./probemesh.yaml  # 2. 指定探测配置文件

# agent 端使用
./probermesh \
-mode agent \
-agent.region=ali-cn-shanghai \
-agent.probe.interval=15s \
-agent.sync.interval=1m \
-agent.rpc.report.addr=1.1.1.1:6000



###################
注意: 
脚本 script/probermesh_agent_deploy.sh 提供基于 supervisor 托管的公网网格拨测(场景一)agent一键部署功能;
场景二/三需要根据相应配置调整脚本中agent启动参数;

脚本使用方式:  sh probermesh_agent_deploy.sh ali-cn-shanghai
脚本后需要跟一个agent的region信息,对标 -agent.region

server端建议基于 supervisor 手动配置,因为配置较灵活且只需要一个节点,脚本主要解决agent的快速部署;

7. Prometheus 采集 ProberMesh 的指标

scrape_configs:
  - job_name: "probermesh"
    scrape_interval: 15s
    static_configs:
      - targets: ["$server.http.listen.addr"]
    metric_relabel_configs:
      - source_labels: ["__name__"]
        regex: "^prober.*"
        action: 'keep'

高级功能 (可通过 probermesh-cli 工具操作)

1. Server 端下发任务

1. 需求及使用
例如 我们在拨测不通的情况下可能会借助三方工具,例如 route, 例如 mtr 去进一步定位问题;基于这种场景,probermesh 集成了简单的任务下发系统;
若要使用功能,需要在 server 启动参数中指定 -server.task 来开启功能;

下发流程: 管理机向 server 端 http://${server_http_addr}/-/task 发送 POST 任务下发请求
{
    "region": "欧洲-美国-*",
    "expr": "=~",
    "cmd": "mtr -r www.baidu.com -c 20 -i0.1",
}
region 用来匹配合规的agent, 支持正则匹配;例如,我们只想让欧洲的节点执行命令,那么需要指定 region 为 "欧洲*" 或 "欧洲.+" 等;
expr 标识匹配的操作符,当前支持四种,分别是 "=" 匹配 / "!=" 不匹配 / "=~" 正则匹配 / "!~" 正则不匹配; 通过 region + expr 极其灵活的去下发任务;
cmd 需要执行的命令,不需要再加 bash -c , 直接写原命令即可。

agent端执行并上报后,可以在 server 端的 ./task_meta 目录下找到所有上报的任务; 具体目录可通过 -server.task.meta.dir 更改;
# task_meta 目录
[root@test task_meta]# ll
total 4
-rw-r--r-- 1 root root 1417 Feb  8 16:12 美国-弗吉尼亚_xx.xx.xx.xx_2023-02-08_16-12-27
[root@test task_meta]# cat 美国-弗吉尼亚_xx.xx.xx.xx_2023-02-08_16-12-27 
commond:
mtr -r www.baidu.com -c 10 -i0.1 

output:
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Package 2:mtr-0.85-7.el7.x86_64 already installed and latest version
Nothing to do
Start: Wed Feb  8 16:12:21 2023
HOST: test- Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- xx.xx.xx.x                 0.0%    10    0.5   0.4   0.3   0.5   0.0
  2.|-- xx.xx.xx.x                 0.0%    10    2.2   2.2   2.0   2.4   0.0
  3.|-- xx.xx.xx.x             30.0%    10    0.7   1.4   0.5   4.4   1.4
  4.|-- xx.xx.xx.x            90.0%    10    0.9   0.9   0.9   0.9   0.0
  5.|-- ae72.edge5.washington12.l 50.0%    10    8.5   7.1   1.2  21.2   8.3
  6.|-- 63.243.136.12              0.0%    10    4.6   1.9   1.5   4.6   0.9
  7.|-- if-ae-55-2.tcore3.aeq-ash 40.0%    10   71.3  71.3  71.0  71.8   0.0
  8.|-- if-ae-36-2.tcore2.lvw-los 50.0%    10   69.1  70.2  69.1  73.8   1.9
  9.|-- if-ae-2-2.tcore1.lvw-losa 40.0%    10   71.1  71.6  71.1  72.9   0.4
 10.|-- if-ae-60-2.tcore1.sv1-san 30.0%    10   71.3  71.8  71.1  73.3   0.6
 11.|-- if-ae-0-2.tcore2.sv1-sant  0.0%    10   68.8  69.2  68.8  70.7   0.3
 12.|-- xx.xx.xx.x               0.0%    10   68.9  68.8  68.7  69.0   0.0
 13.|-- xx.xx.xx.x              0.0%     9   69.9  70.1  69.6  72.1   0.6
 14.|-- xx.xx.xx.x             0.0%     9   68.3  68.3  68.3  68.3   0.0

2. Agent 节点自升级

1. 需求及实现
probermesh 部署后存在一种场景,我们需要对 agent 进行升级或bug fix;这在 C/S agent 二进制场景中是一种常见需求;
通用的批量升级方式无非如下几种
1. 手动替换二进制 restart
   弊端:操作繁琐,节点多了后需要耗费大量时间
2. ansible 自动化批量执行
   弊端: 节点多了后ssh执行效率很低
3. 基于 kubernetes 环境做 Deployment/DaemonSet replace
   弊端: probermesh 大部分场景是部署在同内网的多region, 或不同region通过公网通讯;使用k8s托管成本太高
4. self upgrade节点自升级
   弊端: 代码层面适配,大规模节点下升级有可能把管理机带宽打满(probermesh主要多对多拨测,节点数量不会很大,打满问题不太会发生)
5. ...



当前使用4实现自升级,这种实现方式有两个前提: 
1. agent 节点需要使用守护进程托管,例如 supervisord; 
2. agent 需要指定 -agent.upgrade 参数;



升级流程: 管理机向 server 端 http://${server_http_addr}/-/upgrade 发送 POST 升级请求:
{
    "downloadURL": "http://172.18.12.38:9999/probermesh",
    "md5Check": "0a85983226d91029bcf5701f94d18753",
    "version": "0.0.1",
    "force": false,
}
downloadURL: 标识agent新版本二进制的下载地址,这里要注意,二进制名称要和原启动命令二进制名称一致,否则守护进程会restart失败;
md5Check: 标识agent新版本的md5,agent需要和下载的二进制做md5校验,校验成功才会替换升级;
version: 标识新版本的version;
force: 标识是否强制升级,这里存在两种情况
    - false 情况下,正常升级,agent会进行 version check 看需要升级的版本否比当前版本高,如果符合条件,agent会进行调谐重启升级,直至成功升级到高版本为止;
    - true 情况下,强制升级,agent跳过version check,支持任意版本号,agent拿到升级信息后只会升级一次(无论成功或失败,原因是防止强制升级失败导致无限制升级重启,导致服务不可用)
2. 题外话:自升级可能存在的问题
agent升级是全量升级,如何做灰度或做并发控制? 这种需求通常存在于 agent 节点规模很大的场景;
1. 需要一批批替换,例如两万个agent, 500台500台的升级;
2. 管理机需要限制带宽,防止带宽被打满;


probermesh不同于监控等agent,需要每台机器都部署,一般会在每个region选取多台做agent,正常场景下就足够了。
如果后续真有类似的大规模部署拨测需求,这里提供一个简单的思路,后续有需求时再实现:可以通过分布式锁hold agent upgrade count

About

C/S architecture of distributed grid ICMP&HTTP dial test framework, dial test artifact; C/S 架构的分布式网格化 ICMP&HTTP 拨测框架,拨测神器

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages