Docker通过EFK(Elasticsearch + Fluentd + Kibana)查询日志

本文详细介绍如何使用Elasticsearch、Fluentd和Kibana(EFK)搭建日志管理系统,实现Docker环境下日志的收集、存储和可视化分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概述

Elasticsearch是一个开源搜索引擎,以易用性着称。kibana是一个图形界面,可以在上面条件检索存储在ElasticSearch里数据,相当于提供了ES的可视化操作管理器。

fluentd

fluentd是一个针对日志的收集、处理、转发系统。通过丰富的插件系统,可以收集来自于各种系统或应用的日志,转化为用户指定的格式后,转发到用户所指定的日志存储系统之中。

fluentd 常常被拿来和Logstash比较,我们常说ELK,L就是这个agent。fluentd 是随着Docker,GCP 和es一起流行起来的agent。

这篇文章里概括一下的话,有以下区别:

  • fluentd 比 logstash 更省资源;
  • 更轻量级的 fluent-bid 对应 filebeat,作为部署在结点上的日志收集器;
  • fluentd 有更多强大、开放的插件数量和社区。插件列表这一点值得多说,插件太多了,也非常灵活,规则也不复杂。

 

基本的架构

 

 

这里主要解决的问题是日志查询,日志来源是docker。我们使用docker部署任务时,可以使用docker logs -f <容器id>查看日志,也可以去/var/lib/docker/containers/<容器id>/<容器id>-json.log查看日志文件。但是这都很难去做查询,本文介绍的EFK就可以解决这个问题。

我们会创建四个容器:

 

环境说明:

请安装最新的docker及docker-compose,老版本会有些问题。

docker安装,请参考链接:

https://www.cnblogs.com/xiao987334176/p/11771657.html

docker-compose安装,请参考链接:

https://www.cnblogs.com/xiao987334176/p/12377113.html

 

操作系统:centos 7.6

配置:2核8g

docker版本:19.03.6

docker-compose版本:1.24.1

 

本文使用一台centos7.6服务器,来演示EFK。

注意:内存至少在4g或者以上。

 

二、docker-compose运行EFK

目录结构

 创建一个空目录

mkdir /opt/efk/

目录结构如下:

./
├── docker-compose.yml
└── fluentd
    ├── conf
    │   └── fluent.conf
    └── Dockerfile

 

docker-compose.yml

version: '2'
services:
  web:
    image: httpd
    ports:
      - "1080:80" #避免和默认的80端口冲突
    links:
      - fluentd
    logging:
      driver: "fluentd"
      options:
        fluentd-address: localhost:24224
        tag: httpd.access

  fluentd:
    build: ./fluentd
    volumes:
      - ./fluentd/conf:/fluentd/etc
    links:
      - "elasticsearch"
    ports:
      - "24224:24224"
      - "24224:24224/udp"

  elasticsearch:
    image: elasticsearch:7.6.0
    environment:
      - discovery.type=single-node
    expose:
      - 9200
    ports:
      - "9200:9200"

  kibana:
    image: kibana:7.6.0
    links:
      - "elasticsearch"
    ports:
      - "5601:5601"
View Code

注意:elasticsearch 7.6.0要使用单机模式,必须传入环境变量discovery.type=single-node

 

所有web里的日志会自动发送到fluentd-address: localhost:24224,也就是fluentd容器。

Elasticsearch 和 Kibana是目前最新的版本7.6.0,如果想要选择更新的,可以去这里查看

Elasticsearch image tags in DockerHub

Kibana image tags in DockerHub

 

Fluentd的配置和插件

新建文件fluentd/Dockerfile,使用官方镜像Fluentd’s official Docker image,安装需要的插件

# fluentd/Dockerfile
FROM fluent/fluentd:v0.12-debian
RUN ["gem", "install", "fluent-plugin-elasticsearch", "--no-rdoc", "--no-ri", "--version", "1.9.7"]

 

然后新建文件fluentd/conf/fluent.conf,编写Fluentd的配置文件

<source>
  @type forward
  port 24224
  bind 0.0.0.0
