云原生实践之Monitoring(一)

正文共: 2602字
预计阅读时间:7分钟

之前小白有讲到线上服务的可观察性在当下无论是运维还是研发的同学都是必须要掌握和了解的特性。对于当前服务可观察所要承担的功能,各大公司或社区也已基本形成共识,其主要也是围绕三个方向来提出要求:

  • monitoring (监控)

  • logging (日志)

  • tracing (追踪)

当我们翻开CNCF的生态地图,发现最右边的Observability and Analysis正是给大家绘出了各类型服务观测的指导方案。

image.png

更多详情的地址 https://landscape.cncf.io/

在这里小白以日常工作中常使用到的应用来跟大家简单介绍CNCF里面的一些云原生

1. Monitoring 监控


Prometheus |--> Thanos --> Grafana

          |--> AlertManager

  • Prometheus

CNCF已毕业的一个主要面向度量监控的时序数据库,和Kubernetes、Consul等能深度结合为监控服务发现带来极大的便利性

  • Thanos

CNCF沙箱内的一个面向Prometheus分布式架构的应用

  • Grafana

数据可视化展示的前端,以其丰富的数据源和酷炫插件捕获了大批用户

2.Logging 日志


            |--> Loki --> Grafana

Fluentd --> |--> Kafka --> Flume

            |--> ElasticSearch --> Kibana

  • Fluentd

CNCF已毕业的一个由Ruby开发的日志采集客户端,具备良好的采集效率、灵活简单的配置和丰富的插件等特性,更以其与Kubernetes的紧密结合而获得市场快速的验证

  • Loki

GrafanaLab开源的一个类似Prometheus的日志聚合系统,以其轻量的设计和水平扩展,具备很高的成本收益而闻名

3.Tracing 追踪


Collector --> Jaeger --> Grafana

  • Jaeger

CNCF已毕业的一个分布式追踪系统,由Uber推出,因其简单友好的UI和与kubernetes、istio的结合,当下也聚集着大量的使用者

从今天开始,小白会按照上述的结构,并以云原生服务可观察性的这个区块内带大家初尝和体验,那么我们就由Prometheus开始吧

<center>Prometheus架构</center>

首先小白在正式使用前先看下Prometheus的组件及其大概架构

image.png

在图中小白可以了解到,Prometheus的监控数据来源主要分两种,直接从目标exporter中主动抓取数据,或者短期job上传给Pushgateway再由Prometheus主动抓取。其次Prometheus的数据以TSDB方式存储在本地磁盘,同时它也通过一些服务发现方式找到被监控的目标。最终Prometheus的呈现是以内置的UI或者集成Grafana以PromQL方式将数据可视化展示出来,当然用户也可以通过API方式自行绘图展示。

<center>Prometheus部署</center>

关于部署小白不想展开篇幅细说,这里小白仅简单分析下当下主流的两种部署方式以及建议

  • 方式一 :Prometheus-Operator

优点:利用Kubernetes的CRD将Prometheus的部署和配置抽象得更直观和理解,普通用户在K8S里面只需像声明Service一样定义监控即可,不用再过多去关心和维护Prometheus服务

缺点:运维难度比较高,普通用户难以理解真实配置,比较适合熟悉Prometheus的高阶玩家

  • 方式二:Yaml

优点:可以根据自己环境灵活选择部署的服务,更能了解模块之间的协作关系

缺点:部署和配置略复杂,新手们需要一定的学习成本

小白建议新手们还是需要花一段时间从Yaml部署开始熟悉,虽然过程比较复杂,不过现在关于Prometheus部署的资料很多,不会有太大的问题。

<center>Prometheus实践 服务发现 Pod</center>

小白以当前认为最实用的基于Kubernetes Pod为服务发现的案例来和大家一起分析,首先我们先来看下配置


