log-pilot 采集k8s日志
到此,我们的ELK已经部署好了,下面部署log-pilot,它会采集容器的日志并推送到logstash,logstahs处理日志后发到es,下面对log-pilot做一个简单的总结
启动的容器服务,通过配置tag,会被log-pilot解析到,去获取容器的日志
特性
Log-Pilot具有自动发现机制: 容器配置好tag后就会被采集组件发现 CheckPoint句柄保持的机制: 对于日志文件的句柄做跟踪 自动日志数据打标: 通过对容器加tag,这个tag会被记录到日志中,取出日志的时候就可以通过这个tag来区分数据 有效应对动态配置: 容器扩缩容的时候能够自动处理 日志重复和丢失以及日志源标记等问题: 通过句柄保持实现
lable
aliyun.logs.$name = $path
变量 name 是日志名称,只能包含 0~9、a~z、A~Z 和连字符(-)
变量 path 是要收集的日志路径,必须具体到文件,不能只写目录。文件名部分可以使用通配符,例如,/var/log/he.log 和 /var/log/*.log 都是正确的值,但 /var/log 不行,不能只写到目录。stdout 是一个特殊值,表示标准输出
aliyun.logs.$name.format:日志格式,目前支持以下格式 none:无格式纯文本 json:json 格式,每行一个完整的 json 字符串 csv:csv 格式
aliyun.logs.$name.tags:上报日志时,额外增加的字段,格式为 k1=v1,k2=v2,每个 key-value 之间使用逗号分隔,例如 aliyun.logs.access.tags="name=hello,stage=test",上报到存储的日志里就会出现 name 字段和 stage 字段 如果使用 ElasticSearch 作为日志存储,target 这个 tag 具有特殊含义,表示 ElasticSearch 里对应的 index
使用
- 配置一个log-pilot demonSet发布到k8s中,这样每个Node就有采集组件了
- 为要采集的Docker容器添加lable,使用的关键就在于这个tag要怎么添加
PILOT_LOG_PREFIX: "aliyun,custom" 通过修改这个环境变量能改变lable的前缀,默认是aliyun(有些版本不适用了)
docker pull log-pilot:0.9.6-filebeat
部署yaml
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: log-pilot
namespace: kube-system
labels:
k8s-app: log-pilot
kubernetes.io/cluster-service: "true"
spec:
template:
metadata:
labels:
k8s-app: log-es
kubernetes.io/cluster-service: "true"
version: v1.22
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
serviceAccountName: dashboard-admin
containers:
- name: log-pilot
# 版本请参考https://github.com/AliyunContainerService/log-pilot/releases
image: log-pilot:latest
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
env:
- name: "NODE_NAME"
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: "LOGGING_OUTPUT"
value: "logstash"
- name: "LOGSTASH_HOST"
value: "10.90.x.x"
- name: "LOGSTASH_PORT"
value: "5044"
- name: "LOGSTASH_LOADBALANCE"
value: "true"
#- name: "FILEBEAT_OUTPUT"
# value: "elasticsearch"
#- name: "ELASTICSEARCH_HOST"
# value: "elasticsearch"
#- name: "ELASTICSEARCH_PORT"
# value: "9200"
#- name: "ELASTICSEARCH_USER"
# value: "elastic"
#- name: "ELASTICSEARCH_PASSWORD"
# value: "changeme"
volumeMounts:
- name: sock
mountPath: /var/run/docker.sock
- name: root
mountPath: /host
readOnly: true
- name: varlib
mountPath: /var/lib/filebeat
- name: varlog
mountPath: /var/log/filebeat
securityContext:
capabilities:
add:
- SYS_ADMIN
terminationGracePeriodSeconds: 30
volumes:
- name: sock
hostPath:
path: /var/run/docker.sock
- name: root
hostPath:
path: /
- name: varlib
hostPath:
path: /var/lib/filebeat
type: DirectoryOrCreate
- name: varlog
hostPath:
path: /var/log/filebeat
type: DirectoryOrCreate
deployment 注入环境变量配置,假设应用名称叫做 monitor-center
- name: aliyun_logs_monitor-center-stdout
# 采集控制台
value: "stdout"
- name: aliyun_logs_monitor-center-tomcat
# 采集指定目录
value: "/usr/local/tomcat/logs/*.log"
- name: aliyun_logs_monitor-center-netcore
# 采集指定目录
value: "/app/logs/*.log"
- name: aliyun_logs_monitor-center-java
# 采集指定目录
value: "/logs/*.log"
- name: aliyun_logs_monitor-center-stdout_tags
# 为 aliyun_logs_monitor-center-stdout 采集 控制台 配置打上标签,下面类似
value: "app=monitor-center,lang=all,sourceType=stdout"
- name: aliyun_logs_monitor-center-tomcat_tags
value: "app=monitor-center,lang=java,sourceType=log"
- name: aliyun_logs_monitor-center-netcore_tags
value: "app=monitor-center,lang=net,sourceType=log"
- name: aliyun_logs_monitor-center-java_tags
value: "app=monitor-center,lang=java,sourceType=log"
排查filebeat配置是否正确
kubectl -n kube-system get pod | grep log-pilot
kubectl exec -it log-pilot-nspdv sh -n kube-system
cat /etc/filebeat/filebeat.yml
其它知识点
常见的日志采集组件
- filebeat
- Logstash
- logpilot
- fluentd
ElasticSearch Curator
是一个python开发的工具,可以更方便的操作es,不用直接发HTTP请求了 不过这个工具在更高的版本中也已经过时了,es7.X 请直接学习生命周期的运用
elastalert
es扩展插件。可以实现针对特定的匹配日志做处理,产生告警
Elastic Beats
Beats就是轻量的意思,是获取数据的源头服务,这些可以是日志文件(Filebeat),网络数据(Packetbeat),服务器指标(Metricbeat)
所以社区出了 ELKB 的概念,而我们使用log-pilot来采集容器数据,其实已经是 ELKB 的思想了
https://www.cnblogs.com/sanduzxcvbnm/p/12076383.html
关于type
5.x 版本可以创建多个type 6.x 版本只能创建一个type 7.x 版本去掉了type
es是基于索引index的,不需要通过type(关系数据库中的表)来提高查询速度
关于节点
主节点,数据节点,预处理节点(协调节点)。节点类型可以显示的指定,默认都充当了各种功能,主节点是选出来的 主节点要负责同步集群状态,协调节点负责转发请求,如果协调节点也参与数据处理,那么协调节点负载过高,无法转发请求,可能就会影响整体性能 在大规模节点下,比如10台以上,可以每个节点专一职责,对于预处理节点由于不需要存储数据,对CPU内存的要求也不会很高
最好使用nginx负载均衡,轮询节点处理请求,不要每次都把请求发到一个节点上
关于节点重平衡
突然的一台宕机没必要触发集群重平衡,可以关闭,或者设置触发延迟时间
关于自动创建索引
如果不允许自动创建索引,那么ELK中向ES推日志的时候,就没法在前端看到,需要手动创建索引。通过修改配置可以开关这个功能
默认堆
es 默认堆最大最小就是2GB,所以如果是为了测试不知道堆的时候,可能因为默认值太大导入docker启动失败
Docker ES 修改
如果要调整ES jvm参数,步骤
- 先关闭容器,rm容器
- 修改配置文件,把安全相关的注释了,不然容器无法启动
- 修改jvm再次启动容器
- 复制keywords相关文件到容器
- 修改配置文件取消注释
- 重启容器
因为使用了安全校验,keywords文件在容器销毁后消失,注意插件也没了
然后存储数据是映射到本地的,不用理会,当集群失去节点后,会重新平衡索引到其它节点,当集群新增节点后,会再次平衡数据 存储到本地的数据在节点失效的时候就已经失效了,节点重新加入数据又被写入新的,总之在docker模式下,不需要太关注数据的文件
以上的做法其实是重新部署的,还有一种方式是非规操作,可以不用销毁容器,不过不太稳定,建议jvm一开始就规划好。如果非要修改,先采用非规操作,就是去修改docker container里面的文件,这个有点复杂。这样数据还是存在的,如果集群节点较多,有副本备份,那么可以直接销毁容器,这样数据也是不丢失的
问题汇总
记录常见问题处理方案
search.max_buckets 过小异常
trying to create too many buckets. must be less than or equal to: [100000] but was [100001]. this limit can be set by changing the [search.max_buckets] cluster level setting.
出现上述错误,可能是search.max_buckets设置问题,使用transient临时修改
curl -H 'Content-Type: application/json' ip:port/_setting/cluster -d '{
"transient": {
"search.max_buckets": 217483647
}
}'
通过kibana,persistent是持久化配置
PUT /_cluster/settings
{
"persistent": {
"search.max_buckets": 217483647
}
}
或者直接改配置文件
官方参考 https://www.elastic.co/guide/en/elasticsearch/reference/master/search-aggregations-bucket.html
分片数过小
需要调整分片数大小,7.5默认分片数是2000,超过这个值集群无法创建分片,通过kibana,persistent是持久化配置,transient是暂时的
PUT /_cluster/settings
{
"persistent": {
"cluster": {
"max_shards_per_node":10000
}
}
}
写入线程过小
配置文件修改后重启,写入线程大小修改: thread_pool.write.queue_size: 1000
修改默认放回值条目
index.max_result_window: 1000000 默认只能返回10000,可能调用链太长需要修改这个配置(skywalking)
ELK 架构参考 https://www.one-tab.com/page/tto_XdDeQlS44BY-ziLvKg ELK 搭建 https://www.one-tab.com/page/Fb3B3qd2Q9yR9W92dZ2pYQ