K8S-EFK日志收集

部署EFK

1、创建nfs存储访问

启动master节点的nfs服务

创建/data/v1

    kubectl create -f serviceaccount.yaml
    
    kubectl create -f rbac.yaml

修改deployment.yaml文件

    NFS SERVER #存储地址
    
    kubectl create -f deployment.yaml
    
    kubectl create -f class.yaml

 2、构建es集群

    kubectl apply -f kube-logging.yaml
    
    kubectl create -f elasticsearch-statefulset.yaml
    
    kubectl create -f elasticsearch_svc.yaml

测试

    ##所有节点
    yum install -y socat
    ##端口转发,回环地址
    kubectl port-forward es-cluster-0 9200:9200 --namespace=kube-logging
    ##特定地址
    kubectl port-forward --address 192.168.166.128 es-cluster-0 9200:9200 --namespace=kube-logging
    
    
    curl http://localhost:9200/_cluster/health?pretty

 3、部署kibana

    ##修改配置文件如下:
    apiVersion: v1
    kind: Service
    metadata:
      name: kibana
      namespace: kube-logging
      labels:
        app: kibana
    spec:
      type: NodePort
      ports:
      - port: 5601
      selector:
        app: kibana
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: kibana
      namespace: kube-logging
      labels:
        app: kibana
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: kibana
      template:
        metadata:
          labels:
            app: kibana
        spec:
          containers:
          - name: kibana
            image: docker.elastic.co/kibana/kibana:7.2.0
            imagePullPolicy: IfNotPresent
            resources:
              limits:
                cpu: 1000m
              requests:
                cpu: 100m
            env:
              - name: ELASTICSEARCH_URL
                value: http://elasticsearch.kube-logging.svc.cluster.local:9200
            ports:
            - containerPort: 5601
            volumeMounts:
            - name: kibana-config
              mountPath: /usr/share/kibana/config/
          volumes:
          - name: kibana-config
            configMap:
              name: kibana-configmap
    
    
 汉化kibana
     kubectl -n kube-logging create configmap kibana-configmap --from-file=kibana.yml=./kibana.yml
    
     ###kibana.yml
     #
    # ** THIS IS AN AUTO-GENERATED FILE **
    #
    
    # Default Kibana configuration for docker target
    server.name: kibana
    server.host: "0"
    elasticsearch.hosts: [ "http://elasticsearch:9200" ]
    xpack.monitoring.ui.container.elasticsearch.enabled: true
    i18n.locale: "zh-CN"
    
    
    
    kubectl apply -f kibana.yaml
    
    kubectl get pods -n kube-logging
    
    kubectl get svc -n kube-logging

 4、安装fluentd组件

    kubectl apply -f fluentd.yaml
    
    kubectl get po -n kube-logging -o wide

好的,我来为您详细解析 Fluentd 的配置文件。

Fluentd 的配置文件核心在于**连接输入(Input)、过滤(Filter)、输出(Output)** 这三个环节,通常被称为“数据管道”。配置文件使用一种类似于 Apache 或 Nginx 的格式。

一个典型的 Fluentd 配置结构如下:

    # 接收日志(从哪里获取日志)
    <source>
      @type ...
      ...
      tag ...
    </source>
    
    # 处理日志(解析、过滤、增强日志)
    <filter>
      @type ...
      ...
    </filter>
    
    # 输出日志(将日志发送到哪里)
    <match>
      @type ...
      ...
    </match>

* * *

 1. 核心概念

**标签 (Tag)**

这是 Fluentd 最重要的概念之一。它就像日志的“路由地址”。

* `source` 模块会为收到的日志事件打上一个 tag(例如 `app.web`, `syslog.kernel`)。
* 后续的 `filter` 和 `match` 模块通过匹配这个 tag 来决定是否要处理这条日志。
* 标签支持通配符 `*`(匹配0个或多个部分)和 `**`(匹配0个或多个全路径)。

**指令类型 (Directives)**

* **`<source>`**: 定义日志输入源。告诉 Fluentd 从哪里收集日志。
* **`<filter>`**: 定义处理规则。对匹配其标签的事件进行解析、过滤、修改等操作。
* **`<match>`**: 定义输出目的地。将匹配其标签的事件发送到最终的目的地。
* **`<label>`**: (高级)用于将流程分组,简化复杂的路由。
* **`<parse>`**: (嵌套)定义如何解析非结构化的日志文本。
* **`<format>`**: (嵌套)定义输出前的数据格式。
* **`<buffer>`**: (嵌套)定义缓冲设置,用于提高可靠性。

**插件系统 (Plugins)**

Fluentd 的强大之处在于其丰富的插件生态系统。`@type` 参数指定了使用哪个插件。

* `@type forward` (输入/输出)
* `@type tail` (输入)
* `@type regexp` (解析)
* `@type record_modifier` (过滤)
* `@type elasticsearch` (输出)
* `@type s3` (输出)
* `@type stdout` (输出)

* * *

 2. 配置指令详解

 **`<source>` 指令**

