当前位置: 首页 > news >正文

基于Kubernetes编排部署EFK日志收集系统

基于K8S编排部署EFK日志收集系统

案例分析

1. 规划节点

节点规划,见表1。

表1 节点规划

IP主机名k8s版本信息
192.168.100.3masterv1.25.2
192.168.100.4nodev1.25.2
2. 基础准备

Kubernete环境已安装完成,将提供的软件包efk-img.tar.gz上传至master节点/root目录下并解压。

3. EFK简介

EFK日志收集系统

EFK 代表 Elasticsearch、Fluentd 和 Kibana。EFK 是 Kubernetes 日志聚合和分析的常用且最佳的开源选择。

  1. Elasticsearch 是一种分布式且可扩展的搜索引擎,通常用于筛选大量日志数据。它是一个基于 Lucene 搜索引擎(来自 Apache 的搜索库)的 NoSQL 数据库。它的主要工作是存储日志并从 fluentd 检索日志。
  2. Fluentd 是一家原木运输商。它是一个开源的日志收集代理,支持多种数据源和输出格式。此外,它还可以将日志转发到 Stackdriver、Cloudwatch、elasticsearch、Splunk、Bigquery 等解决方案。简而言之,它是生成日志数据的系统和存储日志数据的系统之间的统一层。
  3. Kibana 是用于查询、数据可视化和仪表板的 UI 工具。它是一个查询引擎,允许您通过 Web 界面浏览日志数据,为事件日志构建可视化效果,特定于查询以筛选信息以检测问题。您可以使用 Kibana 虚拟构建任何类型的仪表板。Kibana 查询语言 (KQL) 用于查询 Elasticsearch 数据。在这里,我们使用 Kibana 在 Elasticsearch 中查询索引数据

案例实施

1. 基础环境准备
(1)导入软件包
[root@master ~]# nerdctl load -i efk-img.tar.gz

查看集群状态:

[root@master ~]# kubectl cluster-info
Kubernetes control plane is running at https://apiserver.cluster.local:6443
CoreDNS is running at https://apiserver.cluster.local:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxyTo further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
2. 配置StorageClass 动态绑定
(1)配置NFS Server端
[root@master ~]# yum install -y nfs-utils rpcbind

设置 NFS 服务开机自启

[root@master ~]# systemctl enable nfs rpcbind --now

创建EFK共享目录

[root@master ~]# mkdir -p /root/data/
[root@master ~]# chmod -R 777 /root/data/

编辑 NFS 配置文件

[root@master ~]# vim /etc/exports
/root/data/ *(rw,sync,no_all_squash,no_root_squash)

刷新 NFS 导出列表并启动 NFS 服务

[root@master ~]# exportfs -r
[root@master ~]# systemctl restart nfs

查看 NFS 共享的导出状态

[root@master ~]# showmount -e
Export list for master:
/root/data *
(2)创建ServiceAccount并配置RBAC

创建目录存放EFK配置文件

[root@master ~]# mkdir efk
[root@master ~]# cd efk/

编写 rbac 配置文件

[root@master efk]# vim rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisioner---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:name: leader-locking-nfs-client-provisioner
rules:
- apiGroups:- ""resources:- endpointsverbs:- get- list- watch- create- update- patch---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: leader-locking-nfs-client-provisioner
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: leader-locking-nfs-client-provisioner
subjects:
- kind: ServiceAccountname: nfs-client-provisionernamespace: default---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: nfs-client-provisioner-runner
rules:
- apiGroups:- ""resources:- persistentvolumesverbs:- get- list- watch- create- delete
- apiGroups:- ""resources:- persistentvolumeclaimsverbs:- get- list- watch- update
- apiGroups:- ""resources:- endpointsverbs:- get- list- watch- create- update- patch
- apiGroups:- storage.k8s.ioresources:- storageclassesverbs:- get- list- watch
- apiGroups:- ""resources:- eventsverbs:- create- update- patch
- apiGroups:- ""resources:- pods- namespacesverbs:- get- list- watch---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: run-nfs-client-provisioner
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: nfs-client-provisioner-runner
subjects:
- kind: ServiceAccountname: nfs-client-provisionernamespace: default

部署 rbac 文件

[root@master efk]# kubectl apply -f rbac.yaml
(3)配置NFS Provisioner

导入镜像包

[root@master ~]# nerdctl -n k8s.io load -i nfs-subdir-external-provisioner-v4.0.2.tar