- job_name: kubernetes-pods-discovery

  honor_timestamps: true

  scrape_interval: 15s

  scrape_timeout: 10s

  metrics_path: /metrics

  scheme: http

  kubernetes_sd_configs:

  - role: pod

  relabel_configs:

  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]

    separator: ;

    regex: "true"

    replacement: $1

    action: keep

  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]

    separator: ;

    regex: (.+)

    target_label: __metrics_path__

    replacement: $1

    action: replace

  - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]

    separator: ;

    regex: ([^:]+)(?::\d+)?;(\d+)

    target_label: __address__

    replacement: $1:$2

    action: replace

  - separator: ;

    regex: __meta_kubernetes_pod_label_(.+)

    replacement: $1

    action: labelmap

  - source_labels: [__meta_kubernetes_namespace]

    separator: ;

    regex: (.*)

    target_label: kubernetes_namespace

    replacement: $1

    action: replace

  - source_labels: [__meta_kubernetes_pod_name]

    separator: ;

    regex: (.*)

    target_label: kubernetes_pod_name

    replacement: $1

    action: replace

这段配置的解释如下:

  • 匹配POD元数据中的pod_annotation字段,找到key为prometheus_io_scrape的label,利用正则表达式匹配true字段,成功则通过服务发现

  • 匹配POD元数据中的pod_annotation字段,找到key为peomerheus_io_path的label,然后把目标label变更为metrics_path

  • 匹配POD元数据中的pod_annotation和address字段,利用正则表达式获取 : 前半部分,也就是Pod的IP地址,然后将pod_annotation_prometheus_io_port的端口添加到Pod IP后面,组合成新的address ,然后替换原Label

  • 匹配POD元数据中的所有以_meta_kubernetes_pod_label开头的标签,然后全部重定向到新的Label当中

  • 匹配POD元数据中的__meta_kubernetes_namespace标签,然后重定向成新的kubernetes_namespace标签

  • 匹配POD元数据中的__meta_kubernetes_pod_name标签,然后重定向成新的kubernetes_pod_name标签

如上规则我们大体就可以看出来,小白想要实现在Prometheus发现目标为容器的服务大体要满足spec.template.metadata.annotations里面的三个要素:

  • scrape:定义是否需要采集监控指标

  • port:定义监控指标的采集端口

  • path:定义监控指标的采集路径


spec:

  template:

    metadata:

      annotations:

        prometheus.io/path: /metrics

        prometheus.io/port: "9104"

        prometheus.io/scrape: "true"

<center>Prometheus实践 服务发现 Consul</center>

有的同学可能会问小白:"Prometheus能不能监控非K8S里面的服务呢?",当然是可以的,小白认为如果是少量的服务,我们可以直接通过Prometheus静态配置目标地址。如果我们的环境处于一个动态的,或者有大量的外部服务的话,小白建议采用一些外部的服务中心来做目标监控节点的服务发现,比如Consul。关于Consul里的Service注册,小白也分享我们自身机房服务器上的node-exporter注册到Consul来做服务发现的实践:

node.json主要解释了node注册到Consul中的一些基本的元数据,这部分可以由你的cmdb生成,或者也可以通过其它工具渲染生成


{

    "Datacenter": "<your-consul-datacter>",

    "Node": "x.x.x.x",

    "Address": "x.x.x.x",

    "Service": {

        "ID": "node-exporter",

        "Service": "node-exporter",

        "Port": 9100,

        "Tags": [

            "<your-server-group>"

        ]

    }

}

在prometheus中的consul服务发现就可以按照如下配置:


  - job_name: consul-node-exporter

    consul_sd_configs:

      - server: <your-consul-address>

        datacenter: <your-consul-datacter>

        scheme: https

        username: "<base_auth_username>"

        password: "<base_auth_password>"

        services: ["node-exporter"]

    relabel_configs:

      - source_labels: ["__meta_consul_service"]

        regex: "(.*)"

        target_label: "job"

        replacement: "$1"

      - source_labels: ["__meta_consul_node"]

        regex: "(.*)"

        target_label: "instance"

        replacement: "$1"

      - source_labels: ["__meta_consul_tags"]

        regex: ".*,(.*),.*"

        target_label: "host_group"

        replacement: "$1"

