Lazy loaded image
k8s 日志/指标收集存储和展示体系
Words 9835Read Time 25 min
2025-11-2
2026-2-3
date
related_level
slug
k8s_prometheus_thanos_loki_grafana
type
Post
relate_date
summary
prometheus 收集指标至 thanos 存储,alloy 收集日志至 loki 存储,最终通过 grafana 进行展示
status
Published
tags
k8s
系统管理
可观测性
实用教程
最新推荐
必看精选
category
运维管理
last_updated
Feb 3, 2026 09:01 AM
是否已更新
orginal_page
是否推荐

配置 loki 为日志提供持久存储和 label 索引

  • 相对于 Elasticsearch 更轻量但由于没有全文索引会更依赖于 alloy 的 label 机制
  • helm 添加 grafana 官方 repo
    • helm repo add grafana https://grafana.github.io/helm-charts --force-update
loki 官方 helm 有三种部署模式
  • 这里为了高可用性选择微服务模式,相应地其他要设置 replica 为 0
    • 同时禁用部分组件
  • Single Binary Deployment
    • 可以参考裸机部署
  • Simple Scalable Deployment (SSD) Mode
  • Microservices Mode
配置 loki distribute value
参考资料
  • loki 组件介绍
    • https://grafana.com/docs/loki/latest/get-started/components/
    • YouTubeYouTubeAll the Components of Loki Explained | Grafana Labs
      • 视频模式的组件介绍
  • helm show values grafana/loki > ~/.config/helm/value/loki.default.yaml
    • loki.config 配置由 loki 项下的其他键值决定
  • cp ~/.config/helm/value/loki.default.yaml ~/.config/helm/value/loki.yaml
  • 原本的配置快 4000 行仅保留一部分但仍有 1000 行左右,谨慎打开
vim ~/.config/helm/value/loki.yaml
  • loki 的 auth 主要是用于租户的,添加认证需要在路由层面添加
  • 添加了一些自定义配置
    • ingester 和 distributor 改为 2 个,去掉了查询端的高可用配置
    • 使用外部 redis 替代 memcached,手动配置 results_cache 和 chunk_cache_config
  • 使用 longhorn pvc 作为存储卷存放 /var/loki
    • ingester, compactor, ruler, pattern_ingester
      • 需要同步配置对应项
    • 不要修改 claims 的 name: data
  • helm upgrade --install loki grafana/loki \ -n monitor --create-namespace \ -f ~/.config/helm/value/loki.yaml
查看运行情况
  • kubectl get -n monitor sts -l app.kubernetes.io/name=loki
  • kubectl get -n monitor deploy -l app.kubernetes.io/name=loki
  • kubectl get -n monitor sts/loki-ingester
  • kubectl describe -n monitor sts/loki-ingester
  • kubectl logs -n monitor sts/loki-ingester
配置 traefik 路由并添加 DNS 记录
  • kubectl describe -n monitor svc/loki-gateway
    • 已有 svc
vim ~/.config/k3s/ingressroute.loki.yaml
  • 如果需要添加认证可以在这里添加
  • kubectl describe -n kube-system deploy/traefik | grep namespace
    • 检查 traefik 是否已经为 monitor 命名空间提供路由
添加 DNS 记录到 /etc/hosts
  • 获取 traefik 的 external-ip
    • kubectl get svc -n kube-system traefik -o wide
  • kubectl logs -n kube-system deploy/traefik --since 1h | grep grafana
  • curl 测试 api
    • curl -vk https://loki.traefik.cluster.local/loki/api/v1/push
      • 正常应该返回 405 method not allow
 

配置 thanos 为 Prometheus 提供持久存储

参考资料
thanos 通过将 Prometheus 与对象存储结合,为 Prometheus 提供高可用性、长期存储和全局查询视图等高级功能
thanos 核心特性
  • 提供长期存储
  • 聚合多个 Prometheus 实例提供全局视图
  • 微服务架构实现高可用性
  • 数据压缩和下采样减少存储成本
