AIOps 一场颠覆传统运维的盛筵
1326
2022-10-14
记容器监控从单机到多机进化过程
前言
目前在一间奶茶厂运维,因人员编制整个运维部只有几个伙伴,监控这块很自然落在我的工作范围内。容器监控这块我们也是使用目前业界流行的prometheus系列技术栈。刚开始我们一个单点prometheus➕本地TSdb存储就能解决监控和告警的需求,后面随着业务量增加、监控需求的扩展和单点故障问题,我们转变为多点prometheus➕本地TSdb➕远程对象存储。下面我来聊聊这一个进化过程。
单点prometheus阶段
此阶段一个prometheus负责所有的监控存储➕查询工作,生态架构如图(原生的prometheus生态架构)
工作流程:
1.pull主动方式:
采集器cadvisor、exporter、kube_state_metrics、metrics_server 采集监控指标;prometheus根据k8s动态服务发现、静态服务发现、consul动态服务发现等获取监控target;prometheus 从targets列表拉取指标数据 ,把数据存储到TSdb;grafana接入prometheus数据源,通过对应的json模板展示监控数据;prometheus 配置中加入Alertmanager 和告警规则,发送到微信、钉钉、邮件;
2.push被动方式:
业务暴露指标,客户端通过sdk获取指标-->推送到pushgateway --> pushgateway以job方式接入到prometheus --> grafana展示业务监控指标
3.业务监控方式:
业务监控一:
我们是Java springBoot 业务架构,业务监控是由业务方提供metrics接口,我们使用类consul服务发现动态采集metrics存储到TSdb。业务方通过Spring-boot-starter-actuator来导出内部的运行状态指标,原理如下:
由于业务使用Euraka作注册中心,pod启动都加入到注册中心,我们在prometheus中配置Euraka统一的metrics地址结合consul动态服务发现即可获取业务监控target,prometheus配置如下:
#线上微服务监控 - job_name: 'microservice' metrics_path: /actuator/prometheus scrape_interval: 30s consul_sd_configs: - server: 'base-register-in.heyteago-prd.svc.cluster.local:30001' relabel_configs: - source_labels: ['__meta_consul_tags'] action: keep - source_labels: ['__meta_consul_service'] target_label: job - source_labels: ['__meta_consul_address', '__meta_consul_service_metadata_management_port'] separator: ':' target_label: __address__
业务监控二:
... ...def push_prometheus(kwargs): registry = CollectorRegistry() # Guage(metric_name,HELP,labels_name,registry=registry) g = Gauge("invoive_monitor", u"发票监控", ['metric_item','remarks','company_title'], registry=registry) for k, v in kwargs.items(): metric_item = k remark = v["remarks"] company_titles = v["company_title"] value = v["count"] g.labels(metric_item, remark, company_titles,).set(value) print(k, v) push_to_gateway('http://10.0.6.208:31000', job='invoive_monitor', registry=registry, timeout=200) print("==============上报push gateway已成功============")
多点prometheus阶段
结合单机prometheus所暴露问题:
单个prometheus容器副本数没法进行增加,直接增加副本会造成监控数据混乱;数据存储局限于本地TSdb,数据量大小取决于被采集服务的指标数量、服务数量、采集速率以及数据过期时间;整个业务集群监控metrics统一由一个prometheus采集,业务量大的时候prometheus内存容易oom;Grafana面板通过promQL直接查询prometheus,大数据量时查询响应慢并且每次对prometheus也是不小冲击;
prometheus本身只支持单机部署、不支持高可用以及水平扩展,总不能让我们开发一个吧,社区肯定早早为这些场景造好轮子。
我们考虑可以从服务纬度进行拆分、更换存储引擎、联邦组合等一定程度上可以解决单机prometheus大规模下的场景,但是操作和运维复杂系数比较高,并且不能很好支持数据长期存储。在社区中找到一个更合适的方案Thanos,它完全兼容prometheus API,提供统一查询聚合分布式部署的 Prometheus 数据的能力,同时也支持数据存储到各种对象存储(无限存储能力)、以及降低采样率来加速大时间范围的数据查询。
sidecar模式如下:(https://thanos.io/)
简单介绍下图中这几个组件的作用:
Thanos Query: 实现了 Prometheus API,将来自下游组件提供的数据进行聚合最终返回给查询数据的 client (如 grafana)类似数据库中间件。
Thanos Sidecar: 连接 Prometheus,将其数据提供给 Thanos Query 查询,并且/或者将其上传到对象存储,以供长期存储。
Thanos Store Gateway: 将对象存储的数据暴露给Thanos Query去查询。
Thanos Ruler: 对监控数据进行评估和告警,还可以计算出新的监控数据,将这些新数据提供给Thanos Query查询,并且/或者上传到对象存储,以供长期存储。
Thanos Compact: 将对象存储中的数据进行压缩和降低采样率,加速大时间区间监控数据查询的速度。
解决单机prometheus所暴露问题
部署方法参考官方最佳实践,由于篇幅问题我们具体部署这里不细聊。
https://github.com/thanos-io/kube-thanos
数据长期存储我们使用腾讯云COS,通过secret存储cos相关认证信息:
apiVersion: v1kind: Secretmetadata: name: thanos-objectstorage namespace: thanostype: OpaquestringData: objectstorage.yaml: | type: COS config: bucket: "thanos-monitor-prod" region: "ap-guangzhou" app_id: "1234567890" secret_key: "RDm4brxxxxxxxxxBzEDxRe6MRFi" secret_id: "AKIDLH1xxxxxxxddPyJQGrPBf3MfAi"
prometheus配置sidecar(部分):
apiVersion: apps/v1kind: StatefulSetmetadata: name: prometheus namespace: thanos labels: app.kubernetes.io/name: thanos-queryspec: serviceName: prometheus-headless podManagementPolicy: Parallel replicas: 3 ##prometheus节点数不再是1个 spec: serviceAccountName: prometheus - name: prometheus ##prometheus image: harbor.xxx.com/public/prometheus:v2.4 args: - --config.file=/etc/prometheus/config_out/prometheus.yaml - --storage.tsdb.path=/prometheus - --storage.tsdb.retention.time=8d ##本地TSdb存储8天 - --web.route-prefix=/ - --web.enable-lifecycle - --storage.tsdb.no-lockfile - --storage.tsdb.min-block-duration=2h - --storage.tsdb.max-block-duration=2h - --log.level=debug - --web.enable-admin-api #- --web.cors.origin=".*" - name: thanos ##接入sidecar #image: quay.io/thanos/thanos:v0.11.0 image: harbor.xxx.com/public/thanos:v0.21.0 args: - sidecar - --log.level=debug - --tsdb.path=/prometheus - --prometheus.url=http://127.0.0.1:9090 - --objstore.config-file=/etc/thanos/objectstorage.yaml - --reloader.config-file=/etc/prometheus/config/prometheus.yaml.tmpl - --reloader.config-envsubst-file=/etc/prometheus/config_out/prometheus.yaml - --reloader.rule-dir=/etc/prometheus/rules/
其他组件部署参考以上官方网站。
优化prometheus-config去掉重复采集的job,另外集群配置需要注意:
apiVersion: v1kind: ConfigMapmetadata: name: prometheus-config-tmpl namespace: thanosdata: prometheus.yaml.tmpl: |- global: scrape_interval: 25s evaluation_interval: 30s external_labels: cluster: k8s-prod prometheus_replica: $(POD_NAME)......
Prometheus实例采集的所有指标数据里都会额外加上external_labels指定的label,通常用cluster区分当前Prometheus所在集群的名称,再加了个 prometheus_replica,用于区分相同Prometheus副本(这些副本所采集的数据除了 prometheus_replica 的值不一样,其它几乎一致,这个值会被 Thanos Sidecar 替换成 Pod 副本的名称,用于 Thanos 实现 Prometheus 高可用)
优化prometheus ruler配置
引入recording rules提前设置好一个花费大量时间运算或经常运算的表达式,其结果保存成一组新的时间序列数据。当需要查询的时候直接会返回已经计算好的结果,这样会比直接查询快,同时也减轻了PromQl的计算压力,对可视化查询的时候也很有用,可视化展示每次只需要刷新重复查询相同的表达式即可。
#========================================recording-rulers================================ - name: recordings_pull rules: #监控大屏 - record: gateway_requests_seconds_count_5m_offer6d expr: sum(irate(gateway_requests_seconds_count[5m] offset 6d)) #========================================recording-rulers-02================================ - name: recordings_push interval: 60s rules: #线上UV Rate - record: uv_td_rate expr: prod_bussies{metric_item="uv_td_rate"} - record: uv_7dago_rate expr: prod_bussies{metric_item="uv_7dago_rate"}
总结
通过一番折腾我们接入Thanos解决prometheus单点问题,同时引入对象存储,使得冷数据能够保留到远程的对象存储,优化promQL使用了recording rule减轻PromQl的计算压力。
后续还需要和研发部门沟通,通过业务纬度拆分监控指标和优化业务已经遗弃的监控指标,减少单个prometheus因业务指标巨大造成高内存使用问题。
发表评论
暂时没有评论,来抢沙发吧~