云原生监控体系构建:Prometheus Operator与Grafana Loki在K8s环境下的日志监控一体化实践

 
更多

云原生监控体系构建:Prometheus Operator与Grafana Loki在K8s环境下的日志监控一体化实践

标签:云原生, Prometheus, Grafana, Kubernetes, 监控体系
简介:本文详细介绍如何在Kubernetes环境中构建完整的云原生监控体系,涵盖 Prometheus Operator 的服务监控能力与 Grafana Loki 的日志收集分析功能。通过部署、配置、集成和告警设置的全流程实践,提供一套可落地、可扩展的全栈监控解决方案,助力企业实现可观测性现代化。


一、引言:云原生时代的监控挑战

随着容器化与微服务架构的广泛应用,Kubernetes 已成为现代应用部署的事实标准。然而,系统的复杂性也随之上升:服务数量激增、动态调度频繁、日志分散于多个节点和命名空间,传统的监控手段已难以满足对系统可观测性的要求。

在云原生环境中,一个完整的监控体系必须覆盖三大支柱:

  • Metrics(指标):系统性能、资源使用率、应用健康状态等量化数据
  • Logs(日志):应用运行过程中的结构化或非结构化输出,用于故障排查
  • Traces(追踪):跨服务调用链的性能分析

本文聚焦于前两者——指标监控日志分析,通过 Prometheus Operator 实现自动化指标采集与告警管理,结合 Grafana Loki 构建轻量、高效的日志聚合系统,最终实现统一的可视化与告警平台。


二、技术选型解析

2.1 Prometheus Operator:Kubernetes 原生监控的利器

Prometheus 是云原生生态中最主流的监控系统,支持多维数据模型、强大的查询语言 PromQL,并与 Kubernetes 深度集成。

但原生 Prometheus 在 Kubernetes 中存在部署复杂、配置管理困难等问题。Prometheus Operator 由 CoreOS(现 Red Hat)开发,通过自定义资源定义(CRD)简化了 Prometheus 及其组件(如 Alertmanager、ServiceMonitor)的管理。

核心组件包括:

  • Prometheus CRD:声明式定义 Prometheus 实例
  • ServiceMonitor:自动发现并监控 Kubernetes 服务
  • PodMonitor:监控特定 Pod
  • Alertmanager:集中处理告警通知
  • PrometheusRule:定义告警和记录规则

优势:

  • 声明式配置,符合 GitOps 理念
  • 自动服务发现,无需手动配置 target
  • 支持 TLS、身份认证、RBAC 等安全机制
  • 易于扩展和多租户管理

2.2 Grafana Loki:专为日志设计的云原生日志系统

传统日志系统(如 ELK)通常将日志全文索引,导致存储成本高、查询慢。而 Grafana Loki 采用“日志标签索引 + 压缩日志内容”的设计理念,仅对日志的元数据(如 job, pod, namespace)建立索引,日志内容则以块形式压缩存储。

Loki 的核心优势:

  • 低成本:避免全文索引,存储开销仅为 Elasticsearch 的 1/10
  • 高可扩展性:支持水平扩展,适用于大规模集群
  • 与 Grafana 深度集成:使用 LogQL 查询语言,界面统一
  • 云原生友好:天然支持 Kubernetes 日志采集

Loki 架构组成:

  • Promtail:日志采集代理,运行在每个节点上,负责读取容器日志并发送给 Loki
  • Loki:日志存储与查询服务
  • Grafana:前端展示与查询入口

三、整体架构设计

我们构建的监控体系采用如下架构:

+------------------+       +---------------------+
|   Kubernetes     |       |     Grafana UI      |
|   Cluster        |<----->| (Metrics + Logs)    |
|                  |       +----------+----------+
| +--------------+ |                  |
| | Prometheus   | |                  |
| | (via Operator)| |                  |
| +------+-------+ |                  |
|        |         |                  |
| +------v-------+ |       +----------v----------+
| | Alertmanager | |       |      Loki           |
| +--------------+ |<----->| (Log Aggregation)   |
|                  |       +----------+----------+
| +--------------+ |                  |
| | Promtail     | |                  |
| | (DaemonSet)  | |                  |
| +--------------+ |                  |
+------------------+       +---------------------+

特点:

  • 所有组件均以 Helm Chart 或 YAML 部署,符合声明式管理
  • Prometheus Operator 负责指标采集与告警
  • Loki 负责日志收集与查询
  • Grafana 统一展示 Metrics 与 Logs
  • 告警通过 Alertmanager 统一推送至企业微信、钉钉、邮件等渠道

四、环境准备与基础依赖

4.1 前提条件

  • Kubernetes 集群(v1.20+)
  • kubectl 已配置并可访问集群
  • Helm 3 已安装
  • 存储类(StorageClass)已配置(用于持久化 Prometheus 和 Loki 数据)
  • 至少 4GB 内存可用(建议测试环境使用 8GB+)

