正文共: 2602字 预计阅读时间:7分钟
之前小白有讲到线上服务的可观察性在当下无论是运维还是研发的同学都是必须要掌握和了解的特性。对于当前服务可观察所要承担的功能,各大公司或社区也已基本形成共识,其主要也是围绕三个方向来提出要求:
当我们翻开CNCF的生态地图,发现最右边的Observability and Analysis正是给大家绘出了各类型服务观测的指导方案。
更多详情的地址 https://landscape.cncf.io/
在这里小白以日常工作中常使用到的应用来跟大家简单介绍CNCF里面的一些云原生
1. Monitoring 监控
Prometheus |--> Thanos --> Grafana
|--> AlertManager
CNCF已毕业的一个主要面向度量监控的时序数据库,能和Kubernetes、Consul等能深度结合为监控服务发现带来极大的便利性
CNCF沙箱内的一个面向Prometheus分布式架构的应用
数据可视化展示的前端,以其丰富的数据源和酷炫插件捕获了大批用户
2.Logging 日志
|--> Loki --> Grafana
Fluentd --> |--> Kafka --> Flume
|--> ElasticSearch --> Kibana
CNCF已毕业的一个由Ruby开发的日志采集客户端,具备良好的采集效率、灵活简单的配置和丰富的插件等特性,更以其与Kubernetes的紧密结合而获得市场快速的验证
GrafanaLab开源的一个类似Prometheus的日志聚合系统,以其轻量的设计和水平扩展,具备很高的成本收益而闻名
3.Tracing 追踪
Collector --> Jaeger --> Grafana
CNCF已毕业的一个分布式追踪系统,由Uber推出,因其简单友好的UI和与kubernetes、istio的结合,当下也聚集着大量的使用者
从今天开始,小白会按照上述的结构,并以云原生服务可观察性的这个区块内带大家初尝和体验,那么现在我们就由Prometheus开始吧
1
Prometheus架构
首先小白在正式使用前先看下Prometheus的组件及其大概架构
在图中小白可以了解到,Prometheus的监控数据来源主要分两种,直接从目标exporter中主动抓取数据,或者短期job上传给Pushgateway再由Prometheus主动抓取。其次Prometheus的数据以TSDB方式存储在本地磁盘,同时它也通过一些服务发现方式找到被监控的目标。最终Prometheus的呈现是以内置的UI或者集成Grafana以PromQL方式将数据可视化展示出来,当然用户也可以通过API方式自行绘图展示。
2
Prometheus部署
关于部署小白不想展开篇幅细说,这里小白仅简单分析下当下主流的两种部署方式以及建议
小白建议新手们还是需要花一段时间从Yaml部署开始熟悉,虽然过程比较复杂,不过现在关于Prometheus部署的资料很多,不会有太大的问题。
3
Prometheus实践 服务发现 Pod
小白以当前认为最实用的基于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
这段配置的解释如下:
如上规则我们大体就可以看出来,小白想要实现在Prometheus发现目标为容器的服务大体要满足spec.template.metadata.annotations里面的三个要素:
spec:
template:
metadata:
annotations:
prometheus.io/path: /metrics
prometheus.io/port: "9104"
prometheus.io/scrape: "true"
4
Prometheus实践 服务发现 Consul
有的同学可能会问小白:"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控制Prometheus内的目标采集节点了。这时候如果需要再进一步推进的话,我们就可以考虑打通公司自身的CMDB了,大概的思路也比较简单。有条件的同学可以在CMDB系统内直接与Consul交互来维护资产,没有条件的同学也可以通过脚本的方式定时同步CMDB数据到Consul,其基本的逻辑如下:
CMDB --------------> |
|--> Script --> | Consul --> Prometheus
总之我们终极的目标是任何资产的变更都能同步到Prometheus。
5
node-exporter实践
node-exporter是Prome社区开源一个用于采集主机性能指标的服务,想必大家比较熟悉,小白这里就主要分别提一下关于node-exporter设置启动参数和文本收集器
node-exporter的启动参数如下:
/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
这里面可以看到小白在启动时分别打开了TCP连接状态、进程状态和系统OOM的采集,同时过滤掉了容器相关的网卡信息,以及过滤一些不重要的文件系统数据的采集。
另外关于文本收集器,小白将它理解为是一个文件版的PushGateway,它允许用户自定义一些文件后缀为.prom且满足metrics格式的文本,这样我们就能在http请求里面找到自定义的指标。对于普通用户,我们不用对于一些特定的小功能去开发一个exporter,而是通过crontab定时执行脚本的方式产生一些文本让node-exporter来帮助我们暴露指标。小白举个实用的脚本例子,可以让大家更直观的看到文本收集器的作用,下面这个脚本主要用途为采集主机上磁盘的Uitl值
#!/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
最终我们就得到这样的数据
6
PushGateway实践
PushGateway主要是为了满足允许临时任务或者批处理任务需要将指标让Prometheus来采集的场景。这一块比较简单,小白只推荐一个比较好用,并且带ttl功能的镜像给大家
dmathai/prom-pushgateway-ttl:latest
我们在启动的时候通过参数--metric.timetolive=60s来指定metrics在pushgateway里的保留时间。这里有同学可能会问:"为什么要用ttl",这里小白就卖个关子,有兴趣的同学可以在自己的环境内对比两者的区别?
7
下期预告
--- end ---
关于云原生小白
云原生小白的创号目的是将平日里离大家较远云原生应用以实用的角度展现出来,站在小白的角度来看待和使用云原生,并以每篇文章解决一个实际问题的出发点带领大家走进云原生世界。