资讯动态

基于Helm快速部署K8s EFK日志采集与分析系统

发布时间:2026/10/14 1:13:55 来源:尧图企业网站定制
做K8s运维的人都有一个共同痛点日志。平时觉得没啥一旦线上出问题几十个Pod来回敲kubectl logs运气好日志还在运气不好连日志都被回收了整个晚上就在跟时间赛跑。所以我每到一个新集群第一件事就是把日志采集分析链路搭起来而最适合K8s场景、又最容易上手的组合就是EFK——Elasticsearch负责存储和检索Filebeat负责采集日志Kibana负责可视化查看。整套方案不需要写一堆YAML用Helm一条命令就能把三个组件全部拉起来换环境、改配置、升级回滚都很方便。这篇文章主要面向运维和开发同学带你们完整走一遍基于Helm快速部署EFK的过程包括环境准备、values配置、实际部署命令和部署后经常会踩的坑。我前两天刚在某公司的测试集群上用这套流程搭完EFK从准备到看到第一条日志前后不到半小时。这篇文章不是纯理论的架构讲解而是把我实际操作过程中用到的命令、参数、排查思路和踩过的坑全部记录下来希望能给准备上日志系统的同学省点时间。1. EFK架构与部署思路拆解1.1 为什么是EFK而不是ELKELK这个名字你可能听过很多年Elasticsearch Logstash Kibana。但真到K8s里部署日志采集我更推荐把Logstash换成Filebeat变成EFK。核心原因只有一个资源占用差距太大了。Logstash是Java写的默认就要1GB以上的堆内存对它来说这还只是“够用”。在节点数多、业务Pod密度高的集群里每个节点都挂一个Logstash吃内存吃得非常心疼。而Filebeat是Go语言写的轻量级采集器默认只占用10MB到20MB左右的内存跑起来像个小透明。K8s里托管节点还要考虑节点规格和Pod调度省下来的内存可以给业务应用用这个差距一开始不明显节点一多就特别真实。Filebeat能不能替代Logstash的所有功能不能。如果你要做的是复杂的日志清洗、多路输出、复杂的过滤管道Logstash依然更强。但日志采集链路里90%的场景其实很朴素把容器里产生的日志文件忠实地采出来按行处理一下送到Elasticsearch去。这些事Filebeat完全够用而且它原生支持K8s环境可以通过DaemonSet方式部署每个节点自动跑一个采集器不需要额外处理节点亲和性。1.2 为什么用Helm而不是手工拼YAML我第一次搭EFK的时候还是老办法每个组件手写YAML。Elasticsearch一个StatefulSet就够写半天还要配Service、配置ConfigMap、准备PVC加上Kibana的Deployment和ServiceFilebeat的DaemonSet和RBAC零零散散二十多个文件。最麻烦的是改版本的时候每个文件都要对着改改漏一处就是一次事故现场。Helm解决的正是“重复部署”和“多文件管理”这两个问题。只要维护好一个values.yaml其他内容都交给chart模板去处理换环境只需要复制文件改参数一行helm upgrade就能完整更新整套应用。这一点在做多环境部署的时候价值特别大测试、预发、生产三套环境配置文件结构完全一样只是副本数、资源规格、存储大小不一样维护成本低得多。Helm的另一个好处是版本化回滚。helm rollback一条命令就能回到上一个部署版本手工模式如果改坏了YAML只能一步一步排查往回改而Helm把release状态完整记录下来出问题秒回滚。操作手感上很像Git分支切换用惯了之后真的回不去手写YAML的日子。1.3 组件选型与版本怎么定EFK三个组件的版本必须匹配这是部署前就要决定好的关键项。以主流的7系版本为例Elasticsearch、Kibana、Filebeat尽量使用相同的版本号比如都用7.10.2、7.16.3。版本不一致会导致Kibana显示兼容性警告甚至部分功能不可用。Filebeat如果跟ES版本差太多采集的数据可能因为字段映射问题在Kibana里显示异常。版本定了之后再考虑架构形态测试/小规模环境Elasticsearch单节点1副本数存储给50GB就算舒适区。生产环境建议3个master节点保证选举安全至少2个data节点副本数设2日志数据量大就单独给data节点扩容。首次部署不建议在生产环境直接上大集群先把链路跑通观测数据量再横向扩展。我见过很多同学第一次部署就按生产规格上3个master3个data结果日志量一天不到1GB纯属浪费资源。数据量小的时候单节点足够等监控指标显示存储或查询压力上来了再扩容也不迟。另一个容易被忽略的点是存储类型。ES对磁盘IO非常敏感尤其是写入密集的场景。能上SSD尽量上SSD至少也要确保StorageClass提供的是高IO的存储否则日志量一大集群健康状态直接变黄变红。这一点在volumeClaimTemplate里配置存储类的时候就要注意。2. 部署准备与关键参数设计2.1 环境检查与前置条件动手部署之前先把环境检查清单过一遍避免装到一半才发现底子不够。最基本的几个检查项Kubernetes集群版本建议1.18及以上低版本对StatefulSet的某些特性支持不完整。Helm版本用3.x2.x已经算是老古董了且3.x不需要配置Tiller。StorageClassES依赖持久化存储必须确认集群里有可用的StorageClass或者提前准备好PV。用kubectl get storageclass查看没有默认存储类的话后面创建PVC就会卡在Pending状态。节点资源即使是测试环境单个ES节点最好也有2核4GB可用内存否则一启动就OOM不是开玩笑的。我实际踩过一次环境坑某测试集群用的是本地存储模拟的动态卷但是volumeBindingMode设的是WaitForFirstConsumerES StatefulSet的PVC一直Pending折腾了半天才反应过来是存储时序的问题。所以环境检查这一步千万别省。2.2 添加Helm仓库与拉取chart环境没问题之后先把Elastic官方维护的Helm仓库加到本地。命令很简单helm repo add elastic https://helm.elastic.co helm repo update如果你的网络环境访问官方仓库不方便可以用helm repo add换成社区维护的镜像仓库或者提前在能访问的环境helm pull把chart包下载下来再传到内网用helm install xxx chart包文件安装。这个离线方式在隔离网环境特别常见我建议先把chart包拉下来留底后面免安装做离线部署就是它了。确认仓库添加成功之后用下面命令搜索一下chart是不是在列表里helm search repo elastic正常情况下能看到elastic/elasticsearch、elastic/kibana、elastic/filebeat这几个包。版本字段就是对应产品的版本选好你要的版本号之后还建议额外下载一份默认values文件看看里面有哪些参数可以覆盖helm show values elastic/elasticsearch helm show values elastic/kibana helm show values elastic/filebeat这一步非常关键。默认values不一定符合你的场景生成一份完整的参数清单改动时心里有数。2.3 values.yaml核心参数规划接下来是最核心的工作写自定义values.yaml。以Elasticsearch为例下面是我在测试环境常用的配置replicas: 1 minimumMasterNodes: 1 resources: requests: cpu: 1000m memory: 2Gi limits: cpu: 2000m memory: 4Gi volumeClaimTemplate: storageClassName: standard accessModes: [ReadWriteOnce] resources: requests: storage: 50Gi esJavaOpts: -Xms2g -Xmx2g逐个解释下这些参数的用意replicasES节点副本数测试环境1个就够别上来就写3资源撑不住。minimumMasterNodes集群最少可用master节点数单节点集群配1即可。resourcesPod的requests和limitsrequests申请多少调度就按这个预留limits限制最大可用防止某个节点把宿主机的资源吃爆。volumeClaimTemplate这是StatefulSet里声明PVC的方式storageClassName对应集群里的存储类accessModes用ReadWriteOnce存储大小根据日志量预估测试50GB起步。esJavaOptsJAVA堆内存参数注意跟容器limits里的memory要配套比如limit是4Gi堆给2g给系统和其他进程留一点余量。Kibana的values相对简单一些核心是把Elasticsearch地址指过去replicas: 1 elasticsearchHosts: http://elasticsearch-master:9200 resources: requests: cpu: 500m memory: 1Gi limits: cpu: 1000m memory: 2Gi这里elasticsearch-master是Helm默认创建的ES无头服务名Kibana部署在同一个命名空间下直接通过服务名访问即可不需要写IP。Filebeat的配置重点在采集路径daemonset: enabled: true filebeatConfig: filebeat.yml: | filebeat.autodiscover: providers: - type: kubernetes node: ${NODE_NAME} templates: - condition.equals: kubernetes.labels.app: nginx config: - type: container paths: - /var/log/containers/*.log output.elasticsearch: hosts: [${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}]这个配置的意思是让Filebeat通过自动发现机制监听K8s里的容器日志并把采集到的日志输出到ES。如果你不想做太细的过滤就直接简单指定/var/log/containers/*.log这个路径不区分应用统统采简单粗暴但有效。生产环境再按命名空间或标签维度做更精细的采集分流。3. 实操Helm部署EFK全流程3.1 先部署Elasticsearch正式部署前我习惯先创建独立的命名空间EFK所有组件放到同一个namespace里管理起来清爽kubectl create namespace efk然后执行安装命令指定自定义的values文件helm install es elastic/elasticsearch -f es-values.yaml -n efk如果安装过程没有报错正常情况下会看到一行输出提示release已创建。接着检查Pod状态kubectl get pods -n efk -l appelasticsearchES的启动过程是出了名的慢尤其是第一次启动要分配磁盘空间、分片初始化快则二三十秒慢则几分钟。这时候别急着到处找问题先等一会儿再看。等Pod状态变成Running且READY为1/1之后再检查一下ES集群状态kubectl exec -it es-elasticsearch-0 -n efk -- curl -s http://localhost:9200/_cluster/health?pretty健康状态返回green说明集群完全正常如果yellow说明有副本分片没就位单节点集群下这是常态不影响读写。如果返回red就要警惕说明主分片都没分配好大概率是存储或资源问题用后面第4节的方法排查。等ES就绪后把服务的相关信息记录下来后面Kibana和Filebeat都要依赖它。3.2 部署KibanaKibana安装比较简单但要先确认他能不能连通ES。直接执行helm install kibana elastic/kibana -f kibana-values.yaml -n efk kubectl get pods -n efk -l appkibanaKibana默认只把Service暴露在集群内部想通过浏览器访问的话需要做一层访问暴露。最省事的调试方式是用端口转发kubectl port-forward -n efk svc/kibana-kibana 5601:5601然后浏览器访问http://localhost:5601。如果看到Kibana欢迎页说明跟ES的连通没问题。生产环境不建议用port-forward更合理的做法是配置Ingress给Kibana绑定一个域名并加好认证网关避免裸暴露到公网。首次进入Kibana它会让你创建一个Index Pattern。这一步需要等Filebeat部署好、ES里开始产生日志之后再做不然index列表是空的你没东西可以选。3.3 部署FilebeatFilebeat以DaemonSet方式部署每个节点自动跑一个采集Pod专门收集该节点上所有容器写到宿主机目录里的日志文件helm install filebeat elastic/filebeat -f filebeat-values.yaml -n efk kubectl get pods -n efk -l appfilebeat正常情况下每个节点都会有一个Filebeat Pod处于Running状态。这里分享一个我常用的快速验证方法手动往命名空间里丢一个不断打印日志的测试Pod几秒钟之后去ES里查索引看有没有数据进来。kubectl run logtest --imagebusybox -n efk -- sh -c while true; do echo hello efk; sleep 1; done sleep 20 kubectl exec -it es-elasticsearch-0 -n efk -- curl -s http://localhost:9200/_cat/indices?v | grep filebeat如果你在_cat/indices输出中看到了filebeat-7.x.x-xxxx这样的索引说明日志链路已经全通了。这时候回到Kibana创建对应的Index Pattern然后在Discover页面搜索日志能看到刚才logtest打出来的大量hello efk记录整个EFK系统就算真正跑起来了。Filebeat的采集路径有一个高频踩坑点默认采集/var/log/containers/目录但如果Filebeat容器里没有对宿主机这个目录做hostPath挂载是什么都采不到的。用Helm安装官方chart通常会自动处理挂载但如果你自己改过values要留意挂载别丢了。3.4 多行日志的采集配置这里单独提一下多行日志的场景。Java应用的异常栈是典型的多行日志一条异常信息跨越好几行如果按默认的行规则采集每一行都会被打成一个独立的日志条目排查问题时整个堆栈被拆得七零八落体验非常差。Filebeat的解决办法是配置multiline规则。在filebeatConfig里加上多行合并的配置multiline: pattern: ^\d{4}-\d{2}-\d{2} negate: true match: after含义是以“4位数字-2位数字-2位数字”开头的行算一条日志的起始非这种格式的行就拼接到上一条日志后面。把这段配置加到filebeat.yml的input区域里重启Filebeat让配置生效再回Kibana看一条完整的Java异常栈就是一条日志记录了。4. 常见问题与排查技巧实录4.1 ES Pod一直Pending或CrashLoopBackOff这是最常见的问题没有之一。Pending的排查思路第2.1节已经提到过重点查PVCkubectl get pvc -n efkPVC状态如果是Pending多半是StorageClass的问题要么集群里没有这个存储类要么存储类本身绑定模式不对。还有一种容易被忽视的情况StorageClass是WaitForFirstConsumer模式PVC初始化会被延后到第一个Pod调度时触发但StatefulSet在调度Pod之前又会先等PVC绑定两边互相等最终就是卡死。解决办法是创建Pod前先手动预置PV或者把storageClassName换成Immediate绑定模式的存储类。CrashLoopBackOff则一般是资源申请过小、Pod启动时直接OOM或者esJavaOpts堆内存超过了容器limit。检查事件具体内容kubectl describe pod es-elasticsearch-0 -n efk看到OOMKilled就调大limits和堆内存看到failed to decode之类的启动参数错误就检查esJavaOpts的配置有没有写错。4.2 ES集群健康状态持续yellow/red单节点集群yellow很正常因为副本分片无处可放但这不代表系统不可用读写功能都正常。如果状态变红说明有主分片未分配原因一般是存储卷写满、节点掉线、分片分配数超限等。红状态先看未分配分片的原因kubectl exec -it es-elasticsearch-0 -n efk -- curl -s http://localhost:9200/_cluster/allocation/explain?pretty这个接口会直接告诉你哪些分片因为什么原因分配不了。如果是磁盘水位超过默认阈值清理索引腾空间即可如果是节点失联恢复节点后集群会自动重分配。只要看得到具体原因解决方向就很明确。4.3 Filebeat采集不到任何日志日志链路经常遇到“Filebeat看起来正常但ES里没有索引”的情况。我一般从三个方向排查先看Filebeat的采集日志有没有报错kubectl logs -n efk -l appfilebeat --tail50看到filebeat.autodiscover相关的错误大多是K8s的RBAC权限不够Filebeat没有权限读取Pod和节点信息。在values里开启对应的RBAC相关配置或者检查clusterrole有没有正确创建。检查路径挂载。Filebeat拿不到宿主机日志目录的内容最直接的表现就是日志里一直显示采集到0个文件。验证方法是在Filebeat的Pod里直接ls /var/log/containers/如果目录是空的说明hostPath挂载有问题。检查ES地址连通性。Filebeat配置里elasticsearch.hosts如果写成了localhost:9200连的自然是对面自己永远连不上ES。这里要用elasticsearch-master:9200这样的服务名地址。经历过几次采集问题之后我的经验是先把路径和连通性这两个基础项排除掉再深入RBAC之类的权限问题顺序不要反。4.4 Kibana页面一直显示“Unable to connect to Elasticsearch”这种问题通常不是Kibana本身的问题而是ES地址配错或ES侧网络不通。在Kibana Pod里直接测试kubectl exec -it kibana-kibana-xxxxx -n efk -- curl -s http://elasticsearch-master:9200看有没有JSON响应。如果超时不通检查Kibana所在的网络策略有没有放行到ES的9200端口流量。如果网络正常但ES返回401认证错误说明ES开了安全认证而Kibana的配置里没带用户名密码。Kibana的values里需要额外配置elasticsearch.username和elasticsearch.password字段。另外一个容易忽略的点是Kibana的版本跟ES版本差距过大比如ES是7.10Kibana是7.16虽然能连上但页面可能报兼容性错误。保持版本同系列是省心之道。4.5 索引数据占用增长过快日志系统跑起来之后如果不加任何管控索引会无限制增长很快把磁盘吃满。ES清洗和聚合台上很好用但存储空间就是钱。所以从落地第一天起就应该配好索引生命周期管理策略。在Kibana的Stack Management里可以创建Index Lifecycle Policy常见的策略是按天生成索引保存30天保留1个副本超过30天自动删除。同时给Filebeat配置对应的索引生命周期管理ID让新写入的索引自动套用策略。配置好之后磁盘占用基本就不会失控了。5. 调优与生产化建议5.1 资源量化参考EFK的资源规划可以按一套参考值起步再根据实际负载调整组件测试环境建议生产环境建议Elasticsearch data节点2C4G1节点8C16G起步至少2节点Elasticsearch master节点复用data节点4C8G3节点Kibana1C2G1节点2C4G2节点以上Filebeat0.25C1GDaemonSet每节点0.5C1GDaemonSet每节点ES的JVM堆内存建议不要超过31GB多数场景下控制在16GB以内反而GC表现更好。给ES Pod申请的内存limits建议设置为堆内存的1.5到2倍给Lucene的页缓存和系统本身留出空间。5.2 高可用与滚动升级生产环境的ES至少保证3个master节点这是避免脑裂的基础。data节点建议保持在2个以上保证索引副本能分配到不同节点。还要给副本数做好规划索引副本从1开始至少保证单节点故障时数据不丢。Helm升级版本时使用滚动升级策略ES节点会逐个重启。注意升级前先把集群健康状态调整为green否则滚动重启过程中有分片重新分配可能让整个集群长时间处于red/yellow状态。稳妥的做法是升级前先看一下集群健康再做helm upgrade观察第一个节点是否正常再加入别一次性升级跨度太大的版本。5.3 安全与访问控制默认部署EFKES和Kibana都是无认证的这在生产环境是绝对不允许的。建议开启xpack安全特性为ES创建内置用户账号Kibana和Filebeat都配置带认证的连接。Helm部署时可以通过values激活安全配置esJavaOpts: -Xms2g -Xmx2g extraEnvs: - name: xpack.security.enabled value: true - name: xpack.security.transport.ssl.enabled value: trueKibana端要配置对应的账号密码。另外网络层面如果用了服务网格或NetworkPolicy要确保只放行必要的端口和来源Kibana的访问尽量走Ingress网关加认证。5.4 日志接入面扩展EFK跑通之后最常做的扩展是把更多日志源接进来。不只是K8s容器日志还可以接入应用自定义日志应用里主动输出结构化JSON打到一个独立的文件路径Filebeat单独配一条采集链路解析时直接用原生的JSON字段Kibana里的搜索体验会好很多。集群节点日志宿主机上的系统日志、Kubelet日志等在Filebeat里额外加一条输入配置指定/var/log/syslog或/var/log/messages路径。审计日志如果合规要求比较严K8s的API审计日志也建议接进来方便追溯操作记录。每接入一种日志重点想清楚三件事日志路径在哪里、字段要不要清洗、索引如何分类。规划清楚之后再往Filebeat配置里加不要一股脑全采到同一个索引里后面定位问题会被字段混杂折腾得头疼。这趟EFK搭下来我最大的感受是技术选型上真没什么高深的东西用Helm搭建EFK的核心优势就是把繁杂的K8s编排细节收口进模板里真正需要你花心思的地方全在配置细节——版本对不对齐、存储卷通不通、资源给得合不合理、索引怎么滚动。按照上文这套流程走一遍你也能做到在半小时内从零跑通一条K8s日志采集链路。最后再分享一个实战小技巧部署完成后把用到的values.yaml文件单独存到你自己的配置仓库里标注好对应的chart版本和部署时间一方面方便版本回溯另一方面下次搭建同类环境时直接改几个参数就能复用省下大量重复性工作。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