编写 nfs 配置文件

[root@master efk]# vim nfs-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nfs-client-provisioner  # 部署对象名称为 nfs-client-provisionernamespace: default  # 部署在 default 命名空间
spec:replicas: 1  # 副本数量为 1selector:matchLabels:app: nfs-client-provisioner  # 选择带有此标签的 Podtemplate:metadata:labels:app: nfs-client-provisioner  # 为 Pod 设置标签spec:serviceAccountName: nfs-client-provisioner  # 使用 nfs-client-provisioner 服务账号containers:- name: nfs-client-provisioner  # 容器名称为 nfs-client-provisionerimage: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2  # 使用指定版本的 NFS provisioner 镜像imagePullPolicy: IfNotPresentenv:- name: PROVISIONER_NAME  # 设置环境变量 PROVISIONER_NAMEvalue: nfs.client.com  # 环境变量的值为 nfs.client.com- name: NFS_SERVER  # 设置 NFS 服务端地址value: 192.168.100.3  # 替换为实际的 NFS 服务端 IP 地址- name: NFS_PATH  # 设置 NFS 共享目录路径value: /root/data/  # 替换为实际的 NFS 共享目录路径volumeMounts:- name: nfs-client-root  # 数据卷挂载点名称mountPath: /persistentvolumes  # 容器内的挂载路径volumes:- name: nfs-client-root  # 定义 NFS 数据卷nfs:server: 192.168.100.3  # 替换为实际的 NFS 服务端 IP 地址path: /root/data/  # 替换为实际的 NFS 共享目录路径径

部署 nfs 文件

[root@master efk]# kubectl apply -f nfs-deployment.yaml

查看 Pod 运行状态

[root@master efk]# kubectl get pod
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-76fdd7948b-2n9wv   1/1     Running   0          2s
(4)配置StorageClass动态绑定
[root@master efk]# vim storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: managed-nfs-storage  # StorageClass 名称为 managed-nfs-storageannotations:storageclass.kubernetes.io/is-default-class: "true"  # 使用 annotations 指定为默认 StorageClass
provisioner: nfs.client.com  # 设置 Provisioner 为 nfs.client.com,对应 NFS Provisioner
parameters:archiveOnDelete: "false"  # 当 PVC 被删除时,NFS 上的持久卷不会被自动删除

部署 StorageClass 文件

[root@master efk]# kubectl apply -f storageclass.yaml
3. 配置EFK
(1)配置Elasticsearch
[root@master efk]# vim elasticsearch.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:name: es-cluster
spec:serviceName: elasticsearchreplicas: 3selector:matchLabels:app: elasticsearchtemplate:metadata:labels:app: elasticsearchspec:serviceAccountName: nfs-client-provisioner # 使用 NFS 服务账号提供卷服务initContainers:- name: fix-permissionsimage: busyboximagePullPolicy: IfNotPresentcommand: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"]securityContext:privileged: truevolumeMounts:- name: elasticsearch-datamountPath: /usr/share/elasticsearch/data- name: increase-vm-max-mapimage: busyboximagePullPolicy: IfNotPresentcommand: ["sysctl", "-w", "vm.max_map_count=262144"]securityContext:privileged: true- name: increase-fd-ulimitimage: busyboximagePullPolicy: IfNotPresentcommand: ["sh", "-c", "ulimit -n 65536"]securityContext:privileged: truecontainers:- name: elasticsearchimage: docker.elastic.co/elasticsearch/elasticsearch:7.2.0imagePullPolicy: IfNotPresentresources:limits:cpu: 1000mrequests:cpu: 100mports:- containerPort: 9200name: restprotocol: TCP- containerPort: 9300name: inter-nodeprotocol: TCPvolumeMounts:- name: elasticsearch-datamountPath: /usr/share/elasticsearch/dataenv:- name: cluster.namevalue: k8s-logs- name: node.namevalueFrom:fieldRef:fieldPath: metadata.name- name: discovery.seed_hostsvalue: "es-cluster-0.elasticsearch,es-cluster-1.elasticsearch,es-cluster-2.elasticsearch"- name: cluster.initial_master_nodesvalue: "es-cluster-0,es-cluster-1,es-cluster-2"- name: ES_JAVA_OPTSvalue: "-Xms512m -Xmx512m"volumeClaimTemplates:- metadata:name: elasticsearch-datalabels:app: elasticsearchannotations:volume.beta.kubernetes.io/storage-class: "managed-nfs-storage" # 存储类的名称,使用 NFS 存储spec:accessModes: [ "ReadWriteOnce" ]resources:requests:storage: 100Gi

