ELK采集k8s日志总结(三) log-pilot 采集k8s日志

4,877 阅读9分钟

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

使用

  1. 配置一个log-pilot demonSet发布到k8s中,这样每个Node就有采集组件了
  2. 为要采集的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

其它知识点

常见的日志采集组件

  1. filebeat
  2. Logstash
  3. logpilot
  4. 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参数,步骤

  1. 先关闭容器,rm容器
  2. 修改配置文件,把安全相关的注释了,不然容器无法启动
  3. 修改jvm再次启动容器
  4. 复制keywords相关文件到容器
  5. 修改配置文件取消注释
  6. 重启容器

因为使用了安全校验,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