4.2 添加 Helm 仓库

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update

五、部署 Prometheus Operator

5.1 安装 Prometheus Operator

使用 Helm 安装 kube-prometheus-stack,它集成了 Prometheus Operator、Prometheus、Alertmanager、Grafana 和常用 Dashboard。

helm install prometheus prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace \
  --version 55.0.1 \
  --set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false \
  --set prometheus.prometheusSpec.podMonitorSelectorNilUsesHelmValues=false

说明serviceMonitorSelectorNilUsesHelmValues=false 允许跨命名空间发现 ServiceMonitor。

5.2 验证部署状态

kubectl get pods -n monitoring

预期输出包含:

prometheus-prometheus-kube-prometheus-prometheus-0
alertmanager-prometheus-kube-prometheus-alertmanager-0
prometheus-kube-prometheus-operator-xxx
prometheus-kube-state-metrics-xxx
...

5.3 创建自定义 ServiceMonitor 示例

假设我们有一个名为 myapp 的应用,暴露在 8080 端口,路径为 /metrics

# servicemonitor-myapp.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: myapp-monitor
  namespace: monitoring
  labels:
    release: prometheus  # 必须匹配 Helm 安装时的 release 名称
spec:
  selector:
    matchLabels:
      app: myapp
  namespaceSelector:
    matchNames:
      - default
  endpoints:
    - port: http
      path: /metrics
      interval: 30s
      scheme: http

应用配置:

kubectl apply -f servicemonitor-myapp.yaml

Prometheus Operator 会自动将该服务加入 scrape targets。


六、部署 Grafana Loki 与 Promtail

6.1 安装 Loki Stack(含 Promtail)

使用 Helm 安装 loki-stack,包含 Loki 和 Promtail。

helm install loki grafana/loki-stack \
  --namespace logging \
  --create-namespace \
  --set loki.enabled=true \
  --set promtail.enabled=true \
  --set grafana.enabled=false  # 我们将使用 Prometheus 套件中的 Grafana

6.2 配置 Loki 数据持久化(可选)

编辑 values 文件或使用 --set 指定 PVC:

helm upgrade loki grafana/loki-stack \
  --namespace logging \
  --set loki.persistence.enabled=true \
  --set loki.persistence.storageClassName=standard \
  --set loki.persistence.size=10Gi

6.3 验证 Loki 与 Promtail

kubectl get pods -n logging

应看到:

loki-0
promtail-xxx

查看 Promtail 日志确认采集正常:

kubectl logs -n logging daemonset/promtail

七、集成 Grafana:统一可视化平台

7.1 访问 Grafana

kubectl port-forward -n monitoring svc/prometheus-grafana 3000:80

访问 http://localhost:3000,默认用户名 admin,密码可通过以下命令获取:

kubectl get secret -n monitoring prometheus-grafana -o jsonpath="{.data.admin-password}" | base64 -d

7.2 添加 Loki 数据源

  1. 登录 Grafana
  2. 进入 Configuration > Data Sources
  3. 点击 Add data source
  4. 选择 Loki
  5. 填写 URL:http://loki.logging.svc.cluster.local:3100
  6. 点击 Save & Test,应显示“Data source is working”

注意loki.logging.svc.cluster.local 是 Loki 服务的内部 DNS 名称。

7.3 使用 LogQL 查询日志

在 Grafana Explore 页面选择 Loki 数据源,输入 LogQL 查询:

{namespace="default", container="myapp"} |= "error"

支持的操作符:

  • |= "text":包含文本
  • != "text":不包含
  • |~ "regex":正则匹配
  • unpacked:解析 JSON 日志字段

示例:查询最近 5 分钟的错误日志

{job="promtail"} |= "error"
  | unwrap latency
  | latency > 500ms

八、配置告警规则与通知

8.1 创建 Prometheus 告警规则

通过 PrometheusRule CRD 定义自定义告警。

# alert-rules.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: custom-alert-rules
  namespace: monitoring
  labels:
    release: prometheus
spec:
  groups:
    - name: example-app-rules
      rules:
        - alert: HighRequestLatency
          expr: job:request_latency_seconds:mean5m{job="myapp"} > 1
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: "High latency for {{ $labels.job }}"
            description: "The average request latency for {{ $labels.job }} is above 1s (current value: {{ $value }}s)"

        - alert: PodCrashLooping
          expr: rate(kube_pod_container_status_restarts_total{namespace="default"}[5m]) > 0
          for: 2m
          labels:
            severity: critical
          annotations:
            summary: "Pod {{ $labels.pod }} is crash looping"
            description: "Pod {{ $labels.pod }} in namespace {{ $labels.namespace }} has restarted {{ $value }} times in the last 5 minutes."

应用规则:

kubectl apply -f alert-rules.yaml

8.2 配置 Alertmanager 通知渠道

编辑 Alertmanager 配置(可通过 values.yaml 覆盖或使用 Secret)。