部署 elasticsearch-sts 文件

[root@master efk]# kubectl apply -f elasticsearch.yaml

查看 Pod 运行状态

[root@master efk]# kubectl get pod
NAME                                      READY   STATUS    RESTARTS   AGE
es-cluster-0                              1/1     Running   0          17s
es-cluster-1                              1/1     Running   0          13s
es-cluster-2                              1/1     Running   0          7s
nfs-client-provisioner-79865487f9-tnssn   1/1     Running   0          5m29s

配置 service 文件

[root@master efk]# vim elasticsearch-svc.yaml
apiVersion: v1
kind: Service
metadata:name: elasticsearchlabels:app: elasticsearch
spec:selector:app: elasticsearchclusterIP: Noneports:- port: 9200name: rest- port: 9300name: inter-node

部署 service 文件

[root@master efk]# kubectl apply -f elasticsearch-svc.yaml

查看 service

[root@master efk]# kubectl get svc
NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)             AGE
elasticsearch   ClusterIP   None         <none>        9200/TCP,9300/TCP   3s
kubernetes      ClusterIP   10.96.0.1    <none>        443/TCP             7d19h

验证 Elasticsearch 部署 开启端口转发

[root@master efk]# kubectl port-forward es-cluster-0 9200:9200

打开一个新的 Terminal 窗口,以便我们可以查询 REST API 接口

[root@master efk]# curl -XGET 'localhost:9200/_cluster/health?pretty'
{"cluster_name": "k8s-logs",  // 集群的名称为 "k8s-logs""status": "green",           // 集群状态为 "green",表示所有的主分片和副本分片都正常。"timed_out": false,          // 表示查询没有超时。"number_of_nodes": 3,        // 集群中有 3 个节点。"number_of_data_nodes": 3,   // 集群中有 3 个数据节点,表明这些节点存储数据。"active_primary_shards": 1,  // 当前活跃的主分片数量为 1"active_shards": 2,          // 当前活跃的分片总数为 2(包括主分片和副本分片)。"relocating_shards": 0,      // 当前没有正在重新分配的分片。"initializing_shards": 0,    // 当前没有初始化的分片。"unassigned_shards": 0,      // 当前没有未分配的分片,意味着所有分片都已分配给节点。"delayed_unassigned_shards": 0, // 当前没有延迟的未分配分片。"number_of_pending_tasks": 0, // 当前没有待处理的任务。"number_of_in_flight_fetch": 0, // 当前没有正在进行的获取请求。"task_max_waiting_in_queue_millis": 0, // 当前没有任务在队列中等待,表示没有延迟。"active_shards_percent_as_number": 100.0 // 活跃分片百分比为 100,表示所有分片都处于活跃状态。
}

测试 headless 域名解析

### 创建测试Pod
[root@master efk]# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:name: nslookup
spec:containers:- name: dataimage: busyboximagePullPolicy: IfNotPresentargs:- /bin/sh- -c- sleep 36000

部署 Pod 文件

[root@master efk]# kubectl apply -f pod.yaml

测试解析

[root@master efk]# kubectl exec -it nslookup -- sh
/ # nslookup es-cluster-0.elasticsearch.default.svc.cluster.local
Server:		10.96.0.10
Address:	10.96.0.10:53Name:	es-cluster-0.elasticsearch.default.svc.cluster.local
Address: 10.244.0.18/ # nslookup elasticsearch.default.svc.cluster.local
Server:		10.96.0.10
Address:	10.96.0.10:53Name:	elasticsearch.default.svc.cluster.local
Address: 10.244.0.18
Name:	elasticsearch.default.svc.cluster.local
Address: 10.244.0.20
Name:	elasticsearch.default.svc.cluster.local
Address: 10.244.0.21
(2)配置Kibana
[root@master efk]# vim kibana.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: kibanalabels:app: kibana
spec:replicas: 1selector:matchLabels:app: kibanatemplate:metadata:labels:app: kibanaspec:containers:- name: kibanaimage: docker.elastic.co/kibana/kibana:7.2.0imagePullPolicy: IfNotPresentports:- containerPort: 5601resources:limits:cpu: 1000mrequests:cpu: 100menv:- name: ELASTICSEARCH_URLvalue: http://elasticsearch.default.svc.cluster.local:9200

