监控 Kubernetes 日志)
文档/教程【免费下载链接】90DaysOfDevOpsThis repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.项目地址https://gitcode.com/gh_mirrors/90/90DaysOfDevOps点击查看免费下载本文是 90DaysOfDevOps 可观测性系列的第 82 天教程核心任务是在 Minikube 单机集群中部署 EFK Stack 并采集、检索 Kubernetes 集群日志。前一篇第 81 天Fluentd 与 Fluent Bit介绍了统一日志层的概念而本篇将把日志采集器从 ELK 中的 Logstash 换成 Fluentd与 Elasticsearch、Kibana 组成 EFK 三件套并在 Kibana 中完成索引模式配置与日志可视化。读完本文你将掌握 EFK 各组件的角色分工、整套efk-stack.yaml清单的配置要点以及从集群启动到日志上屏的完整落地流程。EFK 是什么从 ELK 到 EFK 的组件更替在之前学习 ELK Stack 时日志采集环节由Logstash承担而在 EFK Stack 中我们把这个位置替换为Fluentd或更轻量的 Fluent Bit从而形成一条更贴合 Kubernetes 环境的日志流水线。EFK 同样是三款开源软件的组合Elasticsearch一种 NoSQL 数据库负责存储日志数据并提供搜索与查询日志的接口是整个链路中的存储与索引引擎。Fluentd开源的数据采集器面向统一日志层unified logging layer设计。它允许你统一数据的采集与消费方式从而更好地理解和使用数据是整个链路中的搬运工。Kibana面向日志的管理与统计界面负责从 Elasticsearch 读取数据并做可视化展示是整个链路中的可视化前端。如下方架构示意图所示三个组件都将被部署到名为kube-logging图中简写为efk的命名空间内并且各自使用了与其特性匹配的 Kubernetes 工作负载对象Fluentd → DaemonSet保证每个工作节点上都运行一个采集实例负责读取节点上各容器的日志Elasticsearch → StatefulSet有状态服务需要稳定的网络标识与持久存储与 StatefulSet 的语义天然匹配清单中副本数为 3Kibana → Deployment无状态 Web 应用可通过 Deployment 灵活管理副本。这条链路的典型数据流向为FluentdDaemonSet采集节点日志 → ElasticsearchStatefulSet存储与索引 → KibanaDeployment查询与可视化。部署前准备启动 Minikube 集群本教程沿用此前一直在用的 Minikube 单机集群。在原文档演示环境中作者使用开启了 WSL2 的 Windows 系统但命令本身与操作系统无关Linux / macOS / WSL2 环境均可直接照做minikube start集群就绪后我们就可以把 EFK 整套资源一次性送入集群。核心配置文件 efk-stack.yaml 逐段解析仓库中已经准备好了完整的部署清单 efk-stack.yaml一个文件涵盖命名空间、存储、Elasticsearch 有状态集群、Kibana 无状态应用以及 Fluentd 的 RBAC 与采集器。下面按资源类型逐一拆解其设计意图。1. 命名空间与 Elasticsearch 无头服务清单第一部分创建了专用命名空间kube-logging随后定义了一个Headless ServiceclusterIP: None。无头服务不提供负载均衡的 ClusterIP而是为 StatefulSet 的每个 Pod 建立稳定的 DNS 域名如es-cluster-0.elasticsearch这正是 Elasticsearch 节点间发现机制的基础kind: Namespace apiVersion: v1 metadata: name: kube-logging --- kind: Service apiVersion: v1 metadata: name: elasticsearch namespace: kube-logging labels: app: elasticsearch spec: selector: app: elasticsearch clusterIP: None ports: - port: 9200 name: rest # REST 查询接口 - port: 9300 name: inter-node # 节点间通信接口2. Elasticsearch StatefulSet 与数据持久化接下来是 EFK 的存储核心一个 3 副本的 Elasticsearch StatefulSet并配套了本地持久卷与volumeClaimTemplates动态申请存储apiVersion: v1 kind: PersistentVolume metadata: name: data labels: type: elasticsearch spec: storageClassName: standard capacity: storage: 50Gi accessModes: - ReadWriteMany hostPath: path: /mnt/data --- apiVersion: apps/v1 kind: StatefulSet metadata: name: es-cluster namespace: kube-logging spec: serviceName: elasticsearch replicas: 3 selector: matchLabels: app: elasticsearch template: metadata: labels: app: elasticsearch spec: containers: - name: elasticsearch image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0 resources: limits: cpu: 1000m requests: cpu: 100m ports: - containerPort: 9200 name: rest protocol: TCP - containerPort: 9300 name: inter-node protocol: TCP volumeMounts: - name: data mountPath: /usr/share/elasticsearch/data env: - name: cluster.name value: k8s-logs - name: node.name valueFrom: fieldRef: fieldPath: metadata.name - name: discovery.seed_hosts value: es-cluster-0.elasticsearch,es-cluster-1.elasticsearch,es-cluster-2.elasticsearch - name: cluster.initial_master_nodes value: es-cluster-0,es-cluster-1,es-cluster-2 - name: ES_JAVA_OPTS value: -Xms512m -Xmx512m关键配置点说明discovery.seed_hosts通过无头服务域名列出三个候选节点es-cluster-0.elasticsearch等让各节点能互相发现形成集群cluster.initial_master_nodes列出可参与首次选主的节点名用于引导 7.x 版本的集群初始化ES_JAVA_OPTS设置 JVM 堆大小为 512MB-Xms512m -Xmx512m在 Minikube 这类资源有限的单机环境里是合理的内存控制volumeClaimTemplates每个 Pod 会按模板动态申请一块5Gi的 PVCaccessModes: ReadWriteOnce并挂载到/usr/share/elasticsearch/data。StatefulSet 中还有一组重要的initContainers初始化容器它们先于主容器执行负责解决 Elasticsearch 在容器化环境中的常见启动前置问题initContainers: - name: fix-permissions image: busybox command: [sh, -c, chown -R 1000:1000 /usr/share/elasticsearch/data] securityContext: privileged: true volumeMounts: - name: data mountPath: /usr/share/elasticsearch/data - name: increase-vm-max-map image: busybox command: [sysctl, -w, vm.max_map_count262144] securityContext: privileged: true - name: increase-fd-ulimit image: busybox command: [sh, -c, ulimit -n 65536] securityContext: privileged: true三个初始化容器的职责分别是将数据目录属主修正为 Elasticsearch 容器内运行用户UID 1000调大内核参数vm.max_map_count到 262144Elasticsearch 启动的必要条件提高文件描述符上限ulimit -n到 65536。这三个问题正是容器化部署 Elasticsearch 时最常见的坑清单通过 initContainers 自动规避。3. Kibana 的 Service 与 DeploymentKibana 以 Deployment 形式部署副本数为 1通过环境变量ELASTICSEARCH_URL指向 Elasticsearch 服务的集群内地址apiVersion: v1 kind: Service metadata: name: kibana namespace: kube-logging labels: app: kibana spec: ports: - port: 5601 selector: app: kibana --- apiVersion: apps/v1 kind: Deployment metadata: name: kibana namespace: kube-logging labels: app: kibana spec: replicas: 1 selector: matchLabels: app: kibana template: metadata: labels: app: kibana spec: containers: - name: kibana image: docker.elastic.co/kibana/kibana:7.2.0 resources: limits: cpu: 1000m requests: cpu: 100m env: - name: ELASTICSEARCH_URL value: http://elasticsearch:9200 ports: - containerPort: 5601注意 Kibana 与 Elasticsearch 使用相同的 7.2.0 镜像版本保持版本一致可避免兼容性问题Service 暴露 5601 端口供后续kubectl port-forward转发到本地浏览器访问。4. Fluentd 的 RBAC 与 DaemonSetFluentd 要读取每个节点上所有容器的日志因此需要三类配套资源ServiceAccount为 Fluentd Pod 提供集群身份ClusterRole / ClusterRoleBinding授予get / list / watchPod 与 Namespace 的权限apiGroups: 即核心组以便 Fluentd 从 Kubernetes API Server 获取元数据DaemonSet确保每个节点都有一个 Fluentd Pod 采集本地日志。apiVersion: v1 kind: ServiceAccount metadata: name: fluentd namespace: kube-logging labels: app: fluentd --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: fluentd labels: app: fluentd rules: - apiGroups: - resources: - pods - namespaces verbs: - get - list - watch --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: fluentd roleRef: kind: ClusterRole name: fluentd apiGroup: rbac.authorization.k8s.io subjects: - kind: ServiceAccount name: fluentd namespace: kube-logging --- apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd namespace: kube-logging labels: app: fluentd spec: selector: matchLabels: app: fluentd template: metadata: labels: app: fluentd spec: serviceAccount: fluentd serviceAccountName: fluentd tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: fluentd image: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1 env: - name: FLUENT_ELASTICSEARCH_HOST value: elasticsearch.kube-logging.svc.cluster.local - name: FLUENT_ELASTICSEARCH_PORT value: 9200 - name: FLUENT_ELASTICSEARCH_SCHEME value: http - name: FLUENTD_SYSTEMD_CONF value: disable resources: limits: memory: 512Mi requests: cpu: 100m memory: 200Mi volumeMounts: - name: varlog mountPath: /var/log - name: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true terminationGracePeriodSeconds: 30 volumes: - name: varlog hostPath: path: /var/log - name: varlibdockercontainers hostPath: path: /var/lib/docker/containersFluentd 镜像选用官方专为 Kubernetes DaemonSet 场景构建的fluent/fluentd-kubernetes-daemonset变体内置 Elasticsearch 输出插件。配置要点FLUENT_ELASTICSEARCH_HOST通过集群内 DNS 全名elasticsearch.kube-logging.svc.cluster.local指向 Elasticsearch 服务端口 9200协议 httpFLUENTD_SYSTEMD_CONF置为disable关闭默认的 systemd 日志采集聚焦容器日志hostPath卷将宿主机的/var/log与/var/lib/docker/containers目录挂载进容器后者只读这正是 Fluentd 读取每个节点上容器标准输出日志的路径来源tolerations允许 DaemonSet Pod 调度到 master 节点保证在单节点 Minikube 上也能完整覆盖日志采集。一键部署将 EFK 全套资源送入集群清单准备好后用kubectl create -f一次性创建全部资源kubectl create -f efk-stack.yaml命令执行后Kubernetes 会按清单顺序创建命名空间、服务、持久卷、StatefulSet、Deployment、RBAC 资源与 DaemonSet。接下来需要等待镜像拉取与 Pod 启动。观察 Pod 就绪状态首次部署需要从镜像仓库拉取 Elasticsearch、Kibana、Fluentd 等镜像整个过程可能需要几分钟。用 watch 模式持续观察kubectl get pods -n kube-logging -w等所有 Pod 变为Running且READY列显示就绪后再执行一次不带-w的确认命令确保状态稳定kubectl get pods -n kube-logging正常完成后kube-logging命名空间内应看到3 个 Elasticsearch Pod对应es-clusterStatefulSet 的 3 个副本1 个 Fluentd Pod单节点 Minikube 上 DaemonSet 只产生一个实例1 个 Kibana Pod对应 kibana Deployment。用 kubectl get all 验证工作负载类型如果想一次性查看命名空间内的全部资源可以执行kubectl get all -n kube-logging输出中能直观印证三类组件的部署形态差异Fluentd 以DaemonSet形式存在每个节点一个Kibana 是Deployment而 Elasticsearch 则是StatefulSet——这与前文架构图中的设计一一对应。通过 port-forward 访问 Kibana 并创建索引模式端口转发到本地集群内服务默认不暴露到外部需要在新的终端中执行端口转发把 Kibana 的 5601 端口映射到本地kubectl port-forward kibana-84cf7f59c-v2l8v 5601:5601 -n kube-logging注意命令中的 Pod 名称是示例不同环境下 Pod 名随机后缀会不一样请先用kubectl get pods -n kube-logging查到实际的 Kibana Pod 名再替换。转发成功后在浏览器中访问http://localhost:5601首次打开会进入 Kibana 欢迎页如果环境里预置了示例数据也可能先看到样例数据引导页。无论是哪种情况都可以先浏览这些测试数据——它们正是此前学习 ELK Stack 时生成的内容。创建索引模式Index Pattern日志要能在 Kibana 中被检索必须先定义一个索引模式点击左侧菜单的Discover发现标签页在索引模式名称输入框中填入*匹配所有 Elasticsearch 索引点击Next step下一步在Step 2 of 2中从下拉框选择timestamp作为时间筛选字段——这样 Kibana 会按时间维度过滤和排序日志数据点击Create index pattern创建索引模式此操作可能需要几秒钟完成。索引模式创建成功后稍等几秒再回到Discover标签页就能看到来自 Kubernetes 集群的日志数据源源不断地流入每条记录都带有时间戳并包含 Fluentd 从各容器采集到的日志内容与 Kubernetes 元数据。在 Kibana 中扩展更多数据源EFK 链路跑通后日志已经通过 Fluentd 汇聚到 Elasticsearch 并由 Kibana 呈现。回到 Kibana 首页点击左上角 Kibana 图标可以看到 Kibana 7.x 提供多种数据接入能力包括APM应用性能监控、日志数据、指标数据、安全事件等可通过插件或其他数据源接入选择Add log data添加日志数据会出现大量可选日志来源其中也包括 ELK 体系中的Logstash——这说明 EFK 与 ELK 并非互斥Kibana 可以同时消费来自 Fluentd 与 Logstash 的日志在指标数据Metrics分类下可以接入Prometheus等多种监控服务与日志数据互补构建更完整的可观测性视图。补充APM应用性能监控APMApplication Performance Monitoring是另一类可选的观测能力它从应用内部采集深入的性能指标与错误信息支持实时监控大量应用的运行表现。本教程不展开 APM 的具体接入细节但其核心价值在于与集群级日志监控相比APM 能够提供更贴近业务代码的链路追踪与性能剖析视角。小结与仓库资源导航至此我们完成了在 Minikube 上从零部署 EFK Stack 的全流程理解了 EFK 相对 ELK 的组件差异逐段解析了 efk-stack.yaml 中命名空间、Headless Service、StatefulSet 持久化、初始化容器、Kibana Deployment 与 Fluentd RBAC/DaemonSet 的配置细节并通过kubectl create -f、Pod 状态观察、端口转发与索引模式创建最终在 Kibana 的 Discover 页面实时检索到了 Kubernetes 集群日志。想继续深入本主题可以在仓库中找到以下配套资料第 81 天Fluentd 与 Fluent Bit统一日志层概念、Fluent Bit 的 Kubernetes 部署方式与其 ConfigMap 配置示例是理解本篇采集器的前置知识efk-stack.yaml 完整清单本文所有配置段的原始出处可直接用于实操Elastic Stack 示例工程此前 ELK 章节使用的 Docker Compose 编排可对照理解 EFK 与 ELK 两套方案在采集器上的差异。下一步可继续阅读 第 83 天进入可观测性主题的后续内容。赞分享文档/教程【免费下载链接】90DaysOfDevOpsThis repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.项目地址https://gitcode.com/gh_mirrors/90/90DaysOfDevOps点击查看免费下载相关推荐90DaysOfDevOps 实战篇在 Minikube 上部署 EFK Stack用 Elasticsearch Fluentd Kibana 统一监控 Kubernetes 日志90DaysOfDevOps 实战篇在 Minikube 上部署 EFK Stack用 Elasticsearch Fluentd Kibana 统文档/教程Kubernetes 集群日志监控实战基于 90DaysOfDevOps 在 Minikube 上部署 EFK StackElasticsearch Fluentd KibanaKubernetes 集群日志监控实战基于 90DaysOfDevOps 在 Minikube 上部署 EFK StackElasticsearch F文档/教程90DaysOfDevOps使用 EFK StackElasticsearch Fluentd Kibana监控 Kubernetes 日志实战90DaysOfDevOps使用 EFK StackElasticsearch Fluentd Kibana监控 Kubernetes 日志实战文档/教程上一篇基于nodemcu-firmware的环境监测节点传感器数据采集方案下一篇模板方法模式实战解读 LoadingAndRetryManager 的 OnLoadingAndRetryListener 设计之美创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考