thanos 核心组件
  • thanos sidecar 与现有 Prometheus 服务器集成,读取数据用于查询和/或上传到云存储
  • store gateway 从对象存储中检索历史数据,充当对象存储和 querier 之间的桥梁
  • compactor 对对象存储中的数据进行压缩,减少存储空间和提高查询性能
    • 两种压缩方式:对历史数据进行降采样,应用数据保留策略
  • receiver 接收来自 Prometheus 远程写入预写日志的数据,将数据上传到对象存储
  • ruler 根据 Thanos 中的数据评估录制和告警规则,实现自定义规则评估
  • querier 从多个 sidecar 聚合查询结果提供统一的查询 API,支持 PromQL 查询语言
  • query frontend 请求代理到 querier,缓存响应
    • 可选择按天拆分查询
  • 添加非官方 repo
    • helm repo add stevehipwell https://stevehipwell.github.io/helm-charts/ --force-update
创建 thanos sidecar s3 凭据 Secret
vim /tmp/objstore.yaml
  • 格式参考官方文章
    • https://thanos.io/tip/thanos/storage.md/#s3
  • 后续 Prometheus 也要用
  • kubectl create -f /tmp/objstore.yaml
  • kubectl get secret -n monitor thanos-objstore-secret -o yaml
  • kubectl get secret -n monitor thanos-objstore-secret -o jsonpath='{.data.config}' | base64 --decode
    • 查看解码后的情况
  • rm /tmp/objstore.yaml
配置 thanos value
  • helm show values stevehipwell/thanos > ~/.config/helm/value/thanos.default.yaml
  • cp ~/.config/helm/value/thanos.default.yaml ~/.config/helm/value/thanos.yaml
vim ~/.config/helm/value/thanos.yaml
  • 只保留了部分配置项
  • PVC 不能用现有 PVC
  • helm upgrade --install thanos stevehipwell/thanos \ -n monitor --create-namespace \ -f ~/.config/helm/value/thanos.yaml
查看运行情况
  • kubectl get -n monitor deploy -l app.kubernetes.io/name=thanos
  • kubectl get -n monitor sts -l app.kubernetes.io/name=thanos
  • kubectl logs -n monitor sts/thanos-receive-ingestor --since 12h
可选:配置外部 prometheus traefik 路由
  • kubectl describe -n kube-system deploy/traefik | grep namespace
    • 先检查 traefik 是否已经为 monitor 命名空间提供路由
vim ~/.config/k3s/ingressroute.thanos.receive.yaml
  • kubectl apply -f ~/.config/k3s/ingressroute.thanos.receive.yaml
添加 DNS 记录到 /etc/hosts
  • 获取 traefik 的 external-ip
    • kubectl get svc -n kube-system traefik -o wide
  • curl 测试
    • curl -vk https://thanos.traefik.cluster.local/api/v1/receive
 

配置 alloy 收集 pod 日志

  • promtail 后继者,相对而言比较全面,除日志之外还支持指标, traces 的收集和转发
    • ventor 相对轻量但对 otel 支持不太好
  • helm 添加 grafana 官方 repo
    • helm repo add grafana https://grafana.github.io/helm-charts --force-update
配置 alloy value
参考资料
  • helm show values grafana/alloy > ~/.config/helm/value/alloy.default.yaml
  • cp ~/.config/helm/value/alloy.default.yaml ~/.config/helm/value/alloy.yaml
配置 config.alloy 到 configmap
官方资料和样例
  • 也可以写在 values 里但不方便重载
  • loki 沿用微服务高可用配置
    • 如果是单一部署应为 loki:3100 而非 loki-gateway:80
  • 除了 pod log 还可以收集 event
  • 更多日志类型如 syslog, journald 参考相关文章的 alloy 部分
    • Linux 日志/指标聚合和展示系统
vim ~/.config/k3s/cm.alloy.config.yaml
  • 只设置了收集 alloy 和 loki 相关 pod log
  • relabel 部分参考以下项目
使用 discovery.kubernetes 时报错 fsnotify watcher: too many open files
参考资料
  • Grafana Labs Community ForumsGrafana Labs Community ForumsUsing discovery.kubernetes Alloy pushes a lot of failed to create fsnotify watcher: too many open files