部署 kibana 文件

[root@master efk]# kubectl apply -f kibana.yaml

查看 Pod 运行状态

[root@master efk]# kubectl get pod
NAME                                      READY   STATUS    RESTARTS   AGE
es-cluster-0                              1/1     Running   0          3m30s
es-cluster-1                              1/1     Running   0          3m26s
es-cluster-2                              1/1     Running   0          3m20s
kibana-774758dd6c-r5c9s                   1/1     Running   0          3s
nfs-client-provisioner-79865487f9-tnssn   1/1     Running   0          8m42s

配置 service 文件

[root@master efk]# vim kibana-svc.yaml
apiVersion: v1
kind: Service
metadata:name: kibanalabels:app: kibana
spec:type: LoadBalancerports:- protocol: TCPport: 80targetPort: 5601selector:app: kibana

部署 service 文件

[root@master efk]# kubectl apply -f kibana-svc.yaml

查看 service

[root@master efk]# kubectl get svc
NAME            TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)             AGE
elasticsearch   ClusterIP      None          <none>        9200/TCP,9300/TCP   8m
kibana          LoadBalancer   10.99.16.75   <pending>     80:32361/TCP        32s
kubernetes      ClusterIP      10.96.0.1     <none>        443/TCP             7d19h

验证 Kibana 部署 开启端口转发

[root@master efk]# kubectl port-forward kibana-786f7f49d-4vlqk 5601:5601

打开一个新的 Terminal 窗口,以便我们可以查询 REST API 接口

[root@master efk]# curl http://localhost:5601/app/kibana
(3)配置Fluentd

创建角色文件

[root@master efk]# vim fluentd-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:name: fluentdlabels:app: fluentd
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: fluentdlabels:app: fluentd
rules:
- apiGroups:- ""resources:- pods- namespacesverbs:- get- list- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: fluentd
roleRef:kind: ClusterRolename: fluentdapiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccountname: fluentdnamespace: default
---
apiVersion: apps/v1
kind: DaemonSet
metadata:name: fluentdnamespace: defaultlabels:app: fluentd
spec:selector:matchLabels:app: fluentdtemplate:metadata:labels:app: fluentdspec:serviceAccount: fluentdserviceAccountName: fluentdtolerations:- operator: Existscontainers:- name: fluentdimage: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1env:- name:  FLUENT_ELASTICSEARCH_HOSTvalue: "elasticsearch.default.svc.cluster.local"- name:  FLUENT_ELASTICSEARCH_PORTvalue: "9200"- name: FLUENT_ELASTICSEARCH_SCHEMEvalue: "http"- name: FLUENTD_SYSTEMD_CONFvalue: disable- name: FLUENT_ELASTICSEARCH_SED_DISABLEvalue: "true"resources:limits:cpu: 300mmemory: 512Mirequests:cpu: 50mmemory: 100MivolumeMounts:- name: varlogmountPath: /var/log- name: varlibdockercontainersmountPath: /var/lib/docker/containersreadOnly: true- name: configmountPath: /fluentd/etc/kubernetes.confsubPath: kubernetes.conf- name: index-templatemountPath: /fluentd/etc/index_template.jsonsubPath: index_template.jsonterminationGracePeriodSeconds: 30volumes:- name: varloghostPath:path: /var/log- name: varlibdockercontainershostPath:path: /var/lib/docker/containers- name: configconfigMap:name: fluentd-configitems:- key: kubernetes.confpath: kubernetes.conf- name: index-templateconfigMap:name: fluentd-configitems:- key: index_template.jsonpath: index_template.json

部署 fluentd-role 文件

[root@master efk]# kubectl apply -f fluentd-rbac.yaml

创建 configmap 文件

