4. Helm 部署日志平台:使用 Helm 部署 Elasticsearch、Fluentd、Kibana(EFK)到 Kubernetes 集群
本章将带领你使用 Helm 在 Kubernetes 集群中一键部署完整的 EFK 日志栈。EFK 是 Elasticsearch、Fluentd、Kibana 的缩写,是目前云原生环境下最主流的日志采集、存储与可视化方案。通过 Helm Chart 的标准化封装,我们可以将原本复杂的组件依赖、配置注入、资源声明统一管理,实现可重复、可版本化的日志平台交付。
4.1 EFK 架构与组件职责
在开始部署之前,需要明确 EFK 三个核心组件的分工与数据流向。下图展示了 EFK 在 Kubernetes 集群中的典型部署架构:
架构要点:Fluentd 以 DaemonSet 模式运行在每个 Node 上,采集容器标准输出和日志文件;Elasticsearch 以 StatefulSet 部署保证数据持久化与有序扩缩容;Kibana 作为无状态前端 Deployment 对外提供 Web 界面。Helm Chart 将这三者的 Service、ConfigMap、PVC 等附属资源统一打包。
4.2 选择 Helm Chart 与版本约束
社区维护的 EFK Helm Chart 主要有两个来源:Elastic 官方 Helm Charts 和 Bitnami 仓库。生产环境推荐使用 Elastic 官方 Chart,版本兼容性更可靠。下表对比了核心组件的版本选型建议:
| 组件 | 推荐 Chart 名称 | 推荐版本 | Kubernetes 最低版本 | 说明 |
|---|---|---|---|---|
| Elasticsearch | elastic/elasticsearch | 8.5.x | 1.21+ | 支持安全认证、TLS 默认开启 |
| Fluentd | fluent/fluentd | 0.5.x | 1.19+ | 需配置 Elasticsearch 输出插件 |
| Kibana | elastic/kibana | 8.5.x | 1.21+ | 版本需与 ES 大版本一致 |
版本对齐警告:Elasticsearch 与 Kibana 的主版本号必须严格一致(例如 8.x 对 8.x),否则 Kibana 无法连接 ES。Fluentd 的 elasticsearch 插件版本也需要与 ES 版本兼容。建议在 values.yaml 中显式锁定 image tag。
4.3 部署 Elasticsearch
Elasticsearch 是 EFK 的存储核心,需要合理配置资源、存储和集群拓扑。以下是使用 Helm 部署 ES 的完整步骤。
4.3.1 添加 Helm 仓库并更新
# 添加 Elastic 官方 Helm 仓库
helm repo add elastic https://helm.elastic.co
# 添加 Fluentd 社区仓库
helm repo add fluent https://fluent.github.io/helm-charts
# 更新本地仓库索引
helm repo update
4.3.2 创建 Elasticsearch values 文件
创建一个 es-values.yaml 文件,覆盖默认配置以适应生产环境需求:
# es-values.yaml
clusterName: "efk-logging"
nodeGroup: "data"
replicas: 3
resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
volumeClaimTemplate:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 50Gi
storageClassName: "gp2" # 根据集群存储类调整
esConfig:
elasticsearch.yml: |
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.http.ssl.enabled: true
extraEnvs:
- name: ELASTIC_PASSWORD
valueFrom:
secretKeyRef:
name: elasticsearch-master-credentials
key: password
4.3.3 执行 Helm 安装
# 创建命名空间
kubectl create namespace logging
# 部署 Elasticsearch
helm install elasticsearch elastic/elasticsearch \
--namespace logging \
--values es-values.yaml \
--version 8.5.1
部署验证:使用
kubectl get pods -n logging -w 观察 Pod 启动状态。Elasticsearch StatefulSet 会按顺序启动,每个 Pod 就绪后才会启动下一个。全部就绪后,使用 kubectl exec -it elasticsearch-master-0 -n logging -- curl -u elastic:${PASSWORD} https://localhost:9200 测试集群健康状态。
4.4 部署 Fluentd
Fluentd 负责从每个节点采集容器日志,解析后发送到 Elasticsearch。我们需要配置日志源路径、解析规则和输出目标。
4.4.1 创建 Fluentd values 文件
# fluentd-values.yaml
image:
repository: fluent/fluentd-kubernetes-daemonset
tag: "v1.16-debian-elasticsearch8-1"
configMaps:
fluentd.conf: |
<source>
@type tail
path /var/log/containers/*.log
pos_file /var/log/fluentd-containers.log.pos
tag kubernetes.*
read_from_head true
<parse>
@type json
time_format %Y-%m-%dT%H:%M:%S.%NZ
</parse>
</source>
<filter kubernetes.**>
@type kubernetes_metadata
@id filter_kube_metadata
</filter>
<match kubernetes.**>
@type elasticsearch
host elasticsearch-master.logging.svc.cluster.local
port 9200
scheme https
ssl_verify false
user "#{ENV['ES_USER']}"
password "#{ENV['ES_PASSWORD']}"
logstash_format true
logstash_prefix kubernetes-logs
<buffer>
@type file
path /var/log/fluentd-buffers/kubernetes.system.buffer
flush_mode interval
retry_type exponential_backoff
flush_interval 5s
</buffer>
</match>
env:
- name: ES_USER
value: "elastic"
- name: ES_PASSWORD
valueFrom:
secretKeyRef:
name: elasticsearch-master-credentials
key: password
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 1
memory: 1Gi
4.4.2 部署 Fluentd
helm install fluentd fluent/fluentd \
--namespace logging \
--values fluentd-values.yaml \
--version 0.5.2
日志采集路径说明:Fluentd 默认采集
/var/log/containers/*.log,这是 kubelet 将容器标准输出重定向到节点的默认路径。如果你的集群使用不同的容器运行时(如 containerd),路径可能为 /var/log/pods/*/*/*.log,需要在 source 配置中调整。
4.5 部署 Kibana
Kibana 提供日志查询和可视化的 Web 界面。部署时需要配置 Elasticsearch 连接信息。
4.5.1 创建 Kibana values 文件
# kibana-values.yaml
imageTag: "8.5.1"
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "1"
memory: "2Gi"
kibanaConfig:
kibana.yml: |
server.name: kibana
server.host: "0.0.0.0"
elasticsearch.hosts: ["https://elasticsearch-master.logging.svc.cluster.local:9200"]
elasticsearch.username: elastic
elasticsearch.password: ${ELASTIC_PASSWORD}
elasticsearch.ssl.verificationMode: none
extraEnvs:
- name: ELASTIC_PASSWORD
valueFrom:
secretKeyRef:
name: elasticsearch-master-credentials
key: password
service:
type: ClusterIP
port: 5601
ingress:
enabled: true
className: "nginx"
hosts:
- host: kibana.logging.example.com
paths:
- path: /
pathType: Prefix
4.5.2 部署 Kibana
helm install kibana elastic/kibana \
--namespace logging \
--values kibana-values.yaml \
--version 8.5.1
4.6 验证 EFK 整体连通性
部署完成后,需要从数据采集、存储到可视化的全链路验证。下表列出了关键验证点:
| 验证步骤 | 命令 / 操作 | 预期结果 |
|---|---|---|
| 检查所有 Pod 状态 | kubectl get pods -n logging |
所有 Pod 处于 Running 状态,READY 列为 1/1 |
| 验证 ES 集群健康 | kubectl exec -it elasticsearch-master-0 -n logging -- curl -u elastic:${PASS} -k https://localhost:9200/_cluster/health |
返回 status: "green" 或 "yellow" |
| 检查 Fluentd 日志输出 | kubectl logs -n logging -l app.kubernetes.io/name=fluentd --tail=20 |
无连接 ES 报错,显示成功发送日志的日志行 |
| 验证 ES 索引创建 | curl -u elastic:${PASS} -k https://localhost:9200/_cat/indices |
存在以 kubernetes-logs- 开头的索引 |
| Kibana 访问 | 浏览器打开 https://kibana.logging.example.com |
Kibana 登录页面正常加载,使用 elastic 用户登录 |
| 创建索引模式 | Kibana → Stack Management → Index Patterns → 创建 kubernetes-logs-* |
Discover 页面显示采集到的容器日志 |
根因定位前置准备:验证通过后,建议在 Kibana 中创建几个常用的 Dashboard(如 Pod 日志量趋势、错误日志分布、特定 Namespace 日志聚合),为后续根因定位章节的实战操作打好数据可视化基础。
4.7 常见部署问题与排错
Helm 部署 EFK 过程中可能遇到以下典型问题,提前了解有助于快速定位:
- Elasticsearch Pod 启动失败(CrashLoopBackOff):检查 PVC 是否绑定成功,
kubectl describe pvc -n logging查看 Events;确认 StorageClass 是否存在且可用;检查节点资源是否满足 requests 配置。 - Fluentd 无法连接 Elasticsearch:确认 ES Service 名称和端口正确;检查 Secret 中的密码是否与 ES 初始化密码一致;如果 ES 启用了 TLS,Fluentd 配置中需要设置
scheme https和ssl_verify false。 - Kibana 页面 503 错误:Kibana 启动时需等待 ES 完全就绪;检查 Kibana 日志
kubectl logs -n logging deployment/kibana-kibana查看具体连接错误;确认elasticsearch.hosts配置的 URL 协议和端口正确。 - 日志索引未创建:Fluentd 的
logstash_prefix配置决定了索引名称;检查 Fluentd 日志中是否有400或403响应码,可能是 ES 安全认证配置问题。
安全注意事项:Elasticsearch 8.x 默认启用了安全功能,首次启动时会自动生成 elastic 用户的密码。使用
kubectl get secret elasticsearch-master-credentials -n logging -o jsonpath="{.data.password}" | base64 -d 获取密码。生产环境中建议使用 Vault 或 External Secrets Operator 管理凭证,避免明文存储在 values 文件中。