定义数据的输入。

    <source>
      # 使用 tail 插件来监听文件的新增内容(最常用)
      @type tail
    
      # 指定要监控的文件路径
      path /var/log/nginx/access.log
    
      # 为从此源读取的日志打上标签
      tag nginx.access
    
      # 使用哪个解析器来解析每一行日志
      <parse>
        # 这是一个标准的 Nginx 访问日志格式
        @type nginx
      </parse>
    
      # 记录上次读取的位置,防止重启后数据丢失
      pos_file /var/log/fluentd/nginx-access.log.pos
    </source>
    
    <source>
      # 监听 TCP 端口,接收其他系统通过 TCP 发送来的日志
      @type tcp
      tag tcp.events
      port 5170
      <parse>
        @type json # 假设发送来的是 JSON 格式
      </parse>
    </source>

 **`<filter>` 指令**

处理事件流。可以串联多个 filter。

    # 处理所有以 nginx.access 开头的标签的事件
    <filter nginx.access>
      @type parser
    
      # 尝试使用 grok 正则表达式(更强大灵活)再次解析 message 字段
      <parse>
        @type grok
        pattern ^%{IPORHOST:client_ip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:access_time}\] "%{WORD:http_method} %{DATA:request} HTTP/%{NUMBER:http_version}" %{NUMBER:response_code} %{NUMBER:body_sent_bytes} "%{DATA:referrer}" "%{DATA:user_agent}"$
      </parse>
    
      # 将解析后的字段覆盖到原始记录中
      key_name message
      reserve_data true # 保留原有字段
    </filter>
    
    <filter nginx.access>
      @type record_modifier
    
      # 添加一个新字段,例如所在区域
      <record>
        dc ${ENV['FLUENT_DATACENTER']} # 从环境变量读取值
        log_type "web_access"
      </record>
    
      # 删除一些不必要的敏感字段
      remove_keys auth, ident
    </filter>

 **`<match>` 指令**

定义输出目的地。标签匹配遵循“首先匹配”原则。

    # 将所有标签为 nginx.access 的事件输出到 Elasticsearch
    <match nginx.access>
      @type elasticsearch
      host elasticsearch.logging.svc.cluster.local
      port 9200
      index_name fluentd-nginx-access-%Y.%m.%d # 按日创建索引
      logstash_format true
    
      # 缓冲设置:内存+文件缓冲, chunk 大小 32MB,每 5s 刷新一次
      <buffer tag, time>
        @type file
        path /var/log/fluentd/buffer/elasticsearch
        flush_interval 5s
        chunk_limit_size 32m
        timekey 1h # 每1小时切分一个chunk
      </buffer>
    </match>
    
    # 将所有事件(**)都在控制台打印一份,用于调试
    <match **>
      @type stdout
    </match>
    
    # 将特定级别的应用日志发送到 S3 进行长期存储
    <match app.production>
      @type s3
      aws_key_id YOUR_AWS_KEY_ID
      aws_sec_key YOUR_AWS_SECRET_KEY
      s3_bucket my-log-bucket
      path logs/
      time_slice_format %Y%m%d%H
    </match>

* * *

 3. 完整示例:收集 Nginx 日志并发送到 ES

    # 设置 Fluentd 本身的日志级别
    <system>
      log_level info
    </system>
    
    # 输入源:监控 Nginx 访问日志
    <source>
      @type tail
      path /var/log/nginx/access.log
      tag nginx.access
      pos_file /var/log/fluentd/nginx-access.log.pos
      <parse>
        @type nginx
      </parse>
    </source>
    
    # 输入源:接收来自其他容器的 Docker JSON 日志
    <source>
      @type forward
      port 24224
      tag docker.** # 匹配所有以 docker. 开头的标签
    </source>
    
    # 过滤:为所有事件添加主机名
    <filter **>
      @type record_modifier
      <record>
        hostname "#{Socket.gethostname}"
      </record>
    </filter>
    
    # 输出:将所有nginx日志发送到Elasticsearch
    <match nginx.access>
      @type elasticsearch
      host es-host
      port 9200
      logstash_format true
      logstash_prefix nginx-access
      <buffer>
        @type file
        path /var/log/fluentd/buffer/es
        flush_interval 10s
      </buffer>
    </match>
    
    # 输出:将docker日志也发送到ES,但放到不同的索引中
    <match docker.**>
      @type elasticsearch
      host es-host
      port 9200
      logstash_format true
      logstash_prefix docker
      <buffer>
        @type file
        path /var/log/fluentd/buffer/es-docker
        flush_interval 10s
      </buffer>
    </match>
    
    # 输出:同时在控制台打印所有信息(最后执行)
    <match **>
      @type stdout
    </match>

 4. 最佳实践与调试技巧

1. **从简单开始**:先用 `@type stdout` 输出到控制台,确保数据流和你预期的一样。
2. **理解标签路由**:规划好你的标签命名策略(如 `.<service_name>.<log_type>`)。
3. **使用 Buffer**:对于网络输出(如 ES, S3),**务必配置 `<buffer>`**。使用 `file` 缓冲类型可以提高可靠性,防止节点重启或网络抖动时数据丢失。
4. **环境变量**:可以使用 `#{ENV['VARIABLE_NAME']}` 在配置中引用环境变量,避免将密码等敏感信息硬编码在配置文件中。
5. **配置文件检查**:使用 `fluentd --dry-run -c /path/to/your.conf` 命令来检查配置文件语法是否正确,而无需真正启动进程。

通过理解这些核心概念和指令,您就可以编写出强大而灵活的 Fluentd 配置来满足各种日志收集和处理需求。

更多推荐