Loki日志系統,比ELK輕量多了
圖片來自 包圖網
先看看結果有多輕量吧:
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