[root@master efk]# vim fluentd-config.yaml
kind: ConfigMap
apiVersion: v1
metadata:name: fluentd-configlabels:addonmanager.kubernetes.io/mode: Reconcile
data:kubernetes.conf: |-# AUTOMATICALLY GENERATED# DO NOT EDIT THIS FILE DIRECTLY, USE /templates/conf/kubernetes.conf.erb<match fluent.**>@type elasticsearchrequest_timeout 2147483648include_tag_key truehost "#{ENV['FLUENT_ELASTICSEARCH_HOST']}"port "#{ENV['FLUENT_ELASTICSEARCH_PORT']}"path "#{ENV['FLUENT_ELASTICSEARCH_PATH']}"scheme "#{ENV['FLUENT_ELASTICSEARCH_SCHEME'] || 'http'}"ssl_verify "#{ENV['FLUENT_ELASTICSEARCH_SSL_VERIFY'] || 'true'}"ssl_version "#{ENV['FLUENT_ELASTICSEARCH_SSL_VERSION'] || 'TLSv1'}"reload_connections "#{ENV['FLUENT_ELASTICSEARCH_RELOAD_CONNECTIONS'] || 'false'}"reconnect_on_error "#{ENV['FLUENT_ELASTICSEARCH_RECONNECT_ON_ERROR'] || 'true'}"reload_on_failure "#{ENV['FLUENT_ELASTICSEARCH_RELOAD_ON_FAILURE'] || 'true'}"log_es_400_reason "#{ENV['FLUENT_ELASTICSEARCH_LOG_ES_400_REASON'] || 'false'}"logstash_prefix "#{ENV['FLUENT_ELASTICSEARCH_LOGSTASH_PREFIX'] || 'logstash'}"logstash_format "#{ENV['FLUENT_ELASTICSEARCH_LOGSTASH_FORMAT'] || 'true'}"index_name "#{ENV['FLUENT_ELASTICSEARCH_LOGSTASH_INDEX_NAME'] || 'logstash'}"type_name "#{ENV['FLUENT_ELASTICSEARCH_LOGSTASH_TYPE_NAME'] || 'fluentd'}"enable_ilm true#ilm_policy_id watch-history-ilm-policy#ilm_policy_overwrite false#rollover_index true#ilm_policy {}template_name delete-after-7daystemplate_file /fluentd/etc/index_template.json#customize_template {"<<index_prefix>>": "fluentd"}<buffer>@type filepath /var/log/fluentd-bufferflush_thread_count "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_FLUSH_THREAD_COUNT'] || '8'}"flush_interval "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_FLUSH_INTERVAL'] || '5s'}"chunk_limit_size "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_CHUNK_LIMIT_SIZE'] || '4M'}"queue_limit_length "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_QUEUE_LIMIT_LENGTH'] || '32'}"retry_max_interval "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_RETRY_MAX_INTERVAL'] || '30'}"retry_forever true</buffer></match><source>@type tailtag kubernetes.*path /var/log/containers/*.logpos_file /var/log/kube-containers.log.posread_from_head false<parse>@type multi_format<pattern>format jsontime_format %Y-%m-%dT%H:%M:%S.%NZ</pattern><pattern>format regexptime_format %Y-%m-%dT%H:%M:%S.%N%:zexpression /^(?<time>.+)\b(?<stream>stdout|stderr)\b(?<log>.*)$/</pattern></parse></source><source>@type tail@id in_tail_minionpath /var/log/salt/minionpos_file /var/log/fluentd-salt.postag saltread_from_head false<parse>@type regexpexpression /^(?<time>[^ ]* [^ ,]*)[^\[]*\[[^\]]*\]\[(?<severity>[^ \]]*) *\] (?<message>.*)$/time_format %Y-%m-%d %H:%M:%S</parse></source><source>@type tail@id in_tail_startupscriptpath /var/log/startupscript.logpos_file /var/log/fluentd-startupscript.log.postag startupscriptread_from_head false<parse>@type syslog</parse></source><source>@type tail@id in_tail_dockerpath /var/log/docker.logpos_file /var/log/fluentd-docker.log.postag dockerread_from_head false<parse>@type regexpexpression /^time="(?<time>[^)]*)" level=(?<severity>[^ ]*) msg="(?<message>[^"]*)"( err="(?<error>[^"]*)")?( statusCode=($<status_code>\d+))?/</parse></source><source>@type tail@id in_tail_etcdpath /var/log/etcd.logpos_file /var/log/fluentd-etcd.log.postag etcdread_from_head false<parse>@type none</parse></source><source>@type tail@id in_tail_kubeletmultiline_flush_interval 5spath /var/log/kubelet.logpos_file /var/log/fluentd-kubelet.log.postag kubeletread_from_head false<parse>@type kubernetes</parse></source><source>@type tail@id in_tail_kube_proxymultiline_flush_interval 5spath /var/log/kube-proxy.logpos_file /var/log/fluentd-kube-proxy.log.postag kube-proxyread_from_head false<parse>@type kubernetes</parse></source><source>@type tail@id in_tail_kube_apiservermultiline_flush_interval 5spath /var/log/kube-apiserver.logpos_file /var/log/fluentd-kube-apiserver.log.postag kube-apiserverread_from_head false<parse>@type kubernetes</parse></source><source>@type tail@id in_tail_kube_controller_managermultiline_flush_interval 5spath /var/log/kube-controller-manager.logpos_file /var/log/fluentd-kube-controller-manager.log.postag kube-controller-managerread_from_head false<parse>@type kubernetes</parse></source><source>@type tail@id in_tail_kube_schedulermultiline_flush_interval 5spath /var/log/kube-scheduler.logpos_file /var/log/fluentd-kube-scheduler.log.postag kube-schedulerread_from_head false<parse>@type kubernetes</parse></source><source>@type tail@id in_tail_reschedulermultiline_flush_interval 5spath /var/log/rescheduler.logpos_file /var/log/fluentd-rescheduler.log.postag reschedulerread_from_head false<parse>@type kubernetes</parse></source><source>@type tail@id in_tail_glbcmultiline_flush_interval 5spath /var/log/glbc.logpos_file /var/log/fluentd-glbc.log.postag glbcread_from_head false<parse>@type kubernetes</parse></source><source>@type tail@id in_tail_cluster_autoscalermultiline_flush_interval 5spath /var/log/cluster-autoscaler.logpos_file /var/log/fluentd-cluster-autoscaler.log.postag cluster-autoscalerread_from_head false<parse>@type kubernetes</parse></source># Example:# 2017-02-09T00:15:57.992775796Z AUDIT: id="90c73c7c-97d6-4b65-9461-f94606ff825f" ip="104.132.1.72" method="GET" user="kubecfg" as="<self>" asgroups="<lookup>" namespace="default" uri="/api/v1/namespaces/default/pods"# 2017-02-09T00:15:57.993528822Z AUDIT: id="90c73c7c-97d6-4b65-9461-f94606ff825f" response="200"<source>@type tail@id in_tail_kube_apiserver_auditmultiline_flush_interval 5spath /var/log/kubernetes/kube-apiserver-audit.logpos_file /var/log/kube-apiserver-audit.log.postag kube-apiserver-auditread_from_head false<parse>@type multilineformat_firstline /^\S+\s+AUDIT:/# Fields must be explicitly captured by name to be parsed into the record.# Fields may not always be present, and order may change, so this just looks# for a list of key="\"quoted\" value" pairs separated by spaces.# Unknown fields are ignored.# Note: We can't separate query/response lines as format1/format2 because#       they don't always come one after the other for a given query.format1 /^(?<time>\S+) AUDIT:(?: (?:id="(?<id>(?:[^"\\]|\\.)*)"|ip="(?<ip>(?:[^"\\]|\\.)*)"|method="(?<method>(?:[^"\\]|\\.)*)"|user="(?<user>(?:[^"\\]|\\.)*)"|groups="(?<groups>(?:[^"\\]|\\.)*)"|as="(?<as>(?:[^"\\]|\\.)*)"|asgroups="(?<asgroups>(?:[^"\\]|\\.)*)"|namespace="(?<namespace>(?:[^"\\]|\\.)*)"|uri="(?<uri>(?:[^"\\]|\\.)*)"|response="(?<response>(?:[^"\\]|\\.)*)"|\w+="(?:[^"\\]|\\.)*"))*/time_format %Y-%m-%dT%T.%L%Z</parse></source><filter kubernetes.**>@type kubernetes_metadata@id filter_kube_metadata</filter>index_template.json: |-{"index_patterns": ["logstash-*"],"settings": {"index": {"lifecycle": {"name": "watch-history-ilm-policy","rollover_alias": ""}}}}

