配置 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/
YouTubeAll the Components of Loki Explained | Grafana Labs
All the Components of Loki Explained | Grafana Labs
Here are all the components of Loki explained so that you can figure out how many instances of each you need for a resilient Loki deployment. Senior Developer Advocates Jay Clifford and Nicole van der Hoeven talk you through what each component does and which ones are optional. TIMESTAMPS 00:00 Intro 01:04 Distributors and hash rings 05:07 Ingesters 09:21 Query frontend 10:25 Query scheduler 10:56 Queriers 12:53 Index gateway 13:49 Compactor 14:39 Ruler Helpful links: (docs) Loki components: https://gra.fan/lokidocscomponents (repo) Loki on GitHub: https://gra.fan/lokirepo (docs) General Loki docs: https://gra.fan/lokidocs (video) The Zero to Hero: Loki playlist: https://gra.fan/lokiz2h ☁️ Grafana Cloud is the easiest way to get started with Grafana dashboards, metrics, logs, and traces. Our forever-free tier includes access to 10k metrics, 50GB logs, 50GB traces and more. We also have plans for every use case. Sign up: https://grafana.com/get/?src=yt&mdm=social&cnt=description ❓ Have a question that isn't related to this video? Check out the Official Grafana Community Forums and ask your question or find your answer: https://community.grafana.com/?src=yt&mdm=social&cnt=description ----- 👍 If you found this video useful, be sure to give it a thumbs up and subscribe to our channel for more helpful Grafana videos. 📱 Follow us for the latest and greatest on all things Grafana and our other OSS projects. X: https://twitter.com/grafana LinkedIn: https://www.linkedin.com/company/grafana-labs/mycompany Facebook: https://www.facebook.com/grafana #Grafana #Observability #loki #architecture #distributed #logs
- 视频模式的组件介绍
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
- 存储使用外部 garage s3 作为后端
- 使用 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
参考资料
Grafana LabsConfigure Grafana Alloy on Kubernetes | Grafana Alloy documentation
Configure Grafana Alloy on Kubernetes | Grafana Alloy documentation
Learn how to configure Grafana Alloy on Kubernetes
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
官方资料和样例
Grafana Labsdiscovery.kubernetes | Grafana Alloy documentation
discovery.kubernetes | Grafana Alloy documentation
Learn about discovery.kubernetes
Grafana Labsdiscovery.relabel | Grafana Alloy documentation
discovery.relabel | Grafana Alloy documentation
Learn about discovery.relabel
Grafana Labsloki.source.kubernetes | Grafana Alloy documentation
loki.source.kubernetes | Grafana Alloy documentation
Learn about loki.source.kubernetes
Grafana Labsloki.source.kubernetes_events | Grafana Alloy documentation
loki.source.kubernetes_events | Grafana Alloy documentation
Learn about loki.source.kubernetes_events
- 也可以写在 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 ForumsUsing discovery.kubernetes Alloy pushes a lot of failed to create fsnotify watcher: too many open files
Using discovery.kubernetes Alloy pushes a lot of failed to create fsnotify watcher: too many open files
Just switched to Grafana Alloy and did the setup for Kubernetes log collection as shown in the documentation. The logs (or at least most of it?) get collected and forwarded to Loki, but all containers constantly log failed to create fsnotify watcher: too many open files, including the Alloy containers. It’s a small 6-node cluster with less than 80 pods running on it. I installed Alloy using the latest Helm chart and the following config: alloy: configMap: # -- Create a new ConfigMap for...
在宿主机上设置 fs.inotify.max_user_watches 和 fs.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 配置
ThanosMetricsThanos Metrics
Thanos Metrics
Highly available Prometheus setup with long term storage capabilities.
- --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 serviceMonitorSelectorrelease: <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 dashboard 参考
配置 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
- Author:白鸟3
- URL:https://blog.kun2peng.top/operation/k8s_prometheus_thanos_loki_grafana
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