在宿主机上设置 fs.inotify.max_user_watchesfs.inotify.max_user_instances
  • vim /etc/sysctl.d/99.k8s.fs.conf
    • sysctl -p /etc/sysctl.d/99.k8s.fs.conf
    • helm 安装或许可以在 .Values.global.podSecurityContext 里设置?没测试
    vim ~/.config/helm/value/alloy.yaml
    • 配置使用外部 configmap 作为配置文件
      • 启用 configreloader
    • 禁用报告
      • enableReporting: false
    • controller 选用 statefulset
      • 可以通过 clustering 横向拓展
      • daemonset 的话 alloy pod 重启时会丢失 WAL 日志数据,因为没有持久化
        • 每个节点上都会部署,方便收集节点指标,可以减少节点间延迟
        • daemonset 没法通过 clustering 横向拓展
    • helm upgrade --install alloy grafana/alloy \ -n monitor --create-namespace \ -f ~/.config/helm/value/alloy.yaml
    查看运行情况
    • kubectl get -n monitor sts -l app.kubernetes.io/name=alloy
    • kubectl logs -n monitor sts/alloy --since 12h
    • kubectl logs -n monitor sts/alloy --since 12h | grep "opened log stream"
      • 类似于 target=monitor/loki-** 的消息说明找到对应 pod 并开始抓取日志
     

    配置 kube-prometheus-stack 收集指标

    • helm 添加官方 repo
      • helm repo add prometheus https://prometheus-community.github.io/helm-charts --force-update
    • 假设已经额外配置了 thanos 做指标存储
    创建 thanos sidecar s3 凭据 Secret
    vim /tmp/objstore.yaml
    • 格式参考官方文章
      • https://thanos.io/tip/thanos/storage.md/#s3
    • 后续 Prometheus 也要用
    • kubectl create -f /tmp/objstore.yaml
    • kubectl get secret -n monitor thanos-objstore-secret -o yaml
    • kubectl get secret -n monitor thanos-objstore-secret -o jsonpath='{.data.config}' | base64 --decode
      • 查看解码后的情况
    • rm /tmp/objstore.yaml
    配置 kube-prometheus-stack 并部署
    • helm show values prometheus/kube-prometheus-stack > ~/.config/helm/value/kube-prometheus-stack.default.yaml
      • 包含 prometheus-operator, altermanager, grafana 等组件
    • cp ~/.config/helm/value/kube-prometheus-stack.default.yaml ~/.config/helm/value/kube-prometheus-stack.yaml
    vim ~/.config/helm/value/kube-prometheus-stack.yaml
    • 禁用 grafana 和 altermanager,grafana 后续使用 helm 自行管理
    通过 sidecar 与 thanos 集成,需要 helm thanos 启用 serviceMonitor 配置
    • --web.enable-admin-api 启用以支持获取元数据
    • --objstore 指定 s3 对象存储
    • --shipper.upload-compacted 上传压缩块
    • 如果需要远程写入可以配置 enableRemoteWriteReceiver
    • helm upgrade --install prometheus prometheus/kube-prometheus-stack \ -n monitor --create-namespace \ -f ~/.config/helm/value/kube-prometheus-stack.yaml
    查看运行情况
    • kubectl get -n monitor deploy,rs,ds -l app.kubernetes.io/instance=prometheus
    • kubectl get -n monitor sts -l app.kubernetes.io/name=prometheus
    • kubectl logs -n monitor deploy/prometheus-kube-prometheus-operator --since 12h
    operator 日志报错 Endpoints API 弃用,需要迁移
    • kubectl logs -n monitor -l app.kubernetes.io/component=prometheus-operator --since 1h
    如果是 helm 部署只需调整配置
    vim ~/.config/helm/value/kube-prometheus-stack.yaml
    • helm upgrade --install prometheus prometheus/kube-prometheus-stack \ -n monitor --create-namespace \ -f ~/.config/helm/value/kube-prometheus-stack.yaml
    查看现有角色是否已经有 endpointslices 权限
    • kubectl get clusterrole prometheus-operator -o yaml | grep -A10 -B5 endpointslices
    • kubectl get clusterrole prometheus -o yaml | grep -A10 -B5 endpointslices
    如果没有则需要创建 clusterrole 然后绑定到现有 sa
    vim ~/.config/k3s/rbac.prometheus.eps.yaml
    • 查看具体 sa 账户
      • kubectl get -n monitor sa -l app.kubernetes.io/instance=prometheus
    • kubectl apply -f ~/.config/k3s/rbac.prometheus.eps.yaml
    查看 kubelet endpoints 参数是否含 --kubelet-endpointslice=true 避免自动生成 endpointslice 导致冲突
    • kubectl describe -n kube-system endpoints/prometheus-kube-prometheus-kubelet | grep -A10 -B5 endpointslice
    检查 kubelet endpointslice 是否存在且已更新
    • kubectl get endpointslice -A | grep kubelet
    • kubectl describe -n kube-system endpointslice -l kubernetes.io/service-name=prometheus-kube-prometheus-kubelet
    调整指向 kubelet 的 ServiceMonitor 使用 EndpointSlice 而非 Endpoints 做服务发现
    通过 spec.serviceDiscoveryRole 来设置
    • 如果 ServiceMonitor 没设置则默认为 Prometheus/Prometheus agent 的对应值
    • kubectl get prometheus -n monitor prometheus-kube-prometheus-prometheus -o yaml | grep serviceDiscovery
    • kubectl get servicemonitor -n monitor | grep kube
    • kubectl get servicemonitor -n monitor prometheus-kube-prometheus-kubelet -o yaml | grep serviceDiscovery
    在 thanos querier 中添加 prometheus-operator 的 endpoint 以查询这部分指标数据
    如果使用的是 stevehipwell/thanos helm chart,配置项应为 additionalEndpoints
    更新 thanos 部署
    • helm upgrade --install thanos stevehipwell/thanos \ -n monitor --create-namespace \ -f ~/.config/helm/value/thanos.yaml
    • 查看 args 是否更新
      • kubectl describe -n monitor deploy/thanos-query | grep -A20 Args
    配置 prometheus webui traefik 路由并添加 DNS 记录
    • kubectl describe -n monitor svc/prometheus-kube-prometheus-prometheus
      • 已有 svc
    vim ~/.config/k3s/ingressroute.prometheus.yaml
    • kubectl describe -n kube-system deploy/traefik | grep namespace
      • 检查 traefik 是否已经为 monitor 命名空间提供路由
    添加 DNS 记录到 /etc/hosts
    • 获取 traefik 的 external-ip
      • kubectl get svc -n kube-system traefik -o wide
    • kubectl logs -n kube-system deploy/traefik --since 1h -f | grep prometheus
    • curl 测试首页
      • curl -vk https://prometheus.traefik.cluster.local
    • 不需要凭据所以最好配置 auth 中间件
    创建 ServiceMonitor 监控外部服务
    查看 prometheus 的 ServiceMonitorSelector
    • kubectl get prometheus -n monitor prometheus-kube-prometheus-prometheus -o yaml | grep -A5 -B2 serviceMonitorSelector
      • release: <name>
        • 和 helm 安装时配置的名称一致
    vim ~/.config/k3s/servicemonitor.openwrt.yaml
    • 需要 openwrt 安装对应 prometheus-node-exporter-lua 包
      • 具体参考相关文章 openwrt 系统管理
    • kubectl apply -f ~/.config/k3s/servicemonitor.openwrt.yaml
    • kubectl get -n monitor servicemonitor/ext-svc-servicemonitor -o yaml
    • kubectl logs -n monitor sts/prometheus-prometheus-kube-prometheus-prometheus --since 12h | grep config
      • 成功应该看到配置重载
     

    配置 Grafana 进行日志/指标/跟踪的展示以及预警

    • helm 添加 grafana 官方 repo
      • helm repo add grafana https://grafana.github.io/helm-charts --force-update
    创建 grafana 凭据 Secret
    • echo -n "admin passwd: " && read -s GRAFANA_ADMIN_PASSWORD; echo
    • echo -n "smtp passwd: " && read -s GRAFANA_SMTP_PASSWORD; echo
    • kubectl create secret generic grafana-passwd-secret \ --namespace=monitor \ --from-literal=admin-user="<admin-username>" \ --from-literal=admin-password=$GRAFANA_ADMIN_PASSWORD \ --from-literal=user="<stmp-username>" \ --from-literal=password="$GRAFANA_SMTP_PASSWORD"
    • kubectl get secret -n monitor grafana-passwd-secret -o yaml
    • kubectl get secret -n monitor grafana-passwd-secret -o jsonpath='{.data.password}' | base64 --decode
      • 查看解码后的情况
    • unset GRAFANA_ADMIN_PASSWORD GRAFANA_SMTP_PASSWORD
    配置 grafana value
    • 参考资料
    • helm show values grafana/grafana > ~/.config/helm/value/grafana.default.yaml
    • cp ~/.config/helm/value/grafana.default.yaml ~/.config/helm/value/grafana.yaml
    vim ~/.config/helm/value/grafana.yaml
    • 只设置了 grafana 本身的核心配置
      • 具体配置参考相关文章 Linux 日志聚合及展示系统
    • 可以通过 value 文件配置或者 sidecar 两者方式
      • 部分不能同时使用
      • 这里采用了 sidecar
      • sidecar 可以监控带有对应 label 的 config/secret 并动态加载对应配置
        • 缺点是额外的开销
    • helm upgrade --install grafana grafana/grafana \ -n monitor --create-namespace \ -f ~/.config/helm/value/grafana.yaml
    查看运行情况
    • kubectl get -n monitor deploy/grafana
    • kubectl describe -n monitor deploy/grafana
    • kubectl logs -n monitor deploy/grafana
    • kubectl logs -n monitor -l app.kubernetes.io/name=grafana
    配置 traefik 路由并添加 DNS 记录
    • kubectl describe -n monitor svc/grafana
      • 已有 svc
    vim ~/.config/k3s/ingressroute.grafana.yaml
    • kubectl describe -n kube-system deploy/traefik | grep namespace
      • 检查 traefik 是否已经为 monitor 命名空间提供路由
    添加 DNS 记录到 /etc/hosts
    • 获取 traefik 的 external-ip
      • kubectl get svc -n kube-system traefik -o wide
    • kubectl logs -n kube-system deploy/traefik --since 1h | grep grafana
    • curl 测试首页
      • curl -vk https://grafana.traefik.cluster.local
    • 通过之前配置的 admin 凭据登录
    grafana 数据源配置动态发现
    • 以 datasource 的 loki 为例
      • 具体格式和 grafana 配置文件是一样的
    • 可以是 configmap 也可以是 Secret
      • 需要配置 sidecar 部分的 resource: both
    vim ~/.config/k3s/cm.grafana.datasource.loki.yaml
    vim ~/.config/k3s/cm.grafana.datasource.thanos.yaml
    • 集群内 thanos 数据源
    vim ~/.config/k3s/secret.grafana.datasource.psql.yaml
    • kubectl apply -f ~/.config/k3s/cm.grafana.datasource.loki.yaml
    • kubectl apply -f ~/.config/k3s/cm.grafana.datasource.thanos.yaml
    • kubectl create -f ~/.config/k3s/cm.grafana.datasource.psql.yaml
    • kubectl get cm -n monitor loki-datasource -o yaml
    • kubectl get cm -n monitor prometheus-thanos-datasource -o yaml
    • kubectl get secret -n monitor psql-gitea-datasource -o yaml
    如果配错了需要配置 deleteDatasources 来删除,无法在 ui 中手动删除
    vim ~/.config/k3s/cm.grafana.datasource.delete.yaml
    • 配置组织 ID 和对应数据源名称
    • kubectl apply -f ~/.config/k3s/cm.grafana.datasource.delete.yaml
     
    上一篇
    Openstack 云操作系统及核心组件概述
    下一篇
    k3s 部署 longhorn 提供轻量级分布式块存储

    Comments
    Loading...