这段配置的解释如下:

  • 匹配Consul中service字段,并将其值赋值给label为job的目标

  • 匹配Consul中node字段,并将其值赋值给label为instance的目标

  • 匹配Consul中tag字段,以逗号分隔,并将其值赋值给label为host_group的目标

这样的话,小白就能通过Consul控制Prometheus内的目标采集节点了。这时候如果需要再进一步推进的话,我们就可以考虑打通公司自身的CMDB了,大概的思路也比较简单。有条件的同学可以在CMDB系统内直接与Consul交互来维护资产,没有条件的同学也可以通过脚本的方式定时同步CMDB数据到Consul,其基本的逻辑如下:


CMDB --------------> |

    |--> Script --> | Consul -->  Prometheus

总之我们终极的目标是任何资产的变更都能同步到Prometheus

<center>node-exporter实践</center>

node-exporter是Prome社区开源一个用于采集主机性能指标的服务,想必大家比较熟悉,小白这里就主要分别提一下关于node-exporter设置启动参数文本收集器

node-exporter的systemd配置如下:


[Unit]

Description=Node Exporter

After=network-online.target

[Service]

User=root

ExecStart=/usr/local/bin/node_exporter \

--collector.textfile.directory /var/lib/node_exporter/textfile_collector \

--collector.tcpstat \

--collector.processes  \

--collector.netclass.ignored-devices="^(cali.*|veth.*|cni.*|docker.*|flannel.*)$" \

--collector.netdev.ignored-devices="^(cali.*|veth.*|cni.*|docker.*|flannel.*)$" \

--collector.filesystem.ignored-fs-types="^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs|tmpfs)$" \

--collector.vmstat.fields="^(oom_kill|pgpg|pswp|pg.*fault).*" \

--web.disable-exporter-metrics

Restart=always

[Install]

WantedBy=multi-user.target

这里面可以看到小白在启动时分别打开了TCP连接状态、进程状态和系统OOM的采集,同时过滤掉了容器相关的网卡信息,以及过滤一些不重要的文件系统数据的采集。

另外关于文本收集器,小白将它理解为是一个文件版的PushGateway,它允许用户自定义一些文件后缀为.prom且满足metrics格式的文本,这样我们就能在http请求里面找到自定义的指标。对于普通用户,我们不用对于一些特定的小功能去开发一个exporter,而是通过crontab定时执行脚本的方式产生一些文本让node-exporter来帮助我们暴露指标。

小白举个实用的脚本例子,可以让大家更直观的看到文本收集器的作用

下面这个脚本用户监控磁盘的Uitl值,并通过node-exporter最终通过Prometheus采集


#!/bin/bash

iostat -x -k 1 2 -d |grep -E 'sd[a-z]' | sed "/(sd[a-z])/N;n;d;" | grep -E "sd[a-z]" | awk '{print $1 "\t" $NF}' \

    | while read dev utils; do

          echo "cloud_storage_disk_uitls{device=\"$dev\"} $utils";

      done  > /tmp/cloud_storage_disk_utils_info.prom

mv /tmp/cloud_storage_disk_utils_info.prom /var/lib/node_exporter/textfile_collector/cloud_storage_disk_utils_info.prom

最终我们就得到这样的数据

image.png

<center>PushGateway实践</center>

PushGateway主要是为了满足允许临时任务或者批处理任务需要将指标让Prometheus来采集的场景。这一块比较简单,小白只推荐一个比较好用,并且带ttl功能的镜像给大家


dmathai/prom-pushgateway-ttl:latest

我们在启动的时候通过参数--metric.timetolive=60s来指定metrics在pushgateway里的保留时间。这里有同学可能会问:"为什么要用ttl",这里小白就卖个关子,有兴趣的同学可以在自己的环境内对比两者的区别😃


<center>下期实践预告</center>

  • PromQL实践

  • Rules实践

  • Prometheus常见架构

  • Thanos实践

关于云原生小白

云原生小白的创号目的是将平日里离大家较远云原生应用以实用的角度展现出来,站在小白的角度来看待和使用云原生,并以每篇文章解决一个实际问题的出发点带领大家走进云原生世界。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352