基于ECK技术栈收集日志

基于ECK技术栈收集日志

1.Filebeat收集指定空间日志

有时候可能只需要收集部分空间的日志,而并不是收集所有的日志,此时通过修改 Filebeat 的配置,实现只收集部分空间的日志。

比如只收集 krm 和 kube-system 空间下的日志

1.1方式一:使用 Autodiscover + templates

优点:从源头只生成指定命名空间的采集任务,性能更好、日志更干净。

缺点:每增加一个命名空间就要加一段 condition。

方案一:指定要采集的命名空间,每增加一个命名空间就要加一段 condition配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
[root@k8s-master01 29-eck]#vim Filebeat-krm-kubesystem.yaml
# 将hints.enabled:的值改为false,在根据要采集的命名空间指定condition配置
filebeat.autodiscover:
providers:
- type: kubernetes
node: ${NODE_NAME}
hints.enabled: false # ← 必须改成 false
templates:
# ---------- 只采集 krm 命名空间 ----------
- condition:
equals:
kubernetes.namespace: "krm"
config:
- type: filestream
id: "kubernetes-container-${data.kubernetes.container.id}"
paths:
- /var/log/containers/*${data.kubernetes.container.id}.log
prospector.scanner:
fingerprint.enabled: true
symlinks: true
file_identity.fingerprint: {}
close.on_state_change.removed: false
ignore_older: 72h
close.on_state_change.inactive: 5m
clean_inactive: 96h
fields:
log_topic: k8spodlogs
cluster: production
fields_under_root: false

# ---------- 只采集 kube-system 命名空间 ----------
- condition:
equals:
kubernetes.namespace: "kube-system"
config:
- type: filestream
id: "kubernetes-container-${data.kubernetes.container.id}"
paths:
- /var/log/containers/*${data.kubernetes.container.id}.log
prospector.scanner:
fingerprint.enabled: true
symlinks: true
file_identity.fingerprint: {}
close.on_state_change.removed: false
ignore_older: 72h
close.on_state_change.inactive: 5m
clean_inactive: 96h
fields:
log_topic: k8spodlogs
cluster: production
fields_under_root: false

完整的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# Beat 资源
apiVersion: beat.k8s.elastic.co/v1beta1
kind: Beat
metadata:
name: filebeat # 资源名称,生成的 DaemonSet 会叫 filebeat-beat
namespace: logging
labels:
app: filebeat
spec:
# ---------- 基础信息 ----------
type: filebeat # 必须指定 Beat 类型
version: "9.5.2" # ★ 请改成与自己 的 ES 版本一致
image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/filebeat:9.5.2 # ★ 请改成与自己的 ES 版本一致

# ----------# Filebeat 配置,相当于传统部署中的 filebeat.yml----------
config:
# 全局设置
name: "filebeat-${NODE_NAME}" # 每个节点实例名称(便于区分)
# # Filebeat 自身日志,日志级别:生产建议 info 或 warning,排查问题时改 debug
logging.level: info
logging.to_stderr: true # 日志输出到 stderr,方便 kubectl logs 查看
logging.metrics.enabled: false # 关闭 Filebeat 自身 metrics 日志(减少噪音)

# 输入配置(采集日志)
# 输入:Autodiscover + filestream(生产推荐)
filebeat.autodiscover:
providers:
- type: kubernetes
node: ${NODE_NAME}

# 关闭 hints,只使用 templates 控制采集范围
# 如果只针对 krm 和 kube-system 的 templates,却把 hints.enabled: true 保留着,其他命名空间仍然有可能被采集。
hints.enabled: false
templates:
# ---------- 只采集 krm 命名空间 ----------
- condition:
equals:
kubernetes.namespace: "krm"
config:
- type: filestream
id: "kubernetes-container-${data.kubernetes.container.id}"

paths:
- /var/log/containers/*-${data.kubernetes.container.id}.log

parsers:
- container: ~

prospector.scanner:
fingerprint.enabled: true
symlinks: true

file_identity.fingerprint: {}

close.on_state_change.removed: false
ignore_older: 72h
close.on_state_change.inactive: 5m
clean_inactive: 96h

fields:
log_topic: k8spodlogs
cluster: production

fields_under_root: false

# ---------- 只采集 kube-system 命名空间 ----------
- condition:
equals:
kubernetes.namespace: "kube-system"
config:
- type: filestream
id: "kubernetes-container-${data.kubernetes.container.id}"

paths:
- /var/log/containers/*-${data.kubernetes.container.id}.log

parsers:
- container: ~

prospector.scanner:
fingerprint.enabled: true
symlinks: true

file_identity.fingerprint: {}

close.on_state_change.removed: false
ignore_older: 72h
close.on_state_change.inactive: 5m
clean_inactive: 96h

fields:
log_topic: k8spodlogs
cluster: production

fields_under_root: false

# ========================================================
# 处理器(丰富元数据 + 过滤)
# ========================================================
processors:
# 添加主机元数据(主机名、IP、OS 等)
- add_host_metadata:
when.not.contains.tags: forwarded
netinfo.enabled: true # 包含网络接口信息
# 生产必须:丢弃 Filebeat 自己的日志,防止循环采集
- drop_event:
when:
equals:
kubernetes.container.name: "filebeat"

# 输出配置(生产推荐走 Kafka 做缓冲)
# ---------- 输出到 Kafka(推荐)----------
output.kafka:
# Kafka broker 地址(请改成你实际的 Service 名称)
# 常见命名:kafka-broker-0.kafka-broker.logging.svc:9092 或 kafka.logging.svc:9092
hosts:
- "kafka.logging.svc.cluster.local:9092"
# Topic 名称(Logstash 会从这个 Topic 消费)
topic: "k8spodlogs" #把日志输出到名字是k8spodlogs的Topic
# 分区策略
# partition.round_robin:
# reachable_only: true # 只向可达的 broker 写,官方默认是false,生产也推荐用false
# 可靠性
required_acks: 1 # 0=不等待 1=leader确认 -1=所有ISR确认(最可靠但慢)
compression: gzip # 压缩算法:none / gzip / snappy / lz4 / zstd
max_message_bytes: 1000000 # 单条消息最大字节,Filebeat 的max_message_bytes <= Kafka 的broker message.max.bytes

# ---------- SASL 认证(你的环境必须配置)----------
username: "user1"
password: "${KAFKA_PASSWORD}" # 通过环境变量注入,禁止明文写在 YAML
sasl.mechanism: "SCRAM-SHA-256"
# ========================================================
# 队列与性能调优(生产关键)
# ========================================================
queue.mem:
events: 4096 # 内存队列事件数(默认 4096)
flush.min_events: 512 # 批量刷新最小事件数
flush.timeout: 5s # 最长等待时间

# ========================================================
# HTTP 监控端点(可选,用于 Prometheus 抓取)
# ========================================================
http.enabled: true
http.host: localhost
http.port: 5066

# ---------- 部署模型:DaemonSet(每个节点一个实例)----------
daemonSet:
updateStrategy: # 可选滚动更新策略
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
podTemplate:
metadata:
labels:
app: filebeat
k8s-app: filebeat
annotations:
co.elastic.logs/enabled: "false" # 不收集filebeat自己的日志(可选)
spec:
# ---------- 服务账号,必须提前创建好该资源 ----------
serviceAccountName: filebeat
automountServiceAccountToken: true # 必须 true,才能访问 K8s API

# ---------- 网络 ----------
hostNetwork: true # 使用宿主机网络(获取更准确的主机元数据,且避免端口冲突)
dnsPolicy: ClusterFirstWithHostNet # 配合 hostNetwork 使用

# ---------- 安全上下文 ----------
securityContext:
runAsUser: 0 # Filebeat 需要 root 权限读取 /var/log


# 允许调度到控制平面节点(如需采集 master 日志)
# tolerations:
# - key: node-role.kubernetes.io/control-plane
# operator: Exists
# effect: NoSchedule
# - key: node-role.kubernetes.io/master
# operator: Exists
# effect: NoSchedule
# - key: node.kubernetes.io/not-ready
# operator: Exists
# effect: NoExecute
# tolerationSeconds: 300
# - key: node.kubernetes.io/unreachable
# operator: Exists
# effect: NoExecute
# tolerationSeconds: 300
# ---------- 终止宽限期 ----------
terminationGracePeriodSeconds: 30

containers:
- name: filebeat # 容器名必须叫 filebeat(ECK 约定)
# 资源限制(生产根据实际日志量调整)
# resources:
# requests:
# cpu: 100m
# memory: 200Mi
# limits:
# cpu: 1000m
# memory: 1Gi
# 环境变量
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName # 注入当前节点名,供配置使用
- name: KAFKA_PASSWORD
valueFrom:
secretKeyRef:
name: kafka-user-passwords
key: client-passwords


# 健康检查(可选)
# livenessProbe:
# httpGet:
# path: /
# port: 5066
# initialDelaySeconds: 30
# periodSeconds: 10
# readinessProbe:
# httpGet:
# path: /
# port: 5066
# initialDelaySeconds: 10
# periodSeconds: 10
volumeMounts:
# 宿主机日志目录(必须)
- name: varlogcontainers
mountPath: /var/log/containers

- name: varlogpods
mountPath: /var/log/pods

- name: varlibdockercontainers
mountPath: /var/lib/docker/containers

# Filebeat 数据目录(registry 状态文件,必须持久)
- name: data
mountPath: /usr/share/filebeat/data
# 如果使用自定义证书
# - name: kafka-certs
# mountPath: /etc/ssl/certs
# readOnly: true

volumes:
- name: varlogcontainers
hostPath:
path: /var/log/containers
- name: varlogpods
hostPath:
path: /var/log/pods
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers


# 数据目录建议用 hostPath(每个节点独立,避免多 Pod 竞争)
- name: data
hostPath:
path: /var/lib/filebeat-data # 宿主机上的持久目录
type: DirectoryOrCreate

更新 filebeat资源:

1
2
[root@k8s-master01 29-eck]# kubectl replace -f Filebeat-krm-kubesystem.yaml
beat.beat.k8s.elastic.co/filebeat replaced

可以看到只有krm和kube-system两个空间的日志了:

1.2方式二:全量采集 + processor 丢弃不需要的命名空间

优点:配置简单,后续想加/删命名空间只改一处。

缺点:Filebeat 仍然会打开所有容器的日志文件,再丢弃事件,资源消耗比方式一略高。

把原来的 filebeat.autodiscover 保持不变(继续全量采集),然后把 processors 改成下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
processors:
# 添加主机元数据
- add_host_metadata:
when.not.contains.tags: forwarded
netinfo.enabled: true

# 生产必须:丢弃 Filebeat 自己的日志,防止循环采集
- drop_event:
when:
equals:
kubernetes.container.name: "filebeat"

# ---------- 只保留指定命名空间的日志 ----------
- drop_event:
when:
not:
or:
- equals:
kubernetes.namespace: "monitoring"
- equals:
kubernetes.namespace: "kube-system"

控制台只会看到两个命名空间的日志:

1.3方式三:根据 Namespace Label 采集(推荐用于动态场景)

给要收集的命名空间打上标签,这里采集krmcubefs命名空间:

1
2
3
4
# 给想要收集日志的命名空间打上 logging=enabled 标签
kubectl label namespace cubefs logging=enabled
kubectl label namespace krm logging=enabled
# 其他命名空间不打这个标签,就不会采集

filebeat资源配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# Beat 资源
apiVersion: beat.k8s.elastic.co/v1beta1
kind: Beat
metadata:
name: filebeat # 资源名称,生成的 DaemonSet 会叫 filebeat-beat
namespace: logging
labels:
app: filebeat
spec:
# ---------- 基础信息 ----------
type: filebeat # 必须指定 Beat 类型
version: "9.5.2" # ★ 请改成与自己 的 ES 版本一致
image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/filebeat:9.5.2 # ★ 请改成与自己的 ES 版本一致

# ----------# Filebeat 配置,相当于传统部署中的 filebeat.yml----------
config:
# 全局设置
name: "filebeat-${NODE_NAME}" # 每个节点实例名称(便于区分)
# # Filebeat 自身日志,日志级别:生产建议 info 或 warning,排查问题时改 debug
logging.level: info
logging.to_stderr: true # 日志输出到 stderr,方便 kubectl logs 查看
logging.metrics.enabled: false # 关闭 Filebeat 自身 metrics 日志(减少噪音)

# 输入配置(采集日志)
# 输入:Autodiscover + filestream(生产推荐)
filebeat.autodiscover:
providers:
- type: kubernetes
node: ${NODE_NAME} # 只处理本节点 Pod(必须配合 hostNetwork)
hints.enabled: false # 开启 hints 机制(允许 Pod 使用 annotation 控制 Filebeat不采集自己的日志,如:co.elastic.logs/enabled: "false")
add_resource_metadata:
namespace:
include_labels: ["monitoring"] #这里配置的是 Namespace 上 Label 的 key,不是命名空间的名字。
templates:
- condition:
equals:
kubernetes.namespace_labels.logging: "enabled"
config:
- type: filestream
id: "kubernetes-container-${data.kubernetes.container.id}"
paths:
- /var/log/containers/*${data.kubernetes.container.id}.log
parsers:
- container: ~
prospector.scanner:
fingerprint.enabled: true
symlinks: true
file_identity.fingerprint: {}
# Kubernetes 日志轮转/删除时,不立即关闭文件
# 防止尾部日志还未读完就丢失
close.on_state_change.removed: false
# 忽略过旧日志,防止重启后全量重发
ignore_older: 72h
close.on_state_change.inactive: 5m
# 清理 registry 中超过 96 小时的旧状态
# 必须大于 ignore_older + scanner.check_interval(默认10秒)
clean_inactive: 96h
fields:
log_topic: k8spodlogs # 如需动态 topic 可配合使用
cluster: production
fields_under_root: false

# ========================================================
# 处理器(丰富元数据 + 过滤)
# ========================================================
processors:
# 添加 Kubernetes 元数据(namespace、pod、container、labels、annotations 等),依赖已创建的RBAC
# - add_kubernetes_metadata: #待确认
# host: ${NODE_NAME} # 指定节点,避免跨节点查询
# default_indexers.enabled: true
# default_matchers.enabled: true

# 添加主机元数据(主机名、IP、OS 等)
- add_host_metadata:
when.not.contains.tags: forwarded
netinfo.enabled: true # 包含网络接口信息
# 生产必须:丢弃 Filebeat 自己的日志,防止循环采集
- drop_event:
when:
equals:
kubernetes.container.name: "filebeat"
- drop_event:
when:
not:
or:
- equals:
kubernetes.namespace: "monitoring"
- equals:
kubernetes.namespace: "kube-system"

# 输出配置(生产推荐走 Kafka 做缓冲)
# ---------- 输出到 Kafka(推荐)----------
output.kafka:
# Kafka broker 地址(请改成你实际的 Service 名称)
# 常见命名:kafka-broker-0.kafka-broker.logging.svc:9092 或 kafka.logging.svc:9092
hosts:
- "kafka.logging.svc.cluster.local:9092"
# Topic 名称(Logstash 会从这个 Topic 消费)
topic: "k8spodlogs" #把日志输出到名字是k8spodlogs的Topic
# 分区策略
# partition.round_robin:
# reachable_only: true # 只向可达的 broker 写,官方默认是false,生产也推荐用false
# 可靠性
required_acks: 1 # 0=不等待 1=leader确认 -1=所有ISR确认(最可靠但慢)
compression: gzip # 压缩算法:none / gzip / snappy / lz4 / zstd
max_message_bytes: 1000000 # 单条消息最大字节,Filebeat 的max_message_bytes <= Kafka 的broker message.max.bytes

# ---------- SASL 认证(你的环境必须配置)----------
username: "user1"
password: "${KAFKA_PASSWORD}" # 通过环境变量注入,禁止明文写在 YAML
sasl.mechanism: "SCRAM-SHA-256"
# ========================================================
# 队列与性能调优(生产关键)
# ========================================================
queue.mem:
events: 4096 # 内存队列事件数(默认 4096)
flush.min_events: 512 # 批量刷新最小事件数
flush.timeout: 5s # 最长等待时间

# ========================================================
# HTTP 监控端点(可选,用于 Prometheus 抓取)
# ========================================================
http.enabled: true
http.host: localhost
http.port: 5066

# ---------- 部署模型:DaemonSet(每个节点一个实例)----------
daemonSet:
updateStrategy: # 可选滚动更新策略
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
podTemplate:
metadata:
labels:
app: filebeat
k8s-app: filebeat
annotations:
co.elastic.logs/enabled: "false" # 不收集filebeat自己的日志(可选)
spec:
# ---------- 服务账号,必须提前创建好该资源 ----------
serviceAccountName: filebeat
automountServiceAccountToken: true # 必须 true,才能访问 K8s API

# ---------- 网络 ----------
hostNetwork: true # 使用宿主机网络(获取更准确的主机元数据,且避免端口冲突)
dnsPolicy: ClusterFirstWithHostNet # 配合 hostNetwork 使用

# ---------- 安全上下文 ----------
securityContext:
runAsUser: 0 # Filebeat 需要 root 权限读取 /var/log


# 允许调度到控制平面节点(如需采集 master 日志)
# tolerations:
# - key: node-role.kubernetes.io/control-plane
# operator: Exists
# effect: NoSchedule
# - key: node-role.kubernetes.io/master
# operator: Exists
# effect: NoSchedule
# - key: node.kubernetes.io/not-ready
# operator: Exists
# effect: NoExecute
# tolerationSeconds: 300
# - key: node.kubernetes.io/unreachable
# operator: Exists
# effect: NoExecute
# tolerationSeconds: 300
# ---------- 终止宽限期 ----------
terminationGracePeriodSeconds: 30

containers:
- name: filebeat # 容器名必须叫 filebeat(ECK 约定)
# 资源限制(生产根据实际日志量调整)
# resources:
# requests:
# cpu: 100m
# memory: 200Mi
# limits:
# cpu: 1000m
# memory: 1Gi
# 环境变量
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName # 注入当前节点名,供配置使用
- name: KAFKA_PASSWORD
valueFrom:
secretKeyRef:
name: kafka-user-passwords
key: client-passwords


# 健康检查(可选)
# livenessProbe:
# httpGet:
# path: /
# port: 5066
# initialDelaySeconds: 30
# periodSeconds: 10
# readinessProbe:
# httpGet:
# path: /
# port: 5066
# initialDelaySeconds: 10
# periodSeconds: 10
volumeMounts:
# 宿主机日志目录(必须)
- name: varlogcontainers
mountPath: /var/log/containers

- name: varlogpods
mountPath: /var/log/pods

- name: varlibdockercontainers
mountPath: /var/lib/docker/containers

# Filebeat 数据目录(registry 状态文件,必须持久)
- name: data
mountPath: /usr/share/filebeat/data
# 如果使用自定义证书
# - name: kafka-certs
# mountPath: /etc/ssl/certs
# readOnly: true

volumes:
- name: varlogcontainers
hostPath:
path: /var/log/containers
- name: varlogpods
hostPath:
path: /var/log/pods
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers


# 数据目录建议用 hostPath(每个节点独立,避免多 Pod 竞争)
- name: data
hostPath:
path: /var/lib/filebeat-data # 宿主机上的持久目录
type: DirectoryOrCreate

更新资源:

1
2
[root@k8s-master01 29-eck]# kubectl replace -f Filebeat-ns-label.yaml
beat.beat.k8s.elastic.co/filebeat replaced

此时只有krm和cubefs两个命名空间的日志了:

2.采集节点指定文件

要采集节点本地目录的日志(例如 /var/log/messages),需要同时做两件事:

  • 在 Filebeat 配置里增加静态输入(filebeat.inputs)

  • 把节点目录挂载进 Filebeat 容器

第一步:在 config: 下添加静态输入,和 filebeat.autodiscover同级(不要删掉 autodiscover):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
config:
# ... 你原来的 name、logging 等配置 ...

# ---------- 新增:采集节点本地日志 ----------
filebeat.inputs:
- type: filestream
id: host-messages
enabled: true
paths:
# 这里是 Filebeat Pod 内部路径
# 后面通过 hostPath 把节点的文件挂载到容器内
- /node/var/log/messages # 当前正在写的文件
- /node/var/log/messages-* # 轮转后的文件(如 messages-20260904)

parsers: [] # 系统日志一般不需要 container parser
prospector.scanner:
fingerprint.enabled: true
file_identity.fingerprint: {}
ignore_older: 72h
close.on_state_change.inactive: 5m
clean_inactive: 96h
fields:
log_topic: k8spodlogs # 建议和容器日志区分开
log_type: system
cluster: production
fields_under_root: false

# ---------- 原来的容器日志 autodiscover 保持不变 ----------
filebeat.autodiscover:
providers:
- type: kubernetes
# ... 你之前的配置 ...

第二步:DaemonSet 挂载节点目录

在 daemonSet.podTemplate.spec 里增加 volume 和 volumeMount:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
daemonSet:
podTemplate:
spec:
containers:
- name: filebeat
volumeMounts:
# ... 原来的 varlogcontainers、varlogpods、data 等保持不动 ...

# ---------- 新增:挂载节点 /var/log ----------
- name: varlogmessages
#因为已经挂载了 /var/log/containers、/var/log/pods, 防止产生冲突,推荐挂载到其他目录,避免容器日志采集可能失效。
mountPath: /node/var/log #
readOnly: true

volumes:
# ... 原来的 volumes 保持不动 ...

# ---------- 新增 ----------
- name: varlogmessages
hostPath:
path: /var/log
type: Directory

完整的配置参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# Beat 资源
apiVersion: beat.k8s.elastic.co/v1beta1
kind: Beat
metadata:
name: filebeat # 资源名称,生成的 DaemonSet 会叫 filebeat-beat
namespace: logging
labels:
app: filebeat
spec:
# ---------- 基础信息 ----------
type: filebeat # 必须指定 Beat 类型
version: "9.5.2" # ★ 请改成与自己 的 ES 版本一致
image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/filebeat:9.5.2 # ★ 请改成与自己的 ES 版本一致

# ----------# Filebeat 配置,相当于传统部署中的 filebeat.yml----------
config:
# 全局设置
name: "filebeat-${NODE_NAME}" # 每个节点实例名称(便于区分)
# # Filebeat 自身日志,日志级别:生产建议 info 或 warning,排查问题时改 debug
logging.level: info
logging.to_stderr: true # 日志输出到 stderr,方便 kubectl logs 查看
logging.metrics.enabled: false # 关闭 Filebeat 自身 metrics 日志(减少噪音)
# ---------- 新增:采集节点本地日志 ----------
filebeat.inputs:
- type: filestream
id: host-messages
enabled: true
paths:
# 这里是 Filebeat Pod 内部路径
# 后面通过 hostPath 把节点的文件挂载到容器内
- /node/var/log/messages # 当前正在写的文件
- /node/var/log/messages-* # 轮转后的文件(如 messages-20260904)

parsers: [] # 系统日志一般不需要 container parser
prospector.scanner:
fingerprint.enabled: true
file_identity.fingerprint: {}
ignore_older: 72h
close.on_state_change.inactive: 5m
clean_inactive: 96h
fields:
log_topic: k8spodlogs # 建议和容器日志区分开
log_type: system
cluster: production
fields_under_root: false
# 输入配置(采集日志)
# 输入:Autodiscover + filestream(生产推荐)
filebeat.autodiscover:
providers:
- type: kubernetes
node: ${NODE_NAME} # 只处理本节点 Pod(必须配合 hostNetwork)
hints.enabled: false # 开启 hints 机制(允许 Pod 使用 annotation 控制 Filebeat不采集自己的日志,如:co.elastic.logs/enabled: "false")
add_resource_metadata:
namespace:
include_labels: ["logging"] #这里配置的是 Namespace 上 Label 的 key,不是命名空间的名字。
templates:
- condition:
equals:
kubernetes.namespace_labels.logging: "enabled"
config:
- type: filestream
id: "kubernetes-container-${data.kubernetes.container.id}"
paths:
- /var/log/containers/*${data.kubernetes.container.id}.log
parsers:
- container: ~
prospector.scanner:
fingerprint.enabled: true
symlinks: true
file_identity.fingerprint: {}
# Kubernetes 日志轮转/删除时,不立即关闭文件
# 防止尾部日志还未读完就丢失
close.on_state_change.removed: false
# 忽略过旧日志,防止重启后全量重发
ignore_older: 72h
close.on_state_change.inactive: 5m
# 清理 registry 中超过 96 小时的旧状态
# 必须大于 ignore_older + scanner.check_interval(默认10秒)
clean_inactive: 96h
fields:
log_topic: k8spodlogs # 如需动态 topic 可配合使用
cluster: production
fields_under_root: false

# ========================================================
# 处理器(丰富元数据 + 过滤)
# ========================================================
processors:
# 添加 Kubernetes 元数据(namespace、pod、container、labels、annotations 等),依赖已创建的RBAC
# - add_kubernetes_metadata: #待确认
# host: ${NODE_NAME} # 指定节点,避免跨节点查询
# default_indexers.enabled: true
# default_matchers.enabled: true

# 添加主机元数据(主机名、IP、OS 等)
- add_host_metadata:
when.not.contains.tags: forwarded
netinfo.enabled: true # 包含网络接口信息
# 生产必须:丢弃 Filebeat 自己的日志,防止循环采集
- drop_event:
when:
equals:
kubernetes.container.name: "filebeat"

# 输出配置(生产推荐走 Kafka 做缓冲)
# ---------- 输出到 Kafka(推荐)----------
output.kafka:
# Kafka broker 地址(请改成你实际的 Service 名称)
# 常见命名:kafka-broker-0.kafka-broker.logging.svc:9092 或 kafka.logging.svc:9092
hosts:
- "kafka.logging.svc.cluster.local:9092"
# Topic 名称(Logstash 会从这个 Topic 消费)
topic: "k8spodlogs" #把日志输出到名字是k8spodlogs的Topic
# 分区策略
# partition.round_robin:
# reachable_only: true # 只向可达的 broker 写,官方默认是false,生产也推荐用false
# 可靠性
required_acks: 1 # 0=不等待 1=leader确认 -1=所有ISR确认(最可靠但慢)
compression: gzip # 压缩算法:none / gzip / snappy / lz4 / zstd
max_message_bytes: 1000000 # 单条消息最大字节,Filebeat 的max_message_bytes <= Kafka 的broker message.max.bytes

# ---------- SASL 认证(你的环境必须配置)----------
username: "user1"
password: "${KAFKA_PASSWORD}" # 通过环境变量注入,禁止明文写在 YAML
sasl.mechanism: "SCRAM-SHA-256"
# ========================================================
# 队列与性能调优(生产关键)
# ========================================================
queue.mem:
events: 4096 # 内存队列事件数(默认 4096)
flush.min_events: 512 # 批量刷新最小事件数
flush.timeout: 5s # 最长等待时间

# ========================================================
# HTTP 监控端点(可选,用于 Prometheus 抓取)
# ========================================================
http.enabled: true
http.host: localhost
http.port: 5066

# ---------- 部署模型:DaemonSet(每个节点一个实例)----------
daemonSet:
updateStrategy: # 可选滚动更新策略
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
podTemplate:
metadata:
labels:
app: filebeat
k8s-app: filebeat
annotations:
co.elastic.logs/enabled: "false" # 不收集filebeat自己的日志(可选)
spec:
# ---------- 服务账号,必须提前创建好该资源 ----------
serviceAccountName: filebeat
automountServiceAccountToken: true # 必须 true,才能访问 K8s API

# ---------- 网络 ----------
hostNetwork: true # 使用宿主机网络(获取更准确的主机元数据,且避免端口冲突)
dnsPolicy: ClusterFirstWithHostNet # 配合 hostNetwork 使用

# ---------- 安全上下文 ----------
securityContext:
runAsUser: 0 # Filebeat 需要 root 权限读取 /var/log


# 允许调度到控制平面节点(如需采集 master 日志)
# tolerations:
# - key: node-role.kubernetes.io/control-plane
# operator: Exists
# effect: NoSchedule
# - key: node-role.kubernetes.io/master
# operator: Exists
# effect: NoSchedule
# - key: node.kubernetes.io/not-ready
# operator: Exists
# effect: NoExecute
# tolerationSeconds: 300
# - key: node.kubernetes.io/unreachable
# operator: Exists
# effect: NoExecute
# tolerationSeconds: 300
# ---------- 终止宽限期 ----------
terminationGracePeriodSeconds: 30

containers:
- name: filebeat # 容器名必须叫 filebeat(ECK 约定)
# 资源限制(生产根据实际日志量调整)
# resources:
# requests:
# cpu: 100m
# memory: 200Mi
# limits:
# cpu: 1000m
# memory: 1Gi
# 环境变量
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName # 注入当前节点名,供配置使用
- name: KAFKA_PASSWORD
valueFrom:
secretKeyRef:
name: kafka-user-passwords
key: client-passwords


# 健康检查(可选)
# livenessProbe:
# httpGet:
# path: /
# port: 5066
# initialDelaySeconds: 30
# periodSeconds: 10
# readinessProbe:
# httpGet:
# path: /
# port: 5066
# initialDelaySeconds: 10
# periodSeconds: 10
volumeMounts:
# 宿主机日志目录(必须)
- name: varlogcontainers
mountPath: /var/log/containers

- name: varlogpods
mountPath: /var/log/pods

- name: varlibdockercontainers
mountPath: /var/lib/docker/containers

- name: varlogmessages
mountPath: /node/var/log
readOnly: true

# Filebeat 数据目录(registry 状态文件,必须持久)
- name: data
mountPath: /usr/share/filebeat/data
# 如果使用自定义证书
# - name: kafka-certs
# mountPath: /etc/ssl/certs
# readOnly: true

volumes:
- name: varlogcontainers
hostPath:
path: /var/log/containers
- name: varlogpods
hostPath:
path: /var/log/pods
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
- name: varlogmessages
hostPath:
path: /var/log
type: Directory


# 数据目录建议用 hostPath(每个节点独立,避免多 Pod 竞争)
- name: data
hostPath:
path: /var/lib/filebeat-data # 宿主机上的持久目录
type: DirectoryOrCreate

更新资源:

1
2
[root@k8s-master01 29-eck]# kubectl replace -f Filebeat-ns-label.yaml
beat.beat.k8s.elastic.co/filebeat replaced

在控制台上可以查看到messages日志:

3.收集非云原生日志

有些程序在设计时,并没有符合云原生设计,也就是把程序的日志直接输出到了本地文件, 此时如果也需要收集日志,可以在程序的 Pod 内,启动一个 Filebeat 的容器,用于收集日志。

原理是在业务的pod中注入一个filebeat(sidecar)容器,利用共享Volume拿到业务容器的日志,filebeat容器通过挂载ConfigMap的方式将日志发送给ES或者kafka,整理逻辑如下:

1
2
3
4
5
6
7
8
9
Pod
├── 业务容器 (app)
│ └── 把日志写到 /var/log/app/*.log

├── Filebeat 容器 (sidecar)
│ └── 读取 /var/log/app/*.log,然后发送到 Elasticsearch或者kafka

└── 共享 Volume (emptyDir)
└── 业务容器和 Filebeat 都能访问这个目录

3.1部署业务服务

首先创建一个模拟程序,用于输出日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
labels:
app: app
env: release
spec:
selector:
matchLabels:
app: app
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
# minReadySeconds: 30
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: registry.cn-beijing.aliyuncs.com/dotbalo/alpine:3.6
imagePullPolicy: IfNotPresent
volumeMounts: #定义卷挂载
- name: logpath # 挂载名字是logpath卷
mountPath: /opt/ #挂载目录是容器内/opt下
env:
- name: TZ
value: "Asia/Shanghai"
- name: LANG
value: C.UTF-8
- name: LC_ALL
value: C.UTF-8
command:
- sh
- -c
- while true; do date >> /opt/date.log; sleep 2; done #命令模拟程序将日志输出到容器内/opt/date.log
volumes: #定义卷
- name: logpath #卷的名字是logpath
emptyDir: {} #存储卷类型为 emptyDir,它的生命周期与 Pod 绑定,会在宿主机节点的产生文件,路径是/var/lib/kubelet/pods/容器id/volumes/kubernetes.io~empty-dir/logpath/date.log;通常用于在同一个 Pod 的多个容器间共享数据(例如业务容器写日志,Sidecar 容器读日志)

创建服务:

1
2
[root@k8s-master01 29-eck]# kubectl replace -f app.yaml
deployment.apps/app replaced

查看日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@k8s-master01 29-eck]# kubectl get po
NAME READY STATUS RESTARTS AGE
app-b6597d795-qt7fq 1/1 Running 0 35m

[root@k8s-master01 29-eck]# kubectl exec -ti app-b6597d795-qt7fq -- sh
/ # tail -f /opt/date.log
Sat Sep 5 08:50:03 UTC 2026
Sat Sep 5 08:50:05 UTC 2026
Sat Sep 5 08:50:07 UTC 2026
Sat Sep 5 08:50:09 UTC 2026
Sat Sep 5 08:50:11 UTC 2026
Sat Sep 5 08:50:13 UTC 2026
Sat Sep 5 08:50:15 UTC 2026
Sat Sep 5 08:50:17 UTC 2026
Sat Sep 5 08:50:19 UTC 2026
Sat Sep 5 08:50:21 UTC 2026

3.2向pod注入Filebeat 作为 Sidecar 容器

接下来修改业务的资源文件,增加一个filebeat容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
labels:
app: app
env: release
spec:
selector:
matchLabels:
app: app
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
# minReadySeconds: 30
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: registry.cn-beijing.aliyuncs.com/dotbalo/alpine:3.6
imagePullPolicy: IfNotPresent
volumeMounts: #定义卷挂载
- name: logpath # 挂载名字是logpath卷
mountPath: /data/app/logs #挂载目录是容器内/opt下
env:
- name: TZ
value: "Asia/Shanghai"
- name: LANG
value: C.UTF-8
- name: LC_ALL
value: C.UTF-8
command:
- sh
- -c
- while true; do date >> /data/app/logs/date.log; sleep 2; done #命令模拟程序将日志输出到容器内/data/app/logs/date.log
- name: filebeat
image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/filebeat:9.5.2 #镜像要和es保持一致
imagePullPolicy: IfNotPresent
env:
- name: POD_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: POD_DEPLOY_NAME
value: app
- name: TZ
value: "Asia/Shanghai"
- name: KAFKA_PASSWORD #定义一个环境变量,用于存储kafka的密码
valueFrom:
secretKeyRef:
name: kafka-user-passwords
key: client-passwords
securityContext:
runAsUser: 0
volumeMounts: #定义卷挂载
- name: logpath
mountPath: /data/app/logs #挂载目录是容器内/data/app/logs下
- name: filebeatconf
mountPath: /usr/share/filebeat/filebeat.yml #挂载目录是容器内/usr/share/filebeat/filebeat.yml
subPath: filebeat.yml #挂载文件名是filebeat.yml

volumes: #定义卷
- name: filebeatconf
configMap:
name: filebeatconf
items:
- key: filebeat.yml
path: filebeat.yml
- name: logpath #卷的名字是logpath
emptyDir: {} #存储卷类型为 emptyDir,它的生命周期与 Pod 绑定,通常用于在同一个 Pod 的多个容器间共享数据(例如业务容器写日志,Sidecar 容器读日志)

准备ConfigMap资源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
apiVersion: v1
kind: ConfigMap
metadata:
name: filebeatconf
namespace: default # 建议加上命名空间,按实际修改
data:
filebeat.yml: |
#############################
# Filebeat 基础配置
#############################
# 关闭自动探测新配置(Sidecar 场景下配置是静态的)
filebeat.config.inputs:
enabled: false

# 日志采集输入配置
filebeat.inputs:
- type: filestream # 新版本推荐使用 filestream
id: app-logs # 每个 filestream 输入建议加一个唯一 id
enabled: true
paths:
- /data/app/logs/*.log # 共享 Volume 中的日志路径(根据实际挂载路径调整)
# - /data/log/*.log # 如果日志直接在目录下,也可以加这一行

# 从文件末尾开始采集(避免启动时把历史日志全部重新发送)
tail_files: true

# 忽略比指定时间更早的日志(可选,防止采集过旧数据)
# ignore_older: 24h

# 文件不活跃多久后关闭句柄(节省资源)
close_inactive: 5m

# 文件被删除后多久清理状态
close_removed: true
clean_removed: true

# 多行日志合并(Java 异常堆栈、JSON 等多行日志非常有用)
multiline.pattern: '^[[:space:]]+(at|\.{3})|^Caused by:'
multiline.negate: false
multiline.match: after

# 给每条日志添加自定义字段(这些值需要通过 Downward API 注入环境变量)
fields:
pod_name: '${POD_NAME}'
pod_ip: '${POD_IP}'
pod_deploy_name: '${POD_DEPLOY_NAME}'
pod_namespace: '${POD_NAMESPACE}'
log_type: "file-log" # 方便后续在 Kibana 中过滤
fields_under_root: false # 字段放在 fields 下面,不覆盖原有字段

# 添加处理器(可选增强)
processors:
- add_fields:
target: ''
fields:
collector: "filebeat-sidecar"

#############################
# 输出到 Kafka
#############################
output.kafka:
hosts: ["kafka.logging.svc.cluster.local:9092"]
topic: "k8spodlogs"
# 分区策略(可选)
# partition.round_robin:
# reachable_only: false
required_acks: 1 # 0=不等待确认,1=leader确认,-1=所有副本确认
compression: gzip # 压缩减少网络传输
max_message_bytes: 1000000
# ---------- SASL 认证(你的环境必须配置)----------
username: "user1"
password: "${KAFKA_PASSWORD}" # 通过环境变量注入,禁止明文写在 YAML
sasl.mechanism: "SCRAM-SHA-256"

codec.json:
pretty: false # 生产环境关闭美化,减少体积

keep_alive: 30s

#############################
# 日志与监控(可选但推荐)
#############################
logging.level: info
logging.to_files: false # Sidecar 中建议输出到 stdout,方便排查
logging.to_stderr: true

# 开启 HTTP 监控端点(方便查看 Filebeat 自身状态)
http.enabled: true
http.host: 0.0.0.0
http.port: 5066

因为我的kafka需要认证,所以还要准备一个secret:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 在上面步骤中的案例用到过kafka的secret,把它在default空间创建即可,因为业务的服务部署在default
cat filebeat-secret-kafka.yaml
apiVersion: v1
data:
client-passwords: Yzk4dm9BdVFOSA==
controller-password: YktoNWNKV3dkSA==
inter-broker-password: ZkhnNXd3SVFwdQ==
system-user-password: Yzk4dm9BdVFOSA==
kind: Secret
metadata:
name: kafka-user-passwords
namespace: default
type: Opaque

创建资源:

1
2
3
4
5
6
7
8
9
10
11
# 创建secret
[root@k8s-master01 29-eck]# kubectl create -f filebeat-secret-kafka.yaml
secret/kafka-user-passwords created

#先创建cm
[root@k8s-master01 29-eck]# kubectl create -f filebeat-cm.yaml
configmap/filebeatconf created

# 在更新业务服务
[root@k8s-master01 29-eck]# kubectl replace -f app.yaml
deployment.apps/app replaced

查看服务是否正常启动:

1
2
3
[root@k8s-master01 29-eck]# kubectl get po
NAME READY STATUS RESTARTS AGE
app-5b48674877-vn5kk 2/2 Running 0 6s

在控制台检查日志:可以根据上述filebeat-cm.yaml中定义的fields字段来过滤日志:

1
2
3
4
5
6
7
# 给每条日志添加自定义字段(这些值需要通过 Downward API 注入环境变量)
fields:
pod_name: '${POD_NAME}'
pod_ip: '${POD_IP}'
pod_deploy_name: '${POD_DEPLOY_NAME}'
pod_namespace: '${POD_NAMESPACE}'
log_type: "file-log" # 方便后续在 Kibana 中过滤

message列就是在应用中使用do date 模拟的日志信息:

4.清理环境

如果不想留整个环境可以删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# 删除步骤11中创建的资源
[root@k8s-master01 29-eck]# kubectl delete -f app.yaml
deployment.apps "app" deleted
[root@k8s-master01 29-eck]# kubectl delete -f filebeat-cm.yaml
configmap "filebeatconf" deleted
[root@k8s-master01 29-eck]# kubectl delete -f filebeat-secret-kafka.yaml
secret "kafka-user-passwords" deleted

# 整个资源创建的pod
[root@k8s-master01 29-eck]# kubectl get po -n logging
NAME READY STATUS RESTARTS AGE
es-cluster-es-default-0 1/1 Running 0 16h
es-cluster-es-default-1 1/1 Running 0 3d4h
es-cluster-es-default-2 1/1 Running 0 3d4h
filebeat-beat-filebeat-62fgl 1/1 Running 0 57m
filebeat-beat-filebeat-jbgbx 1/1 Running 0 58m
filebeat-beat-filebeat-rt25s 1/1 Running 0 56m
filebeat-beat-filebeat-tzhsz 1/1 Running 0 56m
filebeat-beat-filebeat-vt7bd 1/1 Running 0 57m
filebeat-beat-filebeat-zxpqb 1/1 Running 0 58m
kafka-broker-0 1/1 Running 0 94m
kafka-broker-1 1/1 Running 0 94m
kafka-broker-2 1/1 Running 0 94m
kibana-kb-588655d67d-9n47v 1/1 Running 0 3d4h
kibana-kb-588655d67d-hk5z8 1/1 Running 0 3d4h
logstash-ls-0 1/1 Running 0 63m
logstash-ls-1 1/1 Running 0 64m
logstash-ls-2 1/1 Running 0 65m
zookeeper-0 1/1 Running 0 104m
zookeeper-1 1/1 Running 0 104m
zookeeper-2 1/1 Running 0 104m


#删除filebeat资源
[root@k8s-master01 29-eck]# kubectl delete -f Filebeat.yaml
beat.beat.k8s.elastic.co "filebeat" deleted

# 删除logstash资源
[root@k8s-master01 29-eck]# kubectl delete -f Logstash.yaml
logstash.logstash.k8s.elastic.co "logstash" deleted

# 使用helm部署zk和kafka
[root@k8s-master01 29-eck]# helm list -n logging
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
kafka logging 1 2026-09-05 20:29:36.587891463 +0800 CST deployed kafka-31.5.0 3.9.0
zookeeper logging 1 2026-09-05 20:20:23.441405309 +0800 CST deployed zookeeper-13.7.4 3.9.3

# 删除kafka
[root@k8s-master01 29-eck]# helm uninstall kafka -n logging
release "kafka" uninstalled

#删除zk
[root@k8s-master01 29-eck]# helm uninstall -n logging zookeeper
release "zookeeper" uninstalled

#删除kibana资源
[root@k8s-master01 29-eck]# kubectl delete -f Kibana.yaml
kibana.kibana.k8s.elastic.co "kibana" deleted

#删除es资源
[root@k8s-master01 29-eck]# kubectl delete -f Elasticsearch.yaml
elasticsearch.elasticsearch.k8s.elastic.co "es-cluster" deleted

#删除crd
[root@k8s-master01 29-eck]# kubectl delete -f crds.yaml
customresourcedefinition.apiextensions.k8s.io "agents.agent.k8s.elastic.co" deleted
customresourcedefinition.apiextensions.k8s.io "apmservers.apm.k8s.elastic.co" deleted
customresourcedefinition.apiextensions.k8s.io "autoopsagentpolicies.autoops.k8s.elastic.co" deleted
customresourcedefinition.apiextensions.k8s.io "beats.beat.k8s.elastic.co" deleted
customresourcedefinition.apiextensions.k8s.io "elasticmapsservers.maps.k8s.elastic.co" deleted
customresourcedefinition.apiextensions.k8s.io "elasticsearchautoscalers.autoscaling.k8s.elastic.co" deleted
customresourcedefinition.apiextensions.k8s.io "elasticsearches.elasticsearch.k8s.elastic.co" deleted
customresourcedefinition.apiextensions.k8s.io "enterprisesearches.enterprisesearch.k8s.elastic.co" deleted
customresourcedefinition.apiextensions.k8s.io "kibanas.kibana.k8s.elastic.co" deleted
customresourcedefinition.apiextensions.k8s.io "logstashes.logstash.k8s.elastic.co" deleted
customresourcedefinition.apiextensions.k8s.io "packageregistries.packageregistry.k8s.elastic.co" deleted
customresourcedefinition.apiextensions.k8s.io "stackconfigpolicies.stackconfigpolicy.k8s.elastic.co" deleted

#删除operator
[root@k8s-master01 29-eck]# kubectl delete -f operator.yaml
namespace "elastic-system" deleted
serviceaccount "elastic-operator" deleted
secret "elastic-webhook-server-cert" deleted
configmap "elastic-operator" deleted
clusterrole.rbac.authorization.k8s.io "elastic-operator" deleted
clusterrole.rbac.authorization.k8s.io "elastic-operator-view" deleted
clusterrole.rbac.authorization.k8s.io "elastic-operator-edit" deleted
clusterrolebinding.rbac.authorization.k8s.io "elastic-operator" deleted
service "elastic-webhook-server" deleted
statefulset.apps "elastic-operator" deleted
validatingwebhookconfiguration.admissionregistration.k8s.io "elastic-webhook.k8s.elastic.co" deleted