示例:配置企业微信通知

# alertmanager.yaml
apiVersion: v1
kind: Secret
metadata:
  name: alertmanager-prometheus-kube-prometheus-alertmanager
  namespace: monitoring
stringData:
  alertmanager.yaml: |
    route:
      receiver: 'wechat'
      group_by: ['alertname', 'severity']
      group_wait: 30s
      group_interval: 5m
      repeat_interval: 1h

    receivers:
      - name: 'wechat'
        wechat_configs:
          - send_resolved: true
            corp_id: 'your-corp-id'
            api_secret: 'your-api-secret'
            to_party: '2'
            agent_id: 1000002
            message: '{{ template "wechat.default.message" . }}'

    templates:
    - '/etc/alertmanager/config/template/*.tmpl'

注意:Secret 名称必须与 Helm release 生成的 Alertmanager Secret 一致。

更新后重启 Alertmanager:

kubectl delete pod -n monitoring -l app.kubernetes.io/name=alertmanager

九、最佳实践与优化建议

9.1 Prometheus 性能调优

  • 合理设置 scrape interval:默认 30s,高频服务可设为 15s,低频可设为 1m
  • 启用远程写入(Remote Write):将数据写入 Thanos、Cortex 或 Mimir,实现长期存储与高可用
  • 使用 relabeling 减少标签膨胀
relabelingConfigs:
  - action: drop
    regex: 'very_high_cardinality_label_value'
    source_labels: [__meta_kubernetes_pod_label_app]

9.2 Loki 日志采集优化

  • 过滤无用日志:在 Promtail 配置中丢弃健康检查等噪音日志
pipelineStages:
  - match:
      selector: '{container="myapp"}'
      stage:
        drop:
          source: "log"
          expression: ".*health check.*"
  • 结构化日志处理:使用 dockercri 日志驱动,配合 json 格式输出
  • 启用日志压缩与分片:Loki 默认使用 boltdb-shipper + S3/GCS 存储,适合大规模场景

9.3 安全加固

  • 启用 TLS 通信:在 Prometheus 与 Exporter 之间使用 mTLS
  • RBAC 控制:限制 Prometheus 仅能访问指定命名空间的服务
  • 网络策略(NetworkPolicy):限制 Prometheus、Loki 之间的访问路径
  • Grafana 认证集成:对接 LDAP、OAuth2(如 GitLab、Google)

9.4 多集群监控方案

对于多 Kubernetes 集群,推荐架构:

  • 每个集群部署 Prometheus Operator + Promtail
  • 中心化部署 Thanos 或 Cortex,聚合多个 Prometheus 实例
  • Loki 可集中部署,或每个集群独立部署后通过 federation 查询

十、故障排查常见问题

问题 原因 解决方案
Prometheus 无法抓取目标 ServiceMonitor 标签不匹配 检查 matchLabelsrelease 标签
Loki 查询无数据 Promtail 未正确采集 检查 positions.yaml 和日志路径
Grafana 无法连接 Loki DNS 解析失败 使用 kubectl exec 测试 curl http://loki:3100/ready
告警未触发 表达式语法错误 在 Prometheus UI 中先测试 Expr
Alertmanager 无通知 配置未生效 检查 Secret 名称是否匹配,重启 Pod

十一、结语:构建可持续演进的监控体系

通过 Prometheus Operator 与 Grafana Loki 的集成,我们实现了 Kubernetes 环境下指标与日志的统一监控。这套方案具备以下价值:

  • 声明式管理:符合云原生 GitOps 流程
  • 低成本高效率:Loki 显著降低日志存储开销
  • 统一可视化:Grafana 提供 Metrics 与 Logs 联动分析能力
  • 可扩展性强:支持多集群、远程存储、自定义告警

未来可进一步集成 OpenTelemetry 实现分布式追踪,构建完整的 Observability 三位一体体系。

提示:建议将所有 YAML 配置纳入 Git 仓库,配合 ArgoCD 或 Flux 实现自动化部署与版本控制。


参考资料

  • Prometheus Operator GitHub
  • Grafana Loki 官方文档
  • kube-prometheus-stack Helm Chart
  • LogQL 文档
  • CNCF Observability Whitepaper

作者:云原生技术实践者
最后更新:2025年4月5日
适用场景:生产环境 Kubernetes 监控体系建设、DevOps 团队技术选型参考

打赏

本文固定链接: https://www.cxy163.net/archives/8371 | 绝缘体

该日志由 绝缘体.. 于 2020年01月24日 发表在 未分类 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: 云原生监控体系构建:Prometheus Operator与Grafana Loki在K8s环境下的日志监控一体化实践 | 绝缘体
关键字: , , , ,

云原生监控体系构建:Prometheus Operator与Grafana Loki在K8s环境下的日志监控一体化实践:等您坐沙发呢!

发表评论


快捷键:Ctrl+Enter