Kubernetes 实践——Sidecar Container 使用 Logstash 和 FluentD 进行日志记录
我们将学习如何使用 Sidecar Container 模式在 Kubernetes 上安装 Logstash 和 FluentD 以进行日志聚合。 对于任何系统,日志聚合都非常重要。当你使用 Kubernetes 运行你的应用程序时,日志只属于一个 Pod。如果该 Pod 被删除,日志也会丢失。 因此,如果我们要跟踪系统故障,我们必须有一个日志聚合系统。目前比较流行的两个日志栈是ELK(Elas
我们将学习如何使用 Sidecar Container 模式在 Kubernetes 上安装 Logstash 和 FluentD 以进行日志聚合。
对于任何系统,日志聚合都非常重要。当你使用 Kubernetes 运行你的应用程序时,日志只属于一个 Pod。如果该 Pod 被删除,日志也会丢失。
因此,如果我们要跟踪系统故障,我们必须有一个日志聚合系统。目前比较流行的两个日志栈是ELK(Elasticsearch Logstash Kibana)和EFK(Elasticsearch FluentD Kibana)。
为了收集每个 Pod 上的日志,我们使用 Sidecar Container。
边车集装箱
我们可以不在应用容器上实现日志收集过程,而是将该过程分离到另一个容器中,以避免影响应用容器的性能。该容器称为 Sidecar Container。
Sidecar 容器是应该与 pod 中的主容器一起运行的容器。这个 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 充当聚合器,从多个来源摄取数据,对其进行转换,然后将其发送到您最喜欢的“存储区”。
[](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。
[](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 的日志收集工具。它是一个开源的数据收集器,它可以让您统一数据收集和消费,以便更好地使用和理解数据。
[](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 中收集日志。
[](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 是两个非常流行的日志堆栈。如果您有任何疑问或需要更多说明,可以在下面的评论部分提出。
更多推荐
所有评论(0)