Loki日誌系統(五)
本文是系列文章的最後一篇,著重介紹各個元件的部署和配置,最終配合grafana一起檢視日誌,示例中日誌來源為k8s叢集。
5. 叢集部署
完整的日誌系統包含以下幾個部分:
Loki
叢集
Promtail 日誌收集代理
Etcd/Consul 構成的
hash ring
底層依賴的儲存(不屬於本文內容)
本文所有元件均為二進位制本地部署,透過
systemd
進行統一管理,使用
Ansible
進行部署。
i. Loki
官方提供了
4
種安裝方式:
透過 Tanka 安裝
透過 Helm 安裝
透過Docker 或Docker Compose安裝
本地安裝
二進位制安裝方式較為簡單,詳細介紹一下配置檔案。
Loki
啟動時透過命令列傳入引數
-config。file
指定啟動的配置檔案,配置檔案的詳細格式請參考官網。本次測試使用的配置如下,為ansible語法:
# 當前loki執行的模式,支援的欄位為:
# all, querier, table-manager, ingester, distributor
target:
{{
target
}}
# 如果該欄位設定為true,必須將http請求的頭部欄位X-Scope-OrgID設定為OrgID
# 如果該欄位為false,OrgID 的值為 “fake”。
auth_enabled: true
# 指定各個服務的埠
server:
{%
if
target
==
“distributor”
%}
http_listen_port: 13100
grpc_listen_port: 19095
{%
elif
target
==
“ingester”
%}
http_listen_port: 23100
grpc_listen_port: 29095
{%
elif
target
==
“querier”
%}
http_listen_port: 33100
grpc_listen_port: 39095
{%
endif
%}
log_level: debug
# 此處配置ingester進行服務發現的註冊地址,本文使用etcd作為hash環的實現
ingester:
lifecycler:
ring:
kvstore:
store: etcd
etcd:
endpoints:
{%
for
etcd
in
ring_hosts。split
(
“,”
)
%}
-
{{
etcd
}}
{%
endfor
%}
replication_factor: 1
final_sleep: 0s
# 指定起服務時繫結的網絡卡
interface_names:
- “net2”
chunk_idle_period: 5m
chunk_retain_period: 30s
max_transfer_retries: 0
schema_config:
configs:
- from: 2020-08-01
# index 使用的儲存
store: indexStore
# chunks 使用的儲存
object_store: chunkStore
schema: v11
index:
prefix: index_
period: 168h
# 指定 index 和 chunks 可能使用的儲存配置,具體使用哪個由 schema_config配置決定
storage_config:
indexStore:
addresses:
{{
store_addresses
}}
chunkStore:
directory: /loki-
{{
lookup
(
‘pipe’
,
‘date +%Y%m%d’
)
}}
limits_config:
enforce_metric_name: false
reject_old_samples: true
reject_old_samples_max_age: 168h
chunk_store_config:
max_look_back_period: 0s
table_manager:
retention_deletes_enabled: false
retention_period: 0s
ii. Promtail
Promtail
是
Grafana
設計的日誌代理,負責收集日誌並將其傳送給
Loki
,目前支援兩種型別的日誌: 本地日誌檔案和
systemd journal
日誌。相較於一般的日誌代理,
Promtail
的工作流程如下:
目標發現
Promtail
採用了類似
Prometheus 的服務發現機制,使用 scrape_configs 進行配置, relabel_configs 可以對日誌流進行細粒度的控制。
日誌打標籤
支援複雜的過濾規則,
Promtail
不僅支援透過服務發現來新增標籤,而且可以根據日誌內容進行標籤的追加和替換。
將日誌傳送到
Loki
Promtail
在完成目標發現並正確設定標籤之後,會持續從目標讀取日誌。當讀取的資料達到一定量或者時間超過了設定值之後,
Promtail
會將日誌傳送到
Loki
。 在讀取日誌的時候,
Promtail
會在檔案中記錄已讀
offset
,這個檔案預設是
/var/log/positions。yaml
。即使
Promtail
崩潰重啟,也可以繼續讀取日誌。
a. 安裝
官方提供了幾種
Promtail
的安裝方法,簡單測試可以使用
Docker
安裝,拉起方式:
#!/bin/bash
#set -x
CURRENT_DIR
=
“
$(
cd
”
$(
dirname
“
${
BASH_SOURCE
[0]
}
”
)
“
&&
pwd
)
”
PREFIX
=
“grafana”
TAG
=
“latest”
docker run -d -v
${
CURRENT_DIR
}
:/mnt/config -v /var/log:/var/log -v /tmp:/tmp ——name promtail
${
PREFIX
}
/promtail:
${
TAG
}
-config。file
=
/mnt/config/promtail-config。yaml
b. 說明
Promtail
啟動時透過命令列傳入引數-config。file 指定啟動的配置檔案,配置檔案的詳細格式請參考官網。在配置檔案中,需要注意以下幾點:
標籤說明
以——開頭的標籤是內部標籤,通常來自動態服務發現,一旦
Relabel
完成,就會從標籤集中去除
——path——
是一個特殊標籤,
Promtail
使用該標籤確認從哪裡讀取日誌,支援萬用字元
Promtail
會為每一個從 ——
path——
中發現的日誌檔案,增加一個名為
filename
的標籤,用於確保日誌流的唯一性。標籤的值為日誌檔案的絕對路徑。
Pipelines
Pipeline
用於將日誌的內容,標籤和時間戳進行轉換。通常一個
Pipeline
會包含多個階段,在
Promtail
中共有四種階段型別:
分析階段
:分析並從日誌中抽取資料,取得的資料可以經由其他階段進一步處理利用。
docker: 使用標準Docker格式處理日誌。
cri: 使用標準CRI 格式處理日誌。
regex: 使用正則表示式處理日誌。
json: 使用JSON格式處理日誌。
2. 轉化階段
:對前一階段抽取的資料進行轉換
template: 使用 Go 模板對資料進行修改
3. 執行階段
:對前一階段抽取的資料執行如下步驟(可選):
timestamp: 為日誌設定時間戳。
output: 設定日誌內容
labels: 更新日誌的標籤集
metrics: 根據抽取的資料計算採集指標
tenant: 為日誌設定租戶ID。
4. 過濾階段
:根據條件應用不同的階段
match: 為滿足條件的日誌執行後續
pipeline
c. 配置
本次測試使用的配置如下:
#
Configures
Promtail‘s
behavior
as
an
HTTP
server
server:
http_listen_port:
9080
#
gRPC
server
listen
port
(
0
means
random
port)
grpc_listen_port:
0
log_level:
info
#
Configures
where
Promtail
will
save
a
file
indicating
how
far
it
has
read
into
a
file。
It
is
needed
for
when
Promtail
is
restarted
to
allow
it
to
continue
from
where
it
left
off。
positions:
filename:
/tmp/positions。yaml
#
Configures
how
Promtail
connects
to
an
instance
of
Loki
clients:
-
url:
http://ip:port/loki/api/v
1
/push
#
Static
labels
to
add
to
all
logs
being
sent
to
Loki。
external_labels:
host:
ip
#
Configures
how
Promtail
can
scrape
logs
from
a
series
of
targets
using
a
specified
discovery
method
scrape_configs:
-
job_name:
cube
static_configs:
-
targets:
-
localhost
labels:
__path__:
/var/log/pods/*/*/*。log
pipeline_stages:
-
regex:
source:
filename
expression:
“(?:pods)/(?P
-
labels:
namespace:
pod:
container:
-
tenant:
source:
namespace
-
regex:
expression:
“^(?s)(?P
-
timestamp:
source:
time
format:
RFC
3339
Nano
-
output:
source:
content
relabel_configs:
在上述配置中,
Promtail
從目錄
/var/log/pods/
獲取匹配的日誌,並透過
pipeline
對日誌進行進一步的處理:
regex
。
regex
必須符合Go RE2 標準
,從 filename 中提取欄位。
labels
。 為日誌打上前一步取得的
namespace
、
pod
和
container
標籤。
tenant
。 將請求頭部的
X-Scope-OrgID
的值設定為
namespace
的值。
regex
。 進一步處理日誌,
k8s
產生的日誌格式:
2020-04-29T21:58:25。506148921+08:00 stdout F [ 5] 103。00-104。00 sec 273 MBytes 2。29 Gbits/sec
經過處理後,會得到如下值:
time: 2020-04-29T21:58:25。506148921+08:00
stream
:
stdout
flag
:
F
content
:
[ 5] 103。00-104。00 sec 273 MBytes 2。29 Gbits/sec
timestamp
。 根據上一步的
time
設定時間戳,如果沒有設定該階段,預設設定為日誌採集時間。
output
。 僅將
content
作為日誌內容傳送到
Loki
。
iii. Etcd
#
[
member
]
ETCD_NAME=
{
{
hostvars[inventory_hostname]。name
}
}
ETCD_DATA_DIR=
“/var/lib/etcd/default。etcd”
ETCD_LISTEN_PEER_URLS=
“http://{{ inventory_hostname }}:2380”
ETCD_LISTEN_CLIENT_URLS=
“http://{{ inventory_hostname }}:2379,http://127。0。0。1:2379”
ETCD_MAX_SNAPSHOTS=
“5”
ETCD_MAX_WALS=
“5”
#
[
cluster
]
ETCD_INITIAL_ADVERTISE_PEER_URLS=
“http://{{ inventory_hostname }}:2380”
{
%
set
etcd_list
=
[]
%
}
{
%
for
host
in
groups。etcd
%
}
{
%-
set
etcd_host
=
’{0
}
=http://
{
1
}
:
22380
‘。format(hostvars
[
host
]
。name,
host)
-%}
{
{-
etcd_list。append(etcd_host)
-
}
}
{
%-
endfor
-%
}
ETCD_INITIAL_CLUSTER=
“{{ etcd_list | join(’,‘) }}”
ETCD_INITIAL_CLUSTER_STATE=
“new”
ETCD_INITIAL_CLUSTER_TOKEN=
“etcd-cluster”
ETCD_ADVERTISE_CLIENT_URLS=
“http://{{ inventory_hostname }}:2379,http://127。0。0。1:2379”
叢集正常啟動之後,
ingester
會在
etcd
註冊自身,可透過如下命令檢視:
$
ETCDCTL_API
=
3
etcdctl ——endpoints
=
ip1:2379,ip2:2379 get
“collectors/ring”
6. 使用
安裝完成後,訪問
Grafana
。
選擇新增資料來源,在資料來源列表中選擇
Loki
,並配置源地址。如果
Loki
開啟了多租戶模式,此處需要設定
HTTP Header
。
2。 儲存完成後,切換到
Grafana
左側區域的
Explore
,即可進入到
Loki
的頁面:
3。 點選
Log labels
,會顯示當前系統採集的日誌標籤,可以根據這些標籤進行日誌的過濾查詢
下一篇:黃金時代裡最喜歡的兩段