部署 configmap 文件

[root@master efk]# kubectl apply -f fluentd-config.yaml

创建fluentd

[root@master efk]# vim fluentd.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:name: fluentdnamespace: defaultlabels:app: fluentd
spec:selector:matchLabels:app: fluentdtemplate:metadata:labels:app: fluentdspec:serviceAccount: fluentdserviceAccountName: fluentdtolerations:- operator: Existscontainers:- name: fluentdimage: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1env:- name:  FLUENT_ELASTICSEARCH_HOSTvalue: "elasticsearch.default.svc.cluster.local"- name:  FLUENT_ELASTICSEARCH_PORTvalue: "9200"- name: FLUENT_ELASTICSEARCH_SCHEMEvalue: "http"- name: FLUENTD_SYSTEMD_CONFvalue: disable- name: FLUENT_ELASTICSEARCH_SED_DISABLEvalue: "true"resources:limits:cpu: 300mmemory: 512Mirequests:cpu: 50mmemory: 100MivolumeMounts:- name: varlogmountPath: /var/log- name: varlibdockercontainersmountPath: /var/lib/docker/containersreadOnly: true- name: configmountPath: /fluentd/etc/kubernetes.confsubPath: kubernetes.conf- name: index-templatemountPath: /fluentd/etc/index_template.jsonsubPath: index_template.jsonterminationGracePeriodSeconds: 30volumes:- name: varloghostPath:path: /var/log- name: varlibdockercontainershostPath:path: /var/lib/docker/containers- name: configconfigMap:name: fluentd-configitems:- key: kubernetes.confpath: kubernetes.conf- name: index-templateconfigMap:name: fluentd-configitems:- key: index_template.jsonpath: index_template.json

