云原生与SRE必备:可观测性核心解析及主流工具部署实战(Prometheus+Grafana+Loki+Jaeger全栈部署,SRE必备手册)
可观测性是云原生系统稳定运行的关键能力,通过指标、日志、链路追踪三支柱联动,实现系统状态的全面监控。文章解析了可观测性技术栈的四大环节:数据采集层(Prometheus、Fluentd等工具)、存储层(时序数据库、Elasticsearch等)、分析可视化层(Grafana、Kibana等)和告警响应层(Alertmanager等)。针对Kubernetes环境,详细介绍了Prometheus+G
在SRE(站点可靠性工程)与云原生领域,可观测性是保障系统稳定运行、降低故障影响范围的核心能力,其本质是让系统的运行状态“可感知、可分析”,打破系统黑盒,为故障定位、性能优化提供支撑。
在软件工程中,可观测性的准确定义是:仅通过系统的外部输出(日志、指标、链路数据),无需侵入系统内部修改代码,即可全面理解系统内部运行状态、定位故障根因、分析性能瓶颈的能力。简单来说,就是“不拆机器,也能知道机器里面在干嘛”。
一、可观测性核心技术栈解析
云原生场景下,可观测性技术栈围绕“数据采集→数据存储→数据分析→告警响应”四大核心环节构建,核心目标是实现“指标、日志、链路追踪”三支柱的联动,三者互补,缺一不可,共同构成系统可观测性的完整闭环。
1. 数据采集层:无侵入、全链路获取系统外部输出
数据采集层的核心目标是“无侵入、全链路”采集三类核心数据(指标、日志、链路),避免数据遗漏,为后续分析提供完整、准确的数据源,无需修改业务代码即可完成采集。
|
数据类型 |
采集工具 |
核心作用 |
|---|---|---|
|
指标(Metrics) |
- Node Exporter:采集服务器节点指标(CPU、内存、磁盘IO、网络带宽); - cAdvisor:采集容器指标(容器CPU使用率、内存占用、磁盘读写); - 业务SDK:如Spring Boot Actuator(Java)、Prometheus Client(Go),采集业务指标(接口QPS、错误率、耗时)。 |
将“系统/应用状态”量化为具体数值(如“CPU使用率80%”“接口QPS 1000”),支持趋势分析、阈值监控,快速感知系统异常。 |
|
日志(Logging) |
- Fluentd/Fluent Bit:轻量级日志采集代理,部署在每个节点/容器中,采集stdout日志或日志文件; - Filebeat:Elastic生态的日志采集工具,轻量高效,适合与ELK Stack联动部署。 |
记录系统/应用的“事件详情”(如“用户下单失败:数据库连接超时”),支持故障场景还原、异常原因追溯,补充指标无法覆盖的细节信息。 |
|
链路追踪(Tracing) |
- Jaeger Agent:部署在每个节点,接收应用SDK发送的链路数据,转发到Collector; - SkyWalking Agent:无侵入式探针(基于Java Agent技术),无需修改业务代码即可采集跨服务调用链路数据。 |
追踪跨服务调用路径(如“用户下单→订单服务→支付服务→库存服务”),定位链路中的性能瓶颈、调用失败点,解决分布式系统“调用链黑盒”问题。 |
2. 数据存储层:针对性存储,兼顾性能与成本
指标、日志、链路追踪三类数据的格式、查询需求、数据量差异极大,若采用“一刀切”的存储方式,会导致查询缓慢、存储成本过高。因此需针对性选择存储引擎,适配各类数据的特性。
|
数据类型 |
存储工具 |
选型逻辑 |
|---|---|---|
|
指标(Metrics) |
- Prometheus:时序数据库,适合存储“高频、小体积”的时序数据,支持PromQL灵活查询; - VictoriaMetrics:兼容Prometheus API,存储成本更低,适合大规模集群(TB级指标); - InfluxDB:轻量级时序数据库,部署简单,适合中小规模监控场景。 |
指标数据核心是“按时间戳排序”,需支持“按标签过滤”(如“筛选node=node-1的CPU指标”)和“聚合计算”(如“sum(接口QPS)”),优先保证查询效率和低存储成本。 |
|
日志(Logging) |
- Elasticsearch:分布式搜索引擎,适合存储“非结构化、需全文检索”的日志(如按关键词查询ERROR日志); - Loki:Grafana生态工具,采用“标签索引+原始日志分离”存储,成本比Elasticsearch低50%以上; - ClickHouse:列式存储数据库,适合日志的离线分析(如“统计近7天的错误日志分布”)。 |
日志数据核心是“检索效率”,需支持“快速定位某时间段、某服务的日志”,同时控制存储成本——日志体积通常是指标的10倍以上,需兼顾检索速度和成本优化。 |
|
链路追踪(Tracing) |
- Elasticsearch:适合中小规模链路数据(百万级Trace/天),部署简单,可与日志、指标联动; - Jaeger Storage:支持Cassandra/ScyllaDB,适合大规模链路数据(亿级Trace/天),扩展性强; - Pinpoint Storage:基于HBase,适合长周期链路存储(如30天以上),支持海量数据持久化。 |
链路数据核心是“按Trace ID查询完整链路”,需支持“关联Span的父子关系”(如“找到调用超时的子Span”)和“耗时排序”,根据链路数据量选择对应存储引擎,保证查询完整性。 |
3. 数据分析与可视化层:让数据“可读懂、可复用”
采集、存储数据的最终目的是“理解系统状态”,数据分析与可视化层的核心目标是将原始数据(raw数据)转化为人类可理解的信息,支持工程师快速定位故障、分析性能瓶颈,无需手动处理海量原始数据。
|
工具类型 |
代表工具 |
核心作用 |
|---|---|---|
|
指标可视化 |
- Grafana:可观测性领域“事实标准”可视化工具,支持Prometheus、Loki、Jaeger等所有主流数据源,可自定义仪表盘(如“K8s集群资源总览”“业务接口监控”); - Datadog:SaaS化监控平台,内置大量云原生场景仪表盘(如AWS EKS、Redis监控),无需手动配置。 |
将指标转化为折线图、饼图、仪表盘等直观形式,展示系统状态趋势(如“CPU使用率波动”“接口错误率飙升”),快速发现异常。 |
|
日志分析 |
- Kibana:Elastic生态的日志分析工具,支持日志检索、筛选、可视化(如“近1小时ERROR日志分布”),可关联指标数据; - Grafana Explore:与Loki联动,支持“按标签过滤日志+关键词检索”,无需切换工具,实现日志与指标的统一查看。 |
支持“快速定位故障日志”(如“筛选app=order-service的ERROR日志”)和“日志上下文查看”(如“查看某条错误日志的前后10行”),还原故障发生场景。 |
|
链路分析 |
- Jaeger UI:展示完整调用链路,支持“按服务、耗时、错误率筛选Trace”,可查看每个Span的耗时、请求参数、返回结果; - SkyWalking UI:整合“指标+链路”,支持“链路拓扑图”(直观展示服务依赖关系),可快速定位跨服务调用的瓶颈点。 |
解决分布式系统“调用链黑盒”问题,定位跨服务故障(如“支付服务调用超时导致订单失败”)和性能瓶颈(如“数据库查询耗时占比80%”)。 |
4. 告警与响应层:主动发现故障,实现故障自愈
可观测性的最终目标是“保障系统稳定”,告警与响应层的核心是“在故障影响用户前发现问题”,并触发自动化响应,降低SRE的人工干预成本,实现“早发现、早定位、早解决”。
|
工具类型 |
代表工具 |
核心作用 |
|---|---|---|
|
告警管理 |
- Alertmanager:Prometheus配套告警工具,支持“告警分组”(如同一服务的多个告警合并)、“路由”(如P0告警打电话,P1告警发钉钉)、“静默”(避免告警风暴); - PagerDuty:企业级事件响应平台,支持“on-call排班”(SRE轮班)、“告警升级”(10分钟未处理转上级),保障告警触达效率。 |
过滤无效告警(如抖动导致的瞬时告警),确保关键故障及时触达责任人,避免“告警泛滥”或“告警遗漏”。 |
|
自动化响应 |
- Prometheus Alertmanager Webhook:将告警触发Webhook(如调用Jenkins重启服务、调用API扩容Pod); - Opsgenie:支持“告警触发自动化流程”(如“CPU使用率超90%时自动扩容2个Pod”),与各类运维工具联动。 |
实现“故障自愈”,减少人工干预——SRE的核心目标之一就是“降低手动操作比例”,通过自动化响应缩短故障恢复时间(MTTR)。 |
二、主流可观测性工具部署实战(K8s环境)
以下为Prometheus+Grafana、Loki+Promtail、Jaeger三款核心工具的部署流程,提供Helm一键部署(适合快速测试)和YAML手动部署(适合生产环境自定义配置)两种方式,适配不同场景需求。
1. Prometheus及Grafana部署(指标监控+可视化核心)
Prometheus负责指标采集与存储,Grafana负责指标可视化,两者联动是云原生监控的基础组合,部署步骤如下:
方式一:Helm一键部署(快速测试,推荐新手)
# 1. 安装Helm(若未安装,参考K8s官方文档),添加Prometheus仓库并更新
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# 2. 创建监控专用命名空间
kubectl create namespace observability
# 3. 一键安装Prometheus Stack(包含Prometheus、Grafana、Alertmanager)
helm install prometheus-stack prometheus-community/kube-prometheus-stack -n observability
# 4. 检查安装状态,确保所有Pod正常运行
kubectl get pods -n observability
方式二:YAML手动部署(生产环境,支持自定义配置)
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
namespace: monitoring
data:
prometheus.yml: |
global:
scrape_interval: 15s # 全局采集间隔,默认15秒
scrape_configs:
# 采集K8s Pod指标(需Pod添加prometheus.io/scrape=true注解)
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: pod
# 采集Node Exporter指标(需提前部署Node Exporter)
- job_name: 'node-exporter'
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: monitoring;node-exporter;metrics
- source_labels: [__meta_kubernetes_node_name]
target_label: instance
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
namespace: monitoring
spec:
replicas: 1 # 生产环境可根据需求调整副本数,保证高可用
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
nodeSelector:
hardware-type: gpu # 可根据实际节点标签调整,无标签可删除
serviceAccountName: prometheus
imagePullSecrets:
- name: harbor-secret # 私有仓库密钥,无私有仓库可删除
containers:
- name: prometheus
image: prom/prometheus:v2.53.0 # 固定版本,避免兼容性问题
args:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus" # 指标存储路径
ports:
- containerPort: 9090
name: http
volumeMounts:
- name: config
mountPath: /etc/prometheus
- name: storage
mountPath: /prometheus
volumes:
- name: config
configMap:
name: prometheus-config
- name: storage
hostPath:
path: /mnt/data/prometheus # 主机存储路径,生产环境建议用PV/PVC
type: Directory
---
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: monitoring
spec:
type: NodePort # 测试环境用NodePort,生产环境建议用ClusterIP+Ingress
selector:
app: prometheus
ports:
- port: 9090
targetPort: 9090
nodePort: 30090 # 自定义NodePort端口,范围30000-32767
name: http
---
# 创建Prometheus服务账户及权限(K8s RBAC授权)
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups: [""]
resources: ["nodes", "nodes/proxy", "services", "endpoints", "pods"]
verbs: ["get", "list", "watch"] # 允许Prometheus查询K8s资源
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: monitoring
roleRef:
kind: ClusterRole
name: prometheus
apiGroup: rbac.authorization.k8s.io
5. Grafana在线访问配置(关键步骤)
部署完成后,需配置Grafana的外部访问方式,以下两种方式按需选择:
方法一:NodePort方式(快速测试,适合本地/测试环境)
# 创建Grafana NodePort服务,暴露外部访问端口
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: grafana-external
namespace: observability
spec:
type: NodePort
ports:
- name: web
port: 80
targetPort: 3000 # Grafana默认端口
nodePort: 30000 # 自定义外部访问端口
selector:
app.kubernetes.io/name: grafana # 匹配Helm部署的Grafana Pod标签
EOF
方法二:Ingress方式(生产环境推荐,支持域名访问、HTTPS)
# 需提前部署Ingress控制器(如Nginx Ingress),创建Ingress规则
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana-ingress
namespace: observability
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # 重写规则,避免路径匹配问题
spec:
rules:
- host: grafana.yourdomain.com # 替换为你的实际域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: prometheus-grafana # 注意:Helm部署的Grafana服务名固定为这个,需确认
port:
number: 80
EOF
6. 获取Grafana访问凭证
# 获取Grafana管理员用户名(默认是admin)
kubectl get secret -n observability prometheus-stack-grafana -o jsonpath='{.data.admin-user}' | base64 -d
# 获取Grafana管理员密码(自动生成,需解密)
kubectl get secret -n observability prometheus-stack-grafana -o jsonpath='{.data.admin-password}' | base64 -d
登录Grafana:根据配置的访问方式,访问对应地址(NodePort:http://<节点IP>:30000;Ingress:http://grafana.yourdomain.com),输入上述用户名和密码,即可查看预置的K8s、Prometheus相关仪表盘。
2. Loki和Promtail部署(日志采集与分析)
Loki是Grafana生态的日志存储工具,Promtail(默认包含在Loki Stack中)是日志采集工具,两者联动,配合Grafana实现日志的检索与可视化,部署步骤如下:
方式一:Helm一键部署
# 1. 添加Grafana仓库(已添加可跳过)
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
# 2. 创建日志专用命名空间
kubectl create namespace logging
# 3. 安装Loki Stack(包含Loki、Promtail),一键部署无需额外配置
helm upgrade --install loki grafana/loki-stack --namespace logging
# 4. 验证安装状态,确保Loki和Promtail Pod正常运行
kubectl get pods -n logging
方式二:YAML手动部署(生产环境自定义配置)
apiVersion: v1
kind: ConfigMap
metadata:
name: loki-config
namespace: monitoring
data:
loki.yaml: |
auth_enabled: false # 关闭认证,生产环境可根据需求开启
server:
http_listen_port: 3100 # Loki默认端口
common:
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks # 日志块存储路径
rules_directory: /loki/rules # 规则存储路径
replication_factor: 1 # 副本数,单节点部署设为1
ring:
instance_addr: 127.0.0.1
kvstore:
store: inmemory # 内存存储,生产环境建议用etcd
schema_config:
configs:
- from: 2020-10-24
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h # 索引周期,每天生成一个索引
limits_config:
reject_old_samples: true
reject_old_samples_max_age: 168h # 拒绝7天前的旧日志
allow_structured_metadata: false
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: loki
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: loki
template:
metadata:
labels:
app: loki
spec:
nodeSelector:
hardware-type: gpu # 可删除,无节点标签时生效
imagePullSecrets:
- name: harbor-secret # 私有仓库密钥,无则删除
containers:
- name: loki
image: grafana/loki:latest # 生产环境建议固定版本(如v3.0.0)
args:
- "-config.file=/etc/loki/loki.yaml"
ports:
- containerPort: 3100
name: http
volumeMounts:
- name: config
mountPath: /etc/loki
- name: storage
mountPath: /loki
volumes:
- name: config
configMap:
name: loki-config
- name: storage
hostPath:
path: /mnt/data/loki # 主机存储路径,生产环境建议用PV/PVC
type: Directory
---
apiVersion: v1
kind: Service
metadata:
name: loki
namespace: monitoring
spec:
selector:
app: loki
ports:
- port: 3100
targetPort: 3100
name: http # 暴露服务,供Grafana调用
部署完成后,在Grafana中添加Loki数据源(配置地址:http://loki.monitoring:3100),即可通过Grafana Explore检索日志。
3. Jaeger部署(链路追踪)
Jaeger是开源的分布式链路追踪工具,支持链路数据的采集、存储、分析与可视化,部署步骤如下(Helm一键部署,适合快速集成):
# 1. 创建链路追踪专用命名空间
kubectl create namespace tracing
# 2. 添加Jaeger仓库
helm repo add jaegertracing https://jaegertracing.github.io/helm-charts
helm repo update
# 3. 安装Jaeger,关闭Cassandra(用内存存储,适合测试;生产环境需配置持久化存储)
helm install jaeger jaegertracing/jaeger --namespace tracing --set provisionDataStore.cassandra=false
# 4. 验证安装状态,确保Jaeger相关Pod正常运行
kubectl get pods -n tracing
部署完成后,可通过NodePort/Ingress暴露Jaeger UI(默认端口16686),同时在业务应用中集成Jaeger Agent/SDK,即可采集链路数据,在Jaeger UI中查看完整调用链路。
三、总结
云原生场景下的可观测性,核心是通过“指标、日志、链路追踪”三支柱联动,围绕“采集→存储→分析→告警”四大环节,实现系统黑盒可视化。本文介绍的Prometheus+Grafana(指标监控)、Loki+Promtail(日志分析)、Jaeger(链路追踪),是目前云原生领域最主流、最易用的可观测性工具组合,可根据实际场景(中小规模/大规模、测试/生产)选择对应的部署方式。
对于SRE工程师而言,掌握可观测性技术栈,能有效降低故障定位成本、缩短故障恢复时间,是保障系统高可用的必备技能;对于云原生应用而言,良好的可观测性设计,能为应用的迭代优化、性能调优提供有力支撑。
后续将持续更新可观测性实战技巧,包括仪表盘自定义、告警规则优化、三支柱联动排查故障等内容,欢迎关注交流~
更多推荐



所有评论(0)