</source>
<match *.**>
  @type copy
  <store>
    @type elasticsearch
    host elasticsearch
    port 9200
    logstash_format true
    logstash_prefix fluentd
    logstash_dateformat %Y%m%d
    include_tag_key true
    type_name access_log
    tag_key @log_name
    flush_interval 1s
  </store>
  <store>
    @type stdout
  </store>
</match>
View Code

官方设置文档config-file

 

修改/etc/sysctl.conf 

此参数一定要改,否则Elasticsearch 无法启动

vm.max_map_count = 2621440

加载配置

sysctl -p

 

启动容器

在后台启动,使用docker-compose up -d

# docker-compose up -d
Starting efk_elasticsearch_1 ... done
Starting efk_fluentd_1       ... done
Starting efk_kibana_1        ... done
Starting efk_web_1           ... done

 

查看所有容器

# docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                                                          NAMES
d82b1a16c970        httpd                 "httpd-foreground"       21 hours ago        Up 51 minutes       0.0.0.0:1080->80/tcp                                           efk_web_1
1085be0f9c6e        efk_fluentd           "tini -- /bin/entryp…"   21 hours ago        Up 51 minutes       5140/tcp, 0.0.0.0:24224->24224/tcp, 0.0.0.0:24224->24224/udp   efk_fluentd_1
3e837917f4cf        kibana:7.6.0          "/usr/local/bin/kiba…"   21 hours ago        Up 51 minutes       0.0.0.0:5601->5601/tcp                                         efk_kibana_1
3d860ca7e0db        elasticsearch:7.6.0   "/usr/local/bin/dock…"   21 hours ago        Up 51 minutes       0.0.0.0:9200->9200/tcp, 9300/tcp                               efk_elasticsearch_1

 

产生日志

使用curl执行3遍

curl http://localhost:1080/
curl http://localhost:1080/
curl http://localhost:1080/

 

查看日志

打开http://localhost:5601,提示需要先建索引,输入fluentd-*刷新即可

 

 

选择时间戳

 

 

 

 去Discover页面,然后就可以看到之前的日志了。

 

 

如何接入其他docker日志

这里是以docker-compose形式启动的一个服务,如果还有别的任务需要将日志发送到fluentd,需要这几个步骤。

默认情况下,docker-compose会为我们的应用创建一个网络,服务的每个容器都会加入该网络中。这样,容器就可被该网络中的其他容器访问,不仅如此,该容器还能以服务名称作为hostname被其他容器访问。

所以我们首先需要找到我们现在创建的EFK的网络名,

# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
afa576d45dff        bridge              bridge              local
27d56becedb8        efk_default         bridge              local
1d5b4653e1df        host                host                local
901f8a349049        none                null                local

 

我是在efk目录下创建的docker-compose.yml文件,所以这里默认的名字就是efk_default。

再看看之前web的设置

web:
    image: httpd
    ports:
      - "1080:80" #避免和默认的80端口冲突
    links:
      - fluentd
    logging:
      driver: "fluentd"
      options:
        fluentd-address: localhost:24224
        tag: httpd.access

有几个关键设置是:links和logging,link 用于容器直接的互通,logging则是日志的输出设置。

那我们这里再启动一个新docker需要这些设置

docker run \
    --link efk_fluentd_1 \
    --net efk_default  \
    --log-driver=fluentd \
    --log-opt fluentd-address=localhost:24224 \
    --log-opt tag=httpd.access \
    -d hello-world

我们去kibana看看,果然,日志已经发送到kibana了。

搜索hello

如果是其他机器,需要指定fluentd ip,比如:

docker run \
    --log-driver=fluentd \
    --log-opt fluentd-address=172.19.155.138:24224 \
    --log-opt tag=httpd.access \
    -d hello-world

 

最后想要做的就是如何在一台服务器上搜集所有的日志,理论上来说,只需要一台服务器部署上EFK,暴露端口,其他服务器去发送即可,实际上还没试过。

 

本文参考链接:

https://zhuanlan.zhihu.com/p/63105931

