輕量級日誌系統Loki原理簡介和使用

前言

這篇文章應朋友的要求,讓寫一篇loki日誌系統,咱定責無旁貸 必定要好好寫 開幹!node

現實中的需求

公司的容器雲運行的應用或某一個節點出現了問題,解決的思路正則表達式

問題首先被prometheus監控算法

一、metric是來講明當前或者歷史達到了某個值spring

二、alert設置metric達到某個特定的基數觸發了告警docker

僅僅這些日誌是不可以解決問題的 還須要看下應用的日誌數據庫

k8s的基本單位是podvim

pod把日誌輸出到stdout和stderrcentos

當某個pod的內存變得很大api

觸發了咱們的alertspringboot

這個時候管理員

去頁面查詢確認是哪一個pod有問題

而後要確認pod內存變大的緣由

咱們還須要去查詢pod的日誌

若是沒有日誌系統

那麼咱們就須要到頁面或者使用命令進行查詢了

若是這個時候應用掛掉了 那麼就沒有辦法再查詢到相關日誌了

解決該需求可供選擇的方案

ELK

優點:

一、功能豐富,容許複雜的操做

劣勢:

一、主流的ELK(全文檢索)或者EFK比較重

二、ES複雜的搜索功能不少都用不上 規模複雜,資源佔用高,操做苦難

大多數查詢只關注必定時間範圍和一些簡單的參數(如host、service等)

三、Kibana和Grafana之間切換,影響用戶體驗

四、倒排索引的切分和共享的成本較高

Loki

一、最小化度量和日誌的切換成本

有助於減小異常事件的響應時間和提升用戶的體驗

二、在查詢語言的易操做性和複雜性之間能夠達到一個權衡

三、更具成本效益

loki組件介紹

Promtail

  • 用來將容器日誌發送到 Loki 或者 Grafana 服務上的日誌收集工具
  • 該工具主要包括髮現採集目標以及給日誌流添加上 Label 標籤 而後發送給 Loki
  • Promtail 的服務發現是基於 Prometheus 的服務發現機制實現的

Loki

  • 受 Prometheus 啓發的能夠水平擴展、高可用以及支持多租戶的日誌聚合系統
  • 使用了和 Prometheus 相同的服務發現機制,將標籤添加到日誌流中而不是構建全文索引
  • 從 Promtail 接收到的日誌和應用的 metrics 指標就具備相同的標籤集
  • 不只提供了更好的日誌和指標之間的上下文切換,還避免了對日誌進行全文索引

Grafana

  • 一個用於監控和可視化觀測的開源平臺
  • 支持很是豐富的數據源
  • 在 Loki 技術棧中它專門用來展現來自 Prometheus 和 Loki 等數據源的時間序列數據
  • 可進行查詢、可視化、報警等操做
  • 能夠用於建立、探索和共享數據 Dashboard
  • 鼓勵數據驅動

Loki架構

一、

Loki使用了和prometheus同樣的標籤來做爲索引

經過標籤既能夠查詢日誌的內容也能夠查詢到監控的數據

不但減小了兩種查詢之間的切換成本

也極大地下降了日誌索引的存儲

二、

Loki將使用與prometheus相同的服務發現和標籤從新標記庫編寫了pormtail

在k8s中promtail以daemonset方式運行在每一個節點中

經過kubernetes api等到日誌的正確元數據

並將它們發送到Loki

日誌的存儲架構

Distributor

一、

promtail收集日誌並將其發送給loki

Distributor就是第一個接收日誌的組件

Loki經過構建壓縮數據塊來實現批處理和壓縮數據

二、

組件ingester是一個有狀態的組件

負責構建和刷新chunck

當chunk達到必定的數量或者時間後

刷新到存儲中去

三、

每一個流的日誌對應一個ingester

當日志到達Distributor後

根據元數據和hash算法計算出應該到哪一個ingester上面

四、爲了冗餘和彈性,咱們將其複製n(默認狀況下爲3)次

Ingester

ingester接收到日誌並開始構建chunk

將日誌進行壓縮並附加到chunk上面

一旦chunk「填滿」(數據達到必定數量或者過了必定期限)

ingester將其刷新到數據庫

咱們對塊和索引使用單獨的數據庫

由於它們存儲的數據類型不一樣

刷新一個chunk以後

ingester而後建立一個新的空chunk並將新條目添加到該chunk中

Querier

一、 由Querier負責給定一個時間範圍和標籤選擇器

Querier查看索引以肯定哪些塊匹配

並經過greps將結果顯示出來

它還從Ingester獲取還沒有刷新的最新數據

二、

對於每一個查詢

一個查詢器將爲您顯示全部相關日誌

實現了查詢並行化

提供分佈式grep

即便是大型查詢也是足夠的

拓展性

  • Loki的索引存儲能夠是cassandra/bigtable/dynamodb
  • chuncks能夠是各類對象存儲
  • Querier和Distributor都是無狀態的組件
  • 對於ingester他雖然是有狀態的 但當新的節點加入或者減小整節點間的chunk會從新分配,以適應新的散列環

環境搭建(使用docker編排來實現)

安裝loki、promtail、grafana

  • 編寫docker編排配置文件