部署 fluentd 文件

[root@master efk]# kubectl apply -f fluentd.yaml

查看 Pod 运行状态

[root@master efk]# kubectl get pod
NAME                                      READY   STATUS    RESTARTS   AGE
es-cluster-0                              1/1     Running   0          6h31m
es-cluster-1                              1/1     Running   0          6h31m
es-cluster-2                              1/1     Running   0          6h31m
fluentd-5dkzc                             1/1     Running   0          17m
fluentd-k6h54                             1/1     Running   0          17m
kibana-786f7f49d-x6qt8                    1/1     Running   0          6h31m
nfs-client-provisioner-79865487f9-c28ql   1/1     Running   0          7h12m
(4)登录kibana控制台

image-20241028170614766

(5)数据源模拟
[root@master efk]# vim data.yaml
apiVersion: v1
kind: Pod
metadata:name: data-logs
spec:containers:- name: counterimage: busyboximagePullPolicy: IfNotPresentargs:- /bin/sh- -c- 'i=0; while true; do echo "$i: Hello, are you collecting my data? $(date)"; i=$((i+1)); sleep 5; done'

部署 data 文件

[root@master efk]# kubectl apply -f data.yaml
(6)创建索引模式

配置索引模式

image-20241126165402666

配置时间戳筛选数据

image-20241126165437488

查看数据

image-20241126165852639


http://www.mrgr.cn/news/78218.html

相关文章:

  • STM32C011开发(2)----nBOOT_SEL设置
  • AIGC--AIGC与人机协作:新的创作模式
  • 安装 Docker(使用国内源)
  • 【代码pycharm】动手学深度学习v2-08 线性回归 + 基础优化算法
  • InfluxDB时序数据库笔记(一)
  • 质量留住用户:如何通过测试自动化提供更高质量的用户体验
  • 16 —— Webpack多页面打包
  • 【346】Postgres内核 Startup Process 通过 signal 与 postmaster 交互实现 (5)
  • NUXT3学习日记四(路由中间件、导航守卫)
  • Python的3D可视化库 - vedo (3)visual子模块 点对象的可视化控制
  • 【小白学机器学习35】数据表:整洁数据表,交叉表/列联表,以及两者转化pd.pivot_table()
  • 深度学习基础1
  • WinFrom调用webapi接口另一个方法及其应用实例
  • JVM调优篇之JVM基础入门AND字节码文件解读
  • STM32C011开发(2)----nBOOT_SEL设置
  • LLamafactory 批量推理与异步 API 调用效率对比实测
  • 【11-20期】Java面试进阶:深入解析核心问题与实战案例
  • 【机器学习】机器学习学习笔记 - 数据预处理 - 01
  • 【机器学习】机器学习学习笔记 - 监督学习 - KNN线性回归岭回归 - 02
  • QUICK 调试camera-xml解析
  • QT6学习第四天
  • HT4089电子雾化芯片耐高压40V,带OVP保护功能锂电池线性充电管理芯片,应用带屏幕电子雾化行业MCU解决方案
  • win10中使用ffmpeg的filter滤镜
  • 图论入门编程
  • Python学习34天
  • maven <scope>compile</scope>作用