<think>好的,用户现在想要在Kubernetes集群内部署ElasticsearchFluentdKibanaEFK)技术栈的文档。首先,我需要理解用户的需求。用户可能正在搭建一个日志管理系统,用于收集、存储和可视化Kubernetes中的日志EFK是一个常见的组合,其中Fluentd负责日志收集,Elasticsearch存储日志Kibana提供可视化界面。 接下来,我需要考虑用户可能的背景。他们可能是有一定Kubernetes基础的系统管理员或DevOps工程师,但可能对EFK的具体部署步骤不太熟悉。用户可能希望有一个详细的指南,帮助他们一步步完成部署,并解决可能遇到的问题。 然后,我需要组织内容结构。首先介绍EFK各组件的作用,然后详细说明部署步骤,包括命名空间创建、Elasticsearch部署、Fluentd配置、Kibana部署以及验证步骤。此外,常见问题和优化建议也很重要,帮助用户应对实际部署中的挑战。 在编写具体步骤时,需要注意Kubernetes的资源配置,比如Elasticsearch的StatefulSet需要持久化存储,资源限制,以及节点亲和性设置。Fluentd的配置需要涉及DaemonSet,确保每个节点运行一个Pod来收集日志Kibana的部署则需要注意服务暴露的方式,比如NodePort或Ingress。 同时,要检查用户之前的问题历史。用户之前询问过Filebeat处理多行日志的问题,现在转向EFK,可能对日志收集的可靠性和扩展性有更高要求。因此,在文档中需要强调Fluentd在多行日志处理上的优势,并可能提供相关配置示例。 另外,用户可能关心如何验证部署是否成功,所以需要包括检查Pod状态、访问Kibana界面以及测试日志收集的步骤。常见问题部分需要覆盖存储问题、资源不足、Fluentd配置错误等,提供具体的解决方案。 最后,优化建议部分应该帮助用户提升性能和稳定性,比如Elasticsearch的索引策略、Fluentd的缓冲区配置和Kibana的优化。这些内容能够帮助用户在生产环境中更好地管理EFK栈。 总结来说,需要提供一个结构清晰、步骤详细、包含故障排查和优化建议的文档,帮助用户在K8s上顺利部署EFK,满足日志管理的需求。</think>以下是基于 Kubernetes 集群部署 **Elasticsearch + Fluentd + Kibana (EFK)** 技术栈的完整文档: --- ### 一、架构概述 ```mermaid graph TD A[应用Pod日志] -->|stdout/stderr| B[K8s节点/var/log/containers] B -->|DaemonSet采集| C[Fluentd] C -->|结构化处理| D[Elasticsearch] D -->|数据存储| E[Kibana可视化] ``` --- ### 二、前置条件 1. **Kubernetes 集群版本** ≥ 1.18 2. **存储类(StorageClass)**:支持动态卷供应(如 `rook-ceph`, `nfs`) 3. **资源配额**:建议每个节点预留至少 2CPU + 4GB 内存 4. **Helm 工具**:用于快速部署(版本 ≥ 3.0) --- ### 三、详细部署步骤 #### 步骤 1:创建专用命名空间 ```bash kubectl create namespace efk ``` #### 步骤 2:部署 Elasticsearch ```yaml # elasticsearch-statefulset.yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: elasticsearch namespace: efk spec: serviceName: elasticsearch replicas: 3 selector: matchLabels: app: elasticsearch template: metadata: labels: app: elasticsearch spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: ["elasticsearch"] topologyKey: "kubernetes.io/hostname" containers: - name: elasticsearch image: docker.elastic.co/elasticsearch/elasticsearch:7.17.3 resources: limits: memory: 4Gi requests: cpu: 1000m memory: 2Gi env: - name: discovery.type value: single-node # 生产环境需改为 zen 发现机制 - name: ES_JAVA_OPTS value: "-Xms2g -Xmx2g" ports: - containerPort: 9200 name: http volumeMounts: - name: data mountPath: /usr/share/elasticsearch/data volumes: - name: data persistentVolumeClaim: claimName: es-data-pvc --- # elasticsearch-service.yaml apiVersion: v1 kind: Service metadata: name: elasticsearch namespace: efk spec: selector: app: elasticsearch ports: - port: 9200 name: http clusterIP: None ``` #### 步骤 3:部署 Fluentd ```yaml # fluentd-configmap.yaml apiVersion: v1 kind: ConfigMap metadata: name: fluentd-config namespace: efk data: fluent.conf: | <source> @type tail path /var/log/containers/*.log pos_file /var/log/fluentd-containers.log.pos tag kube.* read_from_head true <parse> @type json time_format %Y-%m-%dT%H:%M:%S.%NZ </parse> </source> <filter kube.**> @type kubernetes_metadata </filter> <match kube.**> @type elasticsearch host elasticsearch.efk.svc.cluster.local port 9200 logstash_format true logstash_prefix fluentd flush_interval 5s </match> --- # fluentd-daemonset.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd namespace: efk spec: selector: matchLabels: app: fluentd template: metadata: labels: app: fluentd spec: tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: fluentd image: fluent/fluentd-kubernetes-daemonset:v1.16-debian-elasticsearch7 env: - name: FLUENT_ELASTICSEARCH_HOST value: "elasticsearch.efk.svc.cluster.local" - name: FLUENT_ELASTICSEARCH_PORT value: "9200" resources: limits: memory: 512Mi requests: cpu: 100m memory: 200Mi volumeMounts: - name: varlog mountPath: /var/log - name: config-volume mountPath: /fluentd/etc/conf.d volumes: - name: varlog hostPath: path: /var/log - name: config-volume configMap: name: fluentd-config ``` #### 步骤 4:部署 Kibana ```yaml # kibana-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: kibana namespace: efk spec: replicas: 1 selector: matchLabels: app: kibana template: metadata: labels: app: kibana spec: containers: - name: kibana image: docker.elastic.co/kibana/kibana:7.17.3 resources: limits: memory: 1Gi requests: cpu: 500m memory: 512Mi env: - name: ELASTICSEARCH_HOSTS value: "http://elasticsearch.efk.svc.cluster.local:9200" ports: - containerPort: 5601 --- # kibana-service.yaml apiVersion: v1 kind: Service metadata: name: kibana namespace: efk spec: type: NodePort selector: app: kibana ports: - port: 5601 targetPort: 5601 nodePort: 30601 ``` --- ### 四、验证部署 1. **检查 Pod 状态**: ```bash kubectl -n efk get pods -l app=elasticsearch kubectl -n efk get pods -l app=fluentd kubectl -n efk get pods -l app=kibana ``` 2. **访问 Kibana**: - 浏览器访问 `http://<任意节点IP>:30601` - 创建索引模式 `fluentd-*` 3. **测试日志收集**: ```bash kubectl run test-logger --image=alpine -- sh -c "while true; do echo 'EFK test log'; sleep 5; done" ``` --- ### 五、常见问题处理 #### 问题 1:Elasticsearch 无法启动 - **现象**:Pod 处于 `CrashLoopBackOff` 状态 - **排查**: ```bash kubectl -n efk logs elasticsearch-0 ``` - **解决方案**:检查存储类是否可用,调整 Java 堆内存参数 #### 问题 2:Fluentd 无法连接 Elasticsearch - **现象**:日志中出现 `Connection refused` 错误 - **排查**: ```bash kubectl -n efk exec -it fluentd-xxxxx -- curl elasticsearch:9200 ``` - **解决方案**:检查 Service 域名解析,确认网络策略允许通信 --- ### 六、生产环境优化建议 1. **Elasticsearch 优化**: - 使用专用节点角色(master/data/ingest) - 配置索引生命周期管理 (ILM) ```yaml # 示例索引模板 PUT _template/logs { "index_patterns": ["fluentd-*"], "settings": { "number_of_shards": 3, "number_of_replicas": 1, "index.lifecycle.name": "logs_policy" } } ``` 2. **Fluentd 优化**: - 增加缓冲区配置防止数据丢失 ```conf <match **> @type elasticsearch buffer_type memory buffer_chunk_limit 32m buffer_queue_limit 1024 flush_interval 5s </match> ``` 3. **Kibana 优化**: - 启用 X-Pack 安全模块 - 配置 Ingress + TLS 证书 --- ### 附:快速部署命令(Helm 方式) ```bash # 添加 Helm 仓库 helm repo add elastic https://helm.elastic.co # 部署 Elasticsearch helm install elasticsearch elastic/elasticsearch -n efk # 部署 Kibana helm install kibana elastic/kibana -n efk # 部署 Fluentd helm install fluentd stable/fluentd --set elasticsearch.host=elasticsearch-master.efk.svc.cluster.local ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值