`vim docker-compose.yaml
version: "3"
networks:
loki:
services:
loki:
image: grafana/loki:1.5.0
ports:

  • "3100:3100"

command: -config.file=/etc/loki/local-config.yaml
networks:

  • loki

promtail:
image: grafana/promtail:1.5.0
volumes:

  • /var/log:/var/log

command: -config.file=/etc/promtail/docker-config.yaml
networks:

  • loki

grafana:
image: grafana/grafana:latest
ports:

  • "3000:3000"

networks:

    • loki`
    • 啓動安裝

    docker-compose up -d

    docker-compose ps

    • 訪問 grafana界面

    http://localhost:3000

    默認的登錄帳號admin/admin

    而後添加loki數據源

    url添加http://loki:3100/

    點擊Explore 選擇Loki 選擇相應的Label

    也能夠經過正則表達式來查詢日誌


    上面咱說完了 liki架構、實現原理及環境搭建過程

    如今就結束了嗎? No 那多顯得那麼出類拔萃呀 哈哈

    咱再結合一個具體的案例:

    使用loki對接下k8s下面的pod日誌

    let's go !

    具體過程以下:

    一、nacos爲註冊中心

    二、user和order爲2個springboot項目

    三、將user和order使用k8s部署

    四、訪問user接口 ,user訪問order 打印出日誌

    五、該日誌經過loki顯示出來

    1-4過程 我們以前的文章介紹過

    【實戰】K8S部署Nacos微服務

    朋友們若是本身想實際操練一遍的話能夠先看下這篇文章 使用k8s把項目部署起來

    部署的效果是

    nacos界面

    user和order服務都是k8s部署的

    這裏顯示的ip是k8s集羣下面的ip

    • 查看pod

    kubectl get pod

    • 查看service服務

    kubectl get svc

    2個都是nodePort類型的

    因此直接能夠訪問user服務的接口

    • 查看user 這個pod的日誌

    kubectl logs -f user-5776d4b64c-xsb5c

    如今loki有了,k8s pod 日誌也有了 下面咱看看loki和k8s如何關聯起來 達到經過loki查詢k8s的效果

    這裏只須要實現 promtail訪問到k8s日誌就能夠了

    promtail能夠直接訪問到k8s集羣內部的日誌

    也能夠將k8s集羣內部的日誌掛載到宿主機器上 而後再經過promtail訪問宿主機上的日誌

    這裏介紹4種實現方式

    我們分別實現下看看

    備註:這篇文章先簡單介紹下4種方式的思路,下篇文章我們針對這4種方式實現相應的效果

    方式1:將默認路徑 var/logs/*log 修改爲/var/log/container

    promtail能夠直接訪問到k8s集羣內部的日誌

    首先須要知道 k8s集羣下面的pod生成的日誌 默認目錄爲/var/log/containers

    一、咱先看看上面的promtail的docker-compose的配置命令

    `promtail:
    image: grafana/promtail:1.5.0
    volumes:

    • /var/log/container:/var/log/container

    command: -config.file=/etc/promtail/docker-config.yaml
    networks:

    • loki`

    其中 /etc/promtail/docker-config.yaml

    是訪問的docker內部的配置文件

    咱進去docker內部看下

    a、查看容器id

    docker ps |grep promtail

    b、進入容器

    docker exec -it 71cb21c2d0a3 sh

    看到了

    job=varlogs

    對應的日誌文件路徑是 /var/log/*log

    是否是有似曾相識的感受

    job對應varlogs

    filenames是對應的日誌路徑 /var/log/*log下面的日誌文件

    固然只是在promtail容器內部的

    在這裏只須要將/var/log/*log路徑修改爲 /var/log/container/*log 這個路徑就能夠了

    那如何修改呢

    咱們知道 這個配置文件是在容器內部的

    要想修改這個配置文件 須要在宿主機也弄一份 而後修改宿主機上的這份文件 而後替換掉docker種的這個配置便可

    重啓部署下docker-compose

    看到界面效果 發現問題了沒?

    一、路徑不是修改爲 /var/log/container/*log 這個了嗎 怎麼仍是 /var/log下面的日誌?

    二、選中一個日誌文件怎麼顯示不出來該文件的內容

    這2個問題放到下篇文章解答下吧 (先埋個坑 哈哈 我這麼這麼壞)

    方式2

    - replacement: /var/log/container/*.log

    這種方式也放到下篇文章再說吧

    方式3:將k8s集羣內部的日誌掛載到宿主機器上 而後再經過promtail訪問宿主機上的日誌

    這種方式 我試過了 也是達到指望效果的

    一、

    首先給springboot項目添加日誌文件輸出 我們這個示例中 以user項目爲例說下

    • 增長日誌文件

    • 日誌文件的輸出目錄是 /opt/logs

    二、將springboot項目生成docker鏡像 而後上傳到阿里的鏡像庫 而後在k8s user 配置文件中引用這個鏡像庫

    這些都在以前那篇文章中詳細說過了 這裏就再也不附述了

    這裏只須要不一樣點

    圈紅的地方是添加的映射

    volumeMounts 這個是將docker內部的/opt/logs目錄做爲掛載目錄

    volumes 這個是將宿主機中的

    /Users/mengfanxiao/Documents/third_software/loki/log

    目錄做爲映射目錄 即docker中的/opt/logs下面的日誌會映射到該目錄下

    須要注意:

    我一開始用的目錄是 /opt/logs 可是在個人mac環境中一直不能將docker中的日誌目錄映射到宿主機上 但 centos就能夠 這個緣由也放到下篇文章說下吧

    三、最後 只須要讓promtail訪問/Users/mengfanxiao/Documents/third_software/loki/log 這個目錄下面的日誌就好了

    至於怎麼讓promtail訪問 下篇再說吧

    方式4:promtail不是從/var/log目錄下讀取的日誌嘛 那麼我將user日誌輸出到/var/log 下面不就好了

    可能遇到的問題

    • 若是k8s狀態是start fail狀態 則service暴露NodePort的端口也訪問不了的狀況下 須要從新啓動下k8s

    啓動方式 能夠參考下我以前的那篇文章 K8S原理簡介及環境搭建

    本文使用 mdnice 排版

    相關文章
    相關標籤/搜索