我们将学习如何使用 Sidecar Container 模式在 Kubernetes 上安装 Logstash 和 FluentD 以进行日志聚合。

对于任何系统,日志聚合都非常重要。当你使用 Kubernetes 运行你的应用程序时,日志只属于一个 Pod。如果该 Pod 被删除,日志也会丢失。

因此,如果我们要跟踪系统故障,我们必须有一个日志聚合系统。目前比较流行的两个日志栈是ELK(Elasticsearch Logstash Kibana)和EFK(Elasticsearch FluentD Kibana)。

为了收集每个 Pod 上的日志,我们使用 Sidecar Container。

边车集装箱

我们可以不在应用容器上实现日志收集过程,而是将该过程分离到另一个容器中,以避免影响应用容器的性能。该容器称为 Sidecar Container。

Sidecar 容器是应该与 pod 中的主容器一起运行的容器。这个 sidecar 容器以某种方式扩展和增强了应用程序容器。

[Sidecar 容器](https://res.cloudinary.com/practicaldev/image/fetch/s--m-Q9uP4w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/u0nvy6lxedej004ytwyg.png)

使用 Logstash 进行日志记录

Logstash 的最初任务是监控日志并将它们转换为一组有意义的字段,并最终将输出流式传输到定义的目的地。但是,它在性能方面存在问题。

因此,Elastic 推出了 Filebeat,用于监控日志并将输出流式传输到定义的目标。

Logstash 充当聚合器,从多个来源摄取数据,对其进行转换,然后将其发送到您最喜欢的“存储区”。

[Filebeat](https://res.cloudinary.com/practicaldev/image/fetch/s--DMcwc-w5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to -uploads.s3.amazonaws.com/uploads/articles/7rvoc6szlqt0thes3rzo.png)

所以我们完成了理论,让我们开始工作。首先,我们部署一个 Pod,其中包含一个将日志写入文件/var/log/access.log的应用程序容器,然后我们在同一个 Pod 上部署一个 sidecar 容器,该 Pod 运行 Filebeat 以收集日志并将日志输出到 Logstash。

[Filebeat](https://res.cloudinary.com/practicaldev/image/fetch/s--zY4xfxOL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads .s3.amazonaws.com/uploads/articles/ks09mcjba5dt4tik7ie7.png)

创建一个名为filebeat.cm.yaml的文件来存储 Filebeat 配置文件。

apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-config
  labels:
    component: filebeat
data:
  conf.yaml: |
    filebeat.inputs:
    - type: log
      paths:
        - '/var/log/*.log'
    output:
      logstash:
        hosts: [ "logstash:5044" ]

进入全屏模式 退出全屏模式

我们从文件/var/log/*.log中读取 Filebeat 的输入,然后我们将这些日志输出到 Logstash。

创建一个名为application.yaml的文件。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox
  labels:
    component: busybox
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      component: busybox
  template:
    metadata:
      labels:
        component: busybox
    spec:
      containers:
        - name: busybox
          image: busybox
          args:
            - sh
            - -c
            - >
              while true;
              do
                echo $(date) - filebeat log >> /var/log/access.log;
                sleep 10;
              done
          volumeMounts:
            - name: log
              mountPath: /var/log
        - name: filebeat
          image: elastic/filebeat:7.16.3
          args:
            - -c
            - /etc/filebeat/conf.yaml
            - -e
          volumeMounts:
            - name: filebeat-config
              mountPath: /etc/filebeat
            - name: log
              mountPath: /var/log
      volumes:
        - name: log
          emptyDir: {}
        - name: filebeat-config
          configMap:
            name: filebeat-config

进入全屏模式 退出全屏模式

在上面的 Pod 中,我们将 Filebeat 配置文件挂载到/etc/filebeat/conf.yaml文件中,并使用 args 为 Filebeat 指定该配置文件。

我们的应用程序容器每 10 秒将日志写入文件/var/log/access.log。我们使用 emptyDir 卷在两个容器之间共享存储。

接下来,我们创建一个名为logstash.cm.yaml的文件来存储 Logstash 配置文件。

apiVersion: v1
kind: ConfigMap
metadata:
  name: logstash
  labels:
    component: logstash
data:
  access-log.conf: |
    input {
      beats {
        port => "5044"
      }
    }
    output {
      elasticsearch {
        hosts => [ "elasticsearch:9200" ]
      }
    }

进入全屏模式 退出全屏模式

创建一个名为logstash.yaml的 Logstash 部署文件。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: logstash
  labels:
    component: logstash
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      component: logstash
  template:
    metadata:
      labels:
        component: logstash
    spec:
      containers:
        - name: logstash
          image: logstash:7.16.3
          ports:
            - containerPort: 5044
          volumeMounts:
            - name: logstash-config
              mountPath: /usr/share/logstash/pipeline
      volumes:
        - name: logstash-config
          configMap:
            name: logstash
---
apiVersion: v1
kind: Service
metadata:
  name: logstash
  labels:
    component: logstash
spec:
  ports:
  - port: 5044
  selector:
    component: logstash

进入全屏模式 退出全屏模式

我们将配置文件挂载到文件夹/usr/share/logstash/pipeline,Logstash 会从该文件夹加载配置文件。

创建 Elasticsearch(仅用于测试)。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: elasticsearch
  labels:
    component: elasticsearch
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      component: elasticsearch
  template:
    metadata:
      labels:
        component: elasticsearch
    spec:
      containers:
        - name: elasticsearch
          image: elasticsearch:7.16.3
          ports:
            - containerPort: 9200
              name: client
            - containerPort: 9300
              name: nodes
          env:
            - name: JAVA_TOOL_OPTIONS
              value: -Xmx256m -Xms256m
            - name: discovery.type
              value: single-node
          resources:
            requests:
              memory: 500Mi
              cpu: 0.5
            limits:
              memory: 500Mi
              cpu: 0.5
---
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  labels:
    component: elasticsearch
spec:
  ports:
  - port: 9200
    name: client
  - port: 9300
    name: nodes
  selector:
    component: elasticsearch

进入全屏模式 退出全屏模式

基巴纳。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kibana
  labels:
    component: kibana
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      component: kibana
  template:
    metadata:
      labels:
        component: kibana
    spec:
      containers:
        - name: kibana
          image: kibana:7.16.3
          ports:
            - containerPort: 5601
---
apiVersion: v1
kind: Service
metadata:
  name: kibana
  labels:
    component: kibana
spec:
  ports:
  - port: 5601
  selector:
    component: kibana

进入全屏模式 退出全屏模式

运行 apply 命令来创建资源。

kubectl apply -f . --recursive

进入全屏模式 退出全屏模式

使用端口转发访问 Kibana Dashboard。

kubectl port-forward svc/kibana 5601:5601

进入全屏模式 退出全屏模式

现在,转到菜单 Stack Management > Index patterns 并创建一个索引模式,然后转到菜单 Discover,您将看到我们从busybox容器中收集的日志。

使用 FluentD 进行日志记录

FluentD 也是一个类似 Filebeat 和 Logstash 的日志收集工具。它是一个开源的数据收集器,它可以让您统一数据收集和消费,以便更好地使用和理解数据。

[FluentD](https://res.cloudinary.com/practicaldev/image/fetch/s--v_X5RS1O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads .s3.amazonaws.com/uploads/articles/idjku6ll1kspe9xgmwrh.png)

我们可以将它用作 Sidecar Container 来从 Pod 中收集日志。

[FluentD Sidecar](https://res.cloudinary.com/practicaldev/image/fetch/s--tovaszaa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/fadlbw2yhr3hkm5rjqrv.png)

创建一个名为fluentd.cm.yaml的文件来存储 Filebeat 配置文件。

apiVersion: v1
kind: ConfigMap
metadata:
  name: fluentd-config
  labels:
    component: fluentd
data:
  fluent.conf: |
    <source>
      @type tail
      path /var/log/access.log
      pos_file /tmp/app.logs.pos
      tag app.logs
      <parse>
        @type none
      </parse>
    </source>
    <match app.logs>
      @type elasticsearch
      host elasticsearch
      port 9200
      logstash_format true
      logstash_prefix fluentd
      flush_interval 1s
    </match>

进入全屏模式 退出全屏模式

我们使用<source>标签来指定我们应该在哪里收集日志,然后我们使用<match>标签将日志输出到 Elasticsearch。

接下来,创建一个名为application.yaml的文件。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox
  labels:
    component: busybox
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      component: busybox
  template:
    metadata:
      labels:
        component: busybox
    spec:
      containers:
        - name: busybox
          image: busybox
          args:
            - sh
            - -c
            - >
              while true;
              do
                echo $(date) - filebeat log >> /var/log/access.log;
                sleep 10;
              done
          volumeMounts:
            - name: log
              mountPath: /var/log
        - name: fluentd
          image: govtechsg/fluentd-elasticsearch
          volumeMounts:
            - name: fluentd-config
              mountPath: /fluentd/etc
            - name: log
              mountPath: /var/log
      volumes:
        - name: log
          emptyDir: {}
        - name: fluentd-config
          configMap:
            name: fluentd-config

进入全屏模式 退出全屏模式

运行 apply 命令来创建资源。

kubectl apply -f . --recursive

进入全屏模式 退出全屏模式

Fluentd 插件

需要注意的是,为了将日志输出到 Elasticsearch,我们必须使用 Fluentd Elasticsearch Plugin。

正如你在上面看到的,我们使用的是govtechsg/fluentd-elasticsearch容器,这个容器已经有 Elasticsearch 插件。

如果使用fluent/fluentd容器,会报找不到@type elasticsearch的错误。

要安装插件,我们可以编写 Dockerfile 如下。

FROM fluent/fluentd:v1.12.0-debian-1.0
USER root
RUN gem install fluent-plugin-elasticsearch --version 5.0.3
USER fluent

进入全屏模式 退出全屏模式

FluentD 插件的完整列表https://www.fluentd.org/plugins/all。

实际用例

继续中

结论

至此,我们学习了如何使用 Sidecar Container 模式为 Pod 设置日志收集。 ELK 和 EFK 是两个非常流行的日志堆栈。如果您有任何疑问或需要更多说明,可以在下面的评论部分提出。

Logo

CI/CD社区为您提供最前沿的新闻资讯和知识内容

更多推荐