云原生监控体系构建: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.*"
  • 结构化日志处理:使用 docker 或 cri 日志驱动,配合 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 标签不匹配 检查 matchLabels 和 release 标签
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日 发表在 docker, express, git, go, kubernetes, 云计算, 后端框架, 开发工具, 编程语言 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: 云原生监控体系构建:Prometheus Operator与Grafana Loki在K8s环境下的日志监控一体化实践 | 绝缘体-小明哥的技术博客
关键字: , , , ,

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

发表评论


快捷键:Ctrl+Enter