Grafana Loki 是一個日志聚合工具,它是功能齊全的日志堆棧的核心。
圖片來自 包圖網
先看看結果有多輕量吧:
Loki 是一個為有效保存日志數據而優化的數據存儲。日志數據的高效索引將 Loki 與其他日志系統區分開來。與其他日志系統不同,Loki 索引是根據標簽構建的,原始日志消息未編入索引。
代理(也稱為客戶端)獲取日志,將日志轉換為流,然后通過 HTTP API 將流推送到 Loki。Promtail 代理專為 Loki 安裝而設計,但許多其他代理與 Loki 無縫集成。
Loki 特點如下:
用于索引日志的高效內存使用:通過在一組標簽上建立索引,索引可以明顯小于其他日志聚合產品。更少的內存使得操作成本更低。
多租戶:Loki 允許多個租戶使用單個 Loki 實例。不同租戶的數據與其他租戶完全隔離。通過在代理中分配租戶 ID 來配置多租戶。
LogQL,Loki 的查詢語言:Prometheus 查詢語言 PromQL 的用戶會發現 LogQL 熟悉且靈活,可用于生成針對日志的查詢。該語言還有助于從日志數據中生成指標,這是一項遠遠超出日志聚合的強大功能。
可擴展性:Loki 在小范圍內運行良好。在單進程模式下,所有需要的微服務都在一個進程中運行。
單進程模式非常適合測試 Loki、在本地運行或小規模運行。Loki 還旨在為大規模安裝進行橫向擴展。
Loki 的每個微服務組件都可以分解為單獨的進程,并且配置允許對組件進行單獨擴展。
靈活性:許多代理(客戶端)都有插件支持。這允許當前的可觀察性結構將 Loki 添加為他們的日志聚合工具,而無需切換可觀察性堆棧的現有部分。
Grafana 集成:Loki 與 Grafana 無縫集成,提供完整的可觀察性堆棧。
Loki/Promtail/Grafana vs EFK
EFK(Elasticsearch、Fluentd、Kibana)堆棧用于從各種來源攝取、可視化和查詢日志。
Elasticsearch 中的數據作為非結構化 JSON 對象存儲在磁盤上。每個對象的鍵和每個鍵的內容都被索引。
然后可以使用 JSON 對象定義查詢(稱為查詢 DSL)或通過 Lucene 查詢語言查詢數據。
相比之下,單二進制模式的 Loki 可以將數據存儲在磁盤上,但在水平可擴展模式下,數據存儲在云存儲系統中,例如 S3、GCS 或 Cassandra。
日志以純文本形式存儲,并標有一組標簽名稱和值,其中僅索引標簽對。這種權衡使得操作比完整索引更便宜,并允許開發人員積極地從他們的應用程序中登錄。使用LogQL查詢 Loki 中的日志。
然而,由于這種設計權衡,基于內容(即日志行中的文本)過濾的 LogQL 查詢需要加載搜索窗口中與查詢中定義的標簽匹配的所有塊。
Fluentd 通常用于收集日志并將其轉發到 Elasticsearch。Fluentd 被稱為數據收集器,它可以從許多來源攝取日志,對其進行處理,并將其轉發到一個或多個目標。
相比之下,Promtail 的用例是專門為 Loki 量身定制的。它的主要操作模式是發現存儲在磁盤上的日志文件,并將它們與一組標簽相關聯地轉發給 Loki。
Promtail 可以為與 Promtail 運行在同一節點上的 Kubernetes pod 進行服務發現,充當容器邊車或 Docker 日志驅動程序,從指定文件夾讀取日志,并跟蹤 systemd 日志。
Loki 通過一組標簽對表示日志的方式類似于 Prometheus表示指標的方式。
當與 Prometheus 一起部署在環境中時,由于使用相同的服務發現機制,Promtail 的日志通常具有與應用程序指標相同的標簽。
具有相同標簽的日志和指標使用戶能夠在指標和日志之間無縫切換上下文,幫助進行根本原因分析。
Kibana 用于可視化和搜索 Elasticsearch 數據,并且在對這些數據進行分析方面非常強大。
Kibana 提供了許多可視化工具來進行數據分析,例如位置圖、用于異常檢測的機器學習以及用于發現數據關系的圖形。警報可以配置為在發生意外情況時通知用戶。
相比之下,Grafana 專門針對來自 Prometheus 和 Loki 等來源的時間序列數據量身定制。
儀表板可以設置為可視化指標(即將提供日志支持),并且可以使用瀏覽視圖對您的數據進行臨時查詢。與 Kibana 一樣,Grafana 支持根據您的指標發出警報。
架構圖:
收集日志的架構圖:
一套輕量級日志收集方案:
- Promtail:日志收集工具
- Loki:日志聚合系統
- Grafana:可視化工具
部署 Loki
官網地址:
https://github.com/grafana/loki
①loki
編輯 loki 配置文件:loki-config.yaml,參考:
https://grafana.com/docs/loki/latest/configuration/examples/
https://grafana.com/docs/loki/latest/installation/docker/
---
apiVersion: v1
kind: ConfigMap
metadata:
name: loki-config
labels:
name: loki
data:
loki-config.yaml: |-
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096
ingester:
lifecycler:
address: 127.0.0.1
ring:
kvstore:
store: inmemory
replication_factor: 1
final_sleep: 0s
chunk_idle_period: 5m
chunk_retain_period: 30s
chunk_target_size: 1048576 # Loki will attempt to build chunks up to 1.5MB, flushing first if chunk_idle_period or max_chunk_age is reached first
max_transfer_retries: 0 # Chunk transfers disabled
schema_config:
configs:
- from: 2021-08-18
store: boltdb
object_store: filesystem
schema: v11
index:
prefix: index_
period: 168h
storage_config:
boltdb:
directory: /tmp/loki/index
filesystem:
directory: /tmp/loki/chunks
limits_config:
enforce_metric_name: false
reject_old_samples: true
reject_old_samples_max_age: 168h
ingestion_rate_mb: 15
chunk_store_config:
max_look_back_period: 0s
table_manager:
retention_deletes_enabled: false
retention_period: 0s
kubectl Apply -f loki-config.yaml
創建 Service 和 StatefulSet,loki,.yaml:
----
apiVersion: v1
kind: Service
metadata:
name: loki
annotations:
k8s.kuboard.cn/displayName: loki
k8s.kuboard.cn/workload: loki
labels:
name: loki
spec:
ports:
- name: http
port: 3100
protocol: TCP
targetPort: 3100
selector:
name: loki
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: loki
spec:
serviceName: loki
selector:
matchLabels:
name: loki
template:
metadata:
labels:
name: loki
spec:
volumes:
- name: loki-config
configMap:
#defaultMode: 0640
name: loki-config
containers:
- name: loki
#image: grafana/loki:2.3.0
image: grafana/loki:master
args:
- -config.file=/etc/loki/loki-config.yaml
ports:
- containerPort: 3100
name: loki
protocol: TCP
volumeMounts:
- name: loki-config
mountPath: /etc/loki/
readOnly: true
執行命令創建:
kubectl apply -f loki.yaml
②grafana
根據自己時間情可對存儲那塊進行更改,不改的話是 emptyDir,你懂的。賬號密碼為 admin/admin123.可自行修改。
apiVersion: v1
kind: Service
metadata:
name: grafana
labels:
k8s-app: grafana
spec:
type: NodePort
ports:
- name: http
port: 3000
targetPort: 3000
selector:
k8s-app: grafana
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana
labels:
k8s-app: grafana
spec:
selector:
matchLabels:
k8s-app: grafana
template:
metadata:
labels:
k8s-app: grafana
spec:
# initContainers: ## 初始化容器,用于修改掛載的存儲的文件夾歸屬組與歸屬用戶
# - name: init-file
# image: busybox:1.28
# imagePullPolicy: IfNotPresent
# securityContext:
# runAsUser: 0
# command: ['chown', '-R', "472:0", "/var/lib/grafana"]
# volumeMounts:
# - name: data
# mountPath: /var/lib/grafana
# subPath: grafana
containers:
- name: grafana ## Grafana 容器
#image: grafana/grafana
image: grafana/grafana:7.4.3
#securityContext: ## 容器安全策略,設置運行容器使用的歸屬組與用戶
# fsGroup: 0
# runAsUser: 472
ports:
- name: http
containerPort: 3000
protocol: TCP
env: ## 配置環境變量,設置 Grafana 的默認管理員用戶名/密碼
- name: GF_SECURITY_ADMIN_USER
value: "admin"
- name: GF_SECURITY_ADMIN_PASSword
value: "admin123"
readinessProbe: ## 就緒探針
failureThreshold: 10
httpGet:
path: /api/health
port: 3000
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 30
livenessProbe: ## 存活探針
failureThreshold: 10
httpGet:
path: /api/health
port: 3000
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
volumeMounts: ## 容器掛載配置
- name: data
mountPath: /var/lib/grafana
subPath: grafana
volumes: ## 共享存儲掛載配置
- name: data
emptyDir: {}
#persistentVolumeClaim:
# claimName: grafana ## 指定使用的 PVC
③promtail
應用結合 promtail,進行日志收集。這里使用 Sidecar 模式。一個 pod 中跑兩個容器,一個為業務容器,一個為 promtail,兩個容器掛載同一個存儲目錄,promtail 即可收集日志。
編輯 promtail-config.yaml,可根據不同業務設置標簽。參考:
https://grafana.com/docs/loki/latest/clients/promtail/installation/
---
apiVersion: v1
kind: ConfigMap
metadata:
name: promtail-config
labels:
k8s-app: promtail
data:
promtail.yaml: |-
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: ./positions.yaml # This location needs to be writeable by Promtail.
#filename: /tmp/positions.yaml # This location needs to be writeable by Promtail.
client:
url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system
#- job_name: busybox
static_configs:
- targets:
- localhost
labels:
job: varlog #自定義
host: busybox #自定義
__path__: /tmp/*log 收集日志的目錄
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: promtail-deployment
spec:
replicas: 2
selector:
matchLabels:
name: promtail
template:
metadata:
labels:
name: promtail
spec:
volumes:
- name: log
emptyDir: {}
- name: promtail-config
configMap:
name: promtail-config
containers:
- name: promtail
image: grafana/promtail:master
imagePullPolicy: IfNotPresent
args:
- -config.file=/etc/promtail/promtail.yaml
volumeMounts:
- name: log
mountPath: /tmp/
- name: promtail-config
mountPath: /etc/promtail/
- name: busybox
image: centos:7
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- "while : ; do echo '--- promtail log test ---' `date` && echo '--- promtail log test ---' `date` >> /tmp/healthy.log && sleep 3 ; done "
volumeMounts:
- name: log
mountPath: /tmp/
配置 grafana 并查看日志
查看 grafana 的 nodeport 端口:
kubectl get svc
瀏覽器輸入 Node IP +上邊看到的 port 打開 grafana 頁面:
輸入賬號密碼進行登陸 admin admin123。
配置數據源:
找到 loki,然后 url 處寫上 loki 的 service name 和端口號,即就是 http://locki:3100。
然后點擊頁面低下 "Save && test " 按鈕:
查看日志:
選擇 host 或者 job 來看不同業務的日志:
即可看到日志內容:
至此,Loki+Promtail+Grafana 收集日志方案收工。
作者:Sunzz
編輯:陶家龍
出處:
cnblogs.com/Sunzz/p/15190702.html