之前有简单的提到 loki 的部署和基本的一些使用,能支持用户最基本的在 k8s 中的部署和使用,非常简单。但是因为很多配置是默认的以至于并不满足需求,所以这里就来更新一下一些自定义配置的更改以便更好的支持当前的使用。下面举例包括:
下面以 helm 默认部署 loki 之后为例进行修改
我们最常见的一个需求就是只保留固定天数的日志,因为由于日志量大,所以过期的日志不做保留,以避免磁盘占用量过大。那么在 loki 里面配置也很简单。
官方文档位置:https://grafana.com/docs/loki/latest/operations/storage/retention/
如果你使用 helm 进行部署,那么 loki 的配置文件位置是在 Secrets 下的,名称默认为 loki。
chunk_store_config:
max_look_back_period: 24h
limits_config:
enforce_metric_name: false
reject_old_samples: true
reject_old_samples_max_age: 168h
schema_config:
configs:
- from: "2020-10-24"
index:
period: 24h
prefix: index_
chunks:
period: 24h
prefix: chunk_
object_store: filesystem
schema: v11
store: boltdb-shipper
storage_config:
boltdb_shipper:
active_index_directory: /data/loki/boltdb-shipper-active
cache_location: /data/loki/boltdb-shipper-cache
cache_ttl: 24h
shared_store: filesystem
filesystem:
directory: /data/loki/chunks
table_manager:
retention_deletes_enabled: true
retention_period: 24h
最重要的配置就是 table_manager 其中的 24h 就表示只保存 24 小时的日志
这里第一个坑就出现了,注意 loki 需要配置的保留时间必须为 24 小时的倍数,比如你配置 1h 或者 23h 都是会报错的,详情问题见:https://cloud.tencent.com/developer/article/1668946
其他的配置中:max_look_back_period 指的是最大的查询时间,reject_old_samples_max_age 是拒绝采样的时间,还有 chunk 以多少小时分隔等,比较好理解,详情见文档即可。
如果想知道删除是否生效(很多人都以为删除配置了之后好像看不出来到底是否有效),可以过一段时间后直接在 loki 的日志中搜索:{app=”loki”} |= “retention” ,当出现 file has exceeded the retention period, removing it 则证明删除配置生效,表示当前检测到了过期的日志主动将它删除了
当我们的日志收集上来之后,loki 会进行存储和压缩,变成一个个 chunk 那么默认的情况下,以 helm 部署的话,给到的存储是 volumes 挂到了 emptyDir
第二个坑就是,如果默认以 helm 部署 loki 不做修改配置,那么只要 loki 重启那么之前收集的日志就全都会被删除
故你只需要将存储位置找个 volumes 挂载就可以了,这里我使用的是我指定的一个 pvc,这里就不赘述这个 pvc 和 pv 的创建了。
在 loki 的 statefulset 的配置中修改对应位置
- name: storage
persistentVolumeClaim:
claimName: persistent-volume-loki-claim
这里还有一个坑,因为挂载的 volume 的路径权限不同,可能出现没有权限写入的问题,故可能需要在配置中指定 root 权限或者根据具体权限进行调整,详情问题见:https://github.com/grafana/loki/issues/2018
securityContext:
runAsGroup: 0
runAsNonRoot: false
runAsUser: 0
当然存储不一定要存文件,loki 还支持存储到别的地方如:Cassandra、GCS 等 https://grafana.com/docs/loki/latest/storage/
使用 helm 部署 loki 的时候,默认会部署 loki-promtail 的 daemonset 然后利用 promail 的 k8s 发现机制去发现所有 pod 对应的日志,从而进行收集。这样收集非常方便,在于你不需要对原有的项目部署做任何的处理,但是,因为采集的是 pod 的日志,那么如果有一些项目只是将日志输出到文件中如何进行采集呢?
在收集 k8s 应用日志的时候,官方给出了两种方案,一种是DaemonSet
另一种方案就是 Sidecar
将 promtail 作为一个 sidecar 挂到对应的你需要采集日志的 deployment 中,并且指定对应的文件路径即可。https://grafana.com/docs/loki/latest/clients/promtail/installation/
而这里我们需要使用的就是 sidecar 的部署方式
containers:
- name: promtail
image: grafana/promtail:2.1.0
imagePullPolicy: Always
args:
- "-config.file=/etc/promtail/promtail.yaml"
- "-client.url=http://loki.your-namespace.svc.cluster.local:3100/loki/api/v1/push"
volumeMounts:
- name: promtail-config-volume
mountPath: /etc/promtail
- name: your-app
mountPath: /logs
readOnly: true
ports:
- name: http-metrics
containerPort: 3101
protocol: TCP
env:
- name: HOSTNAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
这里需要注意的是:
下面就是 promtail 的配置了,这个配置可以根据自己的需要进行调整,主要是采集的频率,文件位置等
client:
backoff_config:
max_period: 5s
max_retries: 20
min_period: 100ms
batchsize: 102400
batchwait: 1s
timeout: 10s
server:
http_listen_port: 3101
positions:
filename: /logs/promtail/positions.yaml
target_config:
sync_period: 10s
scrape_configs:
- job_name: custom
static_configs:
- targets:
- localhost
labels:
job: your-app-name
__path__: /logs/*.log
这里需要注意:
当然针对不同的日志格式 promtail 支持 pipeline 的处理,具体见 https://www.qikqiak.com/k8strain2/logging/loki/promtail/#pipeline
我们采集文件类型的日志时,势必想知道当前的日志是由那个 pod 来的,这个方案我也寻找了很久,因为 loki 本身不支持这样操作,所以我们需要通过环境变量的方式去传递进 sidecar 中,这样就能使用 pod 的信息作为 label 来发送了
首先我们需要修改部署文件中的 args 参数添加 -config.expand-env=true
,然后再 env 中指定你需要传递的环境变量,这里我指定了 pod 的名称
containers:
- name: promtail
image: grafana/promtail:2.1.0
imagePullPolicy: Always
args:
- "-config.expand-env=true"
- "-config.file=/etc/promtail/promtail.yaml"
- "-client.url=http://loki.your-namespace.svc.cluster.local:3100/loki/api/v1/push"
env:
- name: HOSTNAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
然后你就可以在配置文件中使用 ${}
来获取到对应的环境变量的值了,这里我指定了上面传递的 POD_NAME
scrape_configs:
- job_name: custom
static_configs:
- targets:
- localhost
labels:
pod: ${POD_NAME}
job: your-app-name
__path__: /logs/*.log
日志收集配置:https://blog.cong.moe/post/2020-08-08-use_loki_as_k8s_log_collector_2/
实际使用案例:https://mp.weixin.qq.com/s/-IvWfhXbm3WXFIBtbrhX-A 这个案例给我很多数据支持,如果建立在这个案例真实的情况下,实际我们现在的使用情况应该 loki 是足够满足的,包括存储容量和查询效率均可以满足当前我们自身的使用需求