阶段七:Kubernetes基于ELK集中化日志管理
K8s日志收集方案
ELK简介:
ELK是由ElasticSearch 、Logstash、Kibana三个开源软件的缩写,是一套集合日志收集、过滤、展示的解决方案。
- Elasticsearch:是个开源分布式搜索引擎数据库,提供搜索、分析、存储数据三大功能。
- Logstash:主要是用来做日志的收集、过滤等处理工作。
- Kibana:为ElasticSearch提供Web界面,可以帮助汇总、分析和搜索日志。

日志收集Fluentd
- Fluentd需要在每个Pod中都附带一个Agent容器(通过sidecar方式在一个Pod运行业务容器和fluentd容器)来对本Pod内部容器的日志进行采集。

日志收集Filebeat
- Filebeat是elasticStack家族中的一个轻量级的日志收集处理工具,Filebeat占用资源少,适合在各个服务器上搜集日志。
- 在每个Node节点仅会部署一个Filebeat进行日志采集,对比与上述fluentd(每个Pod中部署一个Agent)更加的节约资源。
- 通过Filebeat自动发现机制,能够自动感知宿主机上容器的创建和删除事件,进而动态配置容器日志采集配置文件

K8s 环境部署 ELK
通过StatefulSet部署 ES 集群
- 创建命名空间和编写yaml文件
mkdir elk && cd elk
kubectl create ns elk可复制 YAML:
| 项目 | 应该怎么做 |
|---|---|
| 配置类型 | Kubernetes Service + StatefulSet |
| 文件名 | elasticsearch.yml |
| 写在哪里 | 保存到 ~/k8s-manifests/elk/elasticsearch.yml;这是 Kubernetes 清单文件,不是容器内 /etc 配置。 |
| 在哪台机器执行 | Kubernetes 管理节点,或已配置正确 kubeconfig 且能执行 kubectl 的运维机。 |
| 复制后重点改 | namespace、主容器 image、replicas、storageClassName、storage |
| 应用配置 | kubectl apply -f elasticsearch.yml |
| 验证结果 | kubectl get pod -n elk |
| 注意事项 | ES 需要可用的 StorageClass;不要修改 BusyBox 初始化镜像。 |
apiVersion: v1
kind: Service
metadata:
name: es-cluster-svc
namespace: elk
spec:
clusterIP: None
selector:
app: elasticsearch
ports:
- name: http #客户端访问端口
port: 9200
- name: transport #集群之间通信端口
port: 9300
targetPort: 9300
---
# es-cluster.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: es-cluster
namespace: elk
spec:
serviceName: es-cluster-svc
replicas: 3 #设置副本数
selector:
matchLabels:
app: elasticsearch
template:
metadata:
labels:
app: elasticsearch #Pod标签
spec:
#避免三个es都运行在同一节点,通过Pod反亲和策略,不要让Pod运行在同一节点
affinity: #设置Pod亲和与反亲和调度策略
podAntiAffinity: #Pod反亲和调度
preferredDuringSchedulingIgnoredDuringExecution: #在调度时优先以下的规则
- weight: 100 # 权重(1~100,值越大优先级越高)
podAffinityTerm:
labelSelector: #通过标签选择器匹配Pod标签
matchExpressions: #标签选择的表达式
- key: app #标签名称
operator: In
values: ["elasticsearch"] #标签名称的value
topologyKey: "kubernetes.io/hostname" #通过主机名称辨别不同节点
#通过容器部署es参考:https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docker.html
initContainers:
- name: vm-max-map-count
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/busybox:1.32
#通过容器部署es,官方要求修改系统内核参数“vm.max_map_count”这个参数控制一个进程可以拥有的最大内存映射区域的数量,通常在运行需要大量内存映射的应用(如 Elasticsearch)时需要调整
#容器使用 sysctl 命令设置 Linux 内核参数
command: ["sh", "-c", "sysctl -w vm.max_map_count=262144"]
securityContext: #初始容器安全上下文(访问权限)
privileged: true #设置为特权模式,即拥有主机上的root权限
- name: ulimit
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/busybox:1.32
command: ["sh", "-c", "ulimit -n 65536"]
securityContext:
privileged: true
- name: fix-permissions
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/busybox:1.32
command:
- sh
- -c
- chmod -R 777 /usr/share/elasticsearch/data
volumeMounts:
- name: elasticsearch-data
mountPath: /usr/share/elasticsearch/data
containers:
- name: es-container
image: harbor.lanqicheng.top/library/elasticsearch:7.8.1
ports:
# 容器内端口
- name: http
containerPort: 9200
- name: transport
containerPort: 9300
#限制CPU数量
resources:
limits:
cpu: 1000m
requests:
cpu: 100m
# 设置挂载目录
volumeMounts:
- name: elasticsearch-data
mountPath: /usr/share/elasticsearch/data
# 设置环境变量
env:
- name: TZ
value: "Asia/Shanghai"
# 自定义集群名
- name: cluster.name
value: k8s-es
# 定义节点名,使用metadata.name名称
- name: node.name #当前节点在集群名称
valueFrom:
fieldRef:
fieldPath: metadata.name #名称通过该属性下定义的值获取,即:es-cluster-0,es-cluster-1,es-cluster-2
# 初始化集群时,ES从中选出master节点
- name: cluster.initial_master_nodes
# 对应metadata.name名称加编号,编号从0开始
value: "es-cluster-0,es-cluster-1,es-cluster-2"
# 发现节点的地址,discovery.seed_hosts的值应包括所有master候选节点
- name: discovery.seed_hosts
value: "es-cluster-svc"
# 配置JVM堆内存(JVM 的堆内存是 Java 应用程序中对象和数组的主要存储区域,负责动态内存管理和垃圾回收,是 Java 程序运行的核心部分)
- name: ES_JAVA_OPTS
value: "-Xms1g -Xmx1g"
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
# 存储卷访问权限为读写
accessModes: [ "ReadWriteOnce" ]
# 动态存储名称
storageClassName: "nfs-storage"
# 申请资源的大小
resources:
requests:
storage: 1Gi配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: elk | 与实际命名空间一致;使用默认命名空间时可不写。 |
port: 9200 | 对外暴露的 Service 端口;调用方按此端口访问。 |
port: 9300 | 对外暴露的 Service 端口;调用方按此端口访问。 |
targetPort: 9300 | 必须与容器实际监听端口一致。 |
replicas: 3 | 按可用性和资源容量设置副本数。 |
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/busybox:1.32 | 替换为实际可拉取的镜像地址和版本。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
- 镜像地址、版本号和拉取权限要确认,否则 Pod 会进入
ImagePullBackOff。
[root@master elk]# kubectl apply -f elasticsearch.yml
[root@master elk]# kubectl get pod -n elk
NAME READY STATUS RESTARTS AGE
es-cluster-0 1/1 Running 0 3m45s
es-cluster-1 1/1 Running 0 2m51s
es-cluster-2 1/1 Running 0 104s注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
| 项目 | 应该怎么做 |
|---|---|
| 配置类型 | Kubernetes Service + StatefulSet |
| 文件名 | elasticsearch.yml |
| 写在哪里 | 保存到 ~/k8s-manifests/elk/elasticsearch.yml;这是 Kubernetes 清单文件,不是容器内 /etc 配置。 |
| 在哪台机器执行 | Kubernetes 管理节点,或已配置正确 kubeconfig 且能执行 kubectl 的运维机。 |
| 复制后重点改 | namespace、主容器 image、replicas、storageClassName、storage |
| 应用配置 | kubectl apply -f elasticsearch.yml |
| 验证结果 | kubectl get pod -n elk |
| 注意事项 | ES 需要可用的 StorageClass;不要修改 BusyBox 初始化镜像。 |
apiVersion: v1
kind: Service
metadata:
name: es-cluster-svc
namespace: elk
spec:
clusterIP: None
selector:
app: elasticsearch
ports:
- name: http #客户端访问端口
port: 9200
- name: transport #集群之间通信端口
port: 9300
targetPort: 9300
---
# es-standone.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: es-cluster
namespace: elk
spec:
serviceName: es-cluster-svc
replicas: 1 #设置副本数
selector:
matchLabels:
app: elasticsearch
template:
metadata:
labels:
app: elasticsearch #Pod标签
spec:
#通过容器部署es参考:https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docker.html
initContainers:
- name: vm-max-map-count
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/busybox:1.32
#通过容器部署es,官方要求修改系统内核参数“vm.max_map_count”这个参数控制一个进程可以拥有的最大内存映射区域的数量,通常在运行需要大量内存映射的应用(如 Elasticsearch)时需要调整
#容器使用 sysctl 命令设置 Linux 内核参数
command: ["sysctl", "-w", "vm.max_map_count=262144"]
securityContext: #初始容器安全上下文(访问权限)
privileged: true #设置为特权模式,即拥有主机上的root权限
- name: ulimit
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/busybox:1.32
command: ["sh", "-c", "ulimit -n 65536"]
securityContext:
privileged: true
- name: fix-permissions
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/busybox:1.32
command:
- sh
- -c
- chmod -R 777 /usr/share/elasticsearch/data
volumeMounts:
- name: elasticsearch-data
mountPath: /usr/share/elasticsearch/data
containers:
- name: es-container
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.elastic.co/elasticsearch/elasticsearch:7.8.1
ports:
# 容器内端口
- name: http
containerPort: 9200
- name: transport
containerPort: 9300
#限制CPU数量
resources:
limits:
cpu: 1000m
requests:
cpu: 100m
# 设置挂载目录
volumeMounts:
- name: elasticsearch-data
mountPath: /usr/share/elasticsearch/data
# 设置环境变量
env:
- name: TZ
value: "Asia/Shanghai"
# 自定义集群名
- name: cluster.name
value: k8s-es
# 定义节点名,使用metadata.name名称
- name: node.name #当前节点在集群名称
valueFrom:
fieldRef:
fieldPath: metadata.name #名称通过该属性下定义的值获取,即:es-cluster-0,es-cluster-1,es-cluster-2
- name: cluster.initial_master_nodes
# 对应metadata.name名称加编号,编号从0开始
value: "es-cluster-0"
# 发现节点的地址,discovery.seed_hosts的值应包括所有master候选节点
- name: discovery.seed_hosts
value: "es-cluster-svc"
- name: ES_JAVA_OPTS
value: "-Xms1g -Xmx1g"
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
# 存储卷访问权限为读写
accessModes: [ "ReadWriteOnce" ]
# 动态存储名称
storageClassName: "nfs-storage"
# 申请资源的大小
resources:
requests:
storage: 1Gi配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: elk | 与实际命名空间一致;使用默认命名空间时可不写。 |
port: 9200 | 对外暴露的 Service 端口;调用方按此端口访问。 |
port: 9300 | 对外暴露的 Service 端口;调用方按此端口访问。 |
targetPort: 9300 | 必须与容器实际监听端口一致。 |
replicas: 1 | 按可用性和资源容量设置副本数。 |
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/busybox:1.32 | 替换为实际可拉取的镜像地址和版本。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
- 镜像地址、版本号和拉取权限要确认,否则 Pod 会进入
ImagePullBackOff。
K8s 部署 kibana
- 通过Deployment部署Kibana
| 项目 | 应该怎么做 |
|---|---|
| 配置类型 | Kubernetes Deployment + Service + Ingress |
| 文件名 | kibana.yml |
| 写在哪里 | 保存到 ~/k8s-manifests/elk/kibana.yml;这是 Kubernetes 清单文件,不是容器内 /etc 配置。 |
| 在哪台机器执行 | Kubernetes 管理节点,或已配置正确 kubeconfig 且能执行 kubectl 的运维机。 |
| 复制后重点改 | namespace、Kibana image、port、targetPort、Ingress host |
| 应用配置 | kubectl apply -f kibana.yml |
| 验证结果 | kubectl get pod,svc,ingress -n elk |
| 注意事项 | ELASTICSEARCH_HOSTS 应指向 Elasticsearch Service;域名需要已解析到 Ingress。 |
apiVersion: apps/v1
kind: Deployment
metadata:
name: kibana
namespace: elk
spec:
selector:
matchLabels:
app: kibana
template:
metadata:
labels:
app: kibana
spec:
containers:
- name: kibana
image: harbor.lanqicheng.top/library/kibana:7.8.1
ports:
- containerPort: 5601
env:
- name: TZ
value: "Asia/Shanghai"
- name: ELASTICSEARCH_HOSTS #指定ES地址及端口
value: http://es-cluster-svc:9200
- name: I18N_LOCALE #kibana汉化
value: "zh-CN"
---
#kibana Service
apiVersion: v1
kind: Service
metadata:
name: kibana-svc
namespace: elk
spec:
selector:
app: kibana
ports:
- port: 5601
targetPort: 5601
---
#kibana Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kibana-ingress
namespace: elk
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: kibana.lancheng.top
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kibana-svc
port:
number: 5601 配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: elk | 与实际命名空间一致;使用默认命名空间时可不写。 |
image: harbor.lanqicheng.top/library/kibana:7.8.1 | 替换为实际可拉取的镜像地址和版本。 |
port: 5601 | 对外暴露的 Service 端口;调用方按此端口访问。 |
targetPort: 5601 | 必须与容器实际监听端口一致。 |
host: kibana.lancheng.top | 替换为已解析到 Ingress 的实际域名。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
- 镜像地址、版本号和拉取权限要确认,否则 Pod 会进入
ImagePullBackOff。
[root@master elk]# kubectl apply -f kibana.yml注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
k8s 环境部署 filebeat
- 通过RBAC授权filebeat访问集群的权限
| 项目 | 应该怎么做 |
|---|---|
| 配置类型 | Kubernetes ServiceAccount + RBAC |
| 文件名 | filebeat-rbac.yml |
| 写在哪里 | 保存到 ~/k8s-manifests/elk/filebeat-rbac.yml;这是 Kubernetes 清单文件,不是容器内 /etc 配置。 |
| 在哪台机器执行 | Kubernetes 管理节点,或已配置正确 kubeconfig 且能执行 kubectl 的运维机。 |
| 复制后重点改 | 通常不用改;仅在命名空间不同或账号名称变更时调整 |
| 应用配置 | kubectl apply -f filebeat-rbac.yml |
| 验证结果 | kubectl get serviceaccount filebeat -n elk |
| 注意事项 | ServiceAccount、ClusterRoleBinding 的引用名称必须保持一致。 |
apiVersion: v1
kind: ServiceAccount
metadata:
name: filebeat
namespace: elk
---
#创建集群角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: filebeat
labels:
k8s-app: filebeat
rules:
- apiGroups: [""] # "" indicates the core API group
resources:
- namespaces
- pods
- nodes
verbs:
- get
- watch
- list
---
#创建集群角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: filebeat
subjects:
- kind: ServiceAccount
name: filebeat
namespace: elk
roleRef:
kind: ClusterRole
name: filebeat
apiGroup: rbac.authorization.k8s.io配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: elk | 与实际命名空间一致;使用默认命名空间时可不写。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
| 项目 | 应该怎么做 |
|---|---|
| 配置类型 | Kubernetes ConfigMap |
| 文件名 | filebeat-configmap.yml |
| 写在哪里 | 保存到 ~/k8s-manifests/elk/filebeat-configmap.yml;这是 Kubernetes 清单文件,不是容器内 /etc 配置。 |
| 在哪台机器执行 | Kubernetes 管理节点,或已配置正确 kubeconfig 且能执行 kubectl 的运维机。 |
| 复制后重点改 | namespace、日志路径或采集规则(仅按实际日志位置调整) |
| 应用配置 | kubectl apply -f filebeat-configmap.yml |
| 验证结果 | kubectl get configmap filebeat-config -n elk |
| 注意事项 | 修改 ConfigMap 后,已运行的 Filebeat 是否读取新配置取决于挂载方式和重载策略。 |
apiVersion: v1
kind: ConfigMap
metadata:
name: filebeat-config
namespace: elk
data:
filebeat.yml: |-
# =========================== Filebeat autodiscover ==============================
filebeat.autodiscover: #通过filebeat自动发现机制采集日志
providers:
- type: kubernetes #收集kubernetes集群日志
templates: #自动发现模板
# =================== 收集kube-system空间日志 ============================
- condition: #定义条件
equals: #等于
kubernetes.namespace: kube-system #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stderr #收集错误日志
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# =========================== Output =====================================
# 先将日志内容输出到console看效果,容器启动后可通过 kubectl logs Pod名称 查看日志输出
output.console:
pretty: true
enable: true
[root@master elk]# kubectl apply -f filebeat-configmap.yml配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: elk | 与实际命名空间一致;使用默认命名空间时可不写。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
| 项目 | 应该怎么做 |
|---|---|
| 配置类型 | Kubernetes DaemonSet |
| 文件名 | filebeat.yml |
| 写在哪里 | 保存到 ~/k8s-manifests/elk/filebeat.yml;这是 Kubernetes 清单文件,不是容器内 /etc 配置。 |
| 在哪台机器执行 | Kubernetes 管理节点,或已配置正确 kubeconfig 且能执行 kubectl 的运维机。 |
| 复制后重点改 | namespace、Filebeat image、挂载日志路径(仅路径不同才改) |
| 应用配置 | kubectl apply -f filebeat.yml |
| 验证结果 | kubectl rollout status daemonset/filebeat -n elk |
| 注意事项 | DaemonSet 应在每个需要采集日志的节点运行。 |
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat
namespace: elk
spec:
selector:
matchLabels:
app: filebeat
template:
metadata:
labels:
app: filebeat
spec:
#如果master节点有污点,需要添加容忍(根据自己实际情况修改)
tolerations: #添加容忍
- key: "node-role.kubernetes.io/control-plane" #污点的key(必须引起来)
#value: "" #key的值,没有无需定义
effect: NoSchedule #容器的污点
serviceAccountName: filebeat #指定服务账户名称
containers:
- name: filebeat
image: harbor.lanqicheng.top/library/filebeat:7.8.1
#通过args传递配置和参数到容器,command、args两项实现覆盖Dockerfile中ENTRYPOINT的功能,在Dockerfile的ENTRYPOINT中定义的filebeat配置文件路径为/usr/share/filebeat/
args: [
"-c", "/etc/filebeat.yml", #指定日志过滤的配置文件位置
"-e", #-e是filebeat自带选项,用于将日志输出发送到标准错误(stderr)以便通过kubectl logs查看filebeat日志
]
#securityContext用于定义Pod或容器安全设置的属性,以确保容器在运行时具有适当的权限。
securityContext:
runAsUser: 0 #指定容器以UID为0的用户身份运行(root身份),后边需要该容器在节点中创建目录,以及对系统中的日志文件有访问权限
resources:
limits:
memory: 500Mi
requests:
cpu: 100m
memory: 100Mi
env:
- name: TZ
value: "Asia/Shanghai"
volumeMounts: #挂载存储卷
- name: config #卷名称
mountPath: /etc/filebeat.yml #挂载到容器路径
subPath: filebeat.yml #避免覆盖掉/etc目录下其他文件
readOnly: true #权限只读,防止容器中的进程无意识地对文件进行修改
- name: data
mountPath: /usr/share/filebeat/data
- name: varlibdockercontainers
mountPath: /var/log/containers
readOnly: true
- name: varlog
mountPath: /var/log
readOnly: true
volumes: #定义存储卷
- name: config #卷名称
configMap: #卷类型CM
name: filebeat-config #CM名称,该文件用于过滤日志
- name: varlibdockercontainers #卷名称
hostPath: #卷类型为本地目录
path: /var/log/containers #该路径是存储当前节点的容器元数据信息
- name: varlog #卷名称
hostPath: #卷类型为本地目录
path: /var/log #该路径是存储当前节点的系统日志
- name: data #卷名称
hostPath: #卷类型为本地目录
path: /var/lib/filebeat-data #data文件夹存储filebeat过滤的所有文件状态信息
type: DirectoryOrCreate #该目录默认不存在,不存在自动创建
[root@master01 elk]# kubectl apply -f filebeat.yml配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: elk | 与实际命名空间一致;使用默认命名空间时可不写。 |
image: harbor.lanqicheng.top/library/filebeat:7.8.1 | 替换为实际可拉取的镜像地址和版本。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
- 镜像地址、版本号和拉取权限要确认,否则 Pod 会进入
ImagePullBackOff。
收集 Ingress-nginx 日志
| 项目 | 应该怎么做 |
|---|---|
| 配置类型 | Kubernetes ConfigMap |
| 文件名 | filebeat-config.yaml |
| 写在哪里 | 保存到 ~/k8s-manifests/elk/filebeat-config.yaml;这是 Kubernetes 清单文件,不是容器内 /etc 配置。 |
| 在哪台机器执行 | Kubernetes 管理节点,或已配置正确 kubeconfig 且能执行 kubectl 的运维机。 |
| 复制后重点改 | namespace、日志路径、采集命名空间或正则规则 |
| 应用配置 | kubectl apply -f filebeat-config.yaml |
| 验证结果 | kubectl get configmap filebeat-config -n elk |
| 注意事项 | 只修改与你的日志来源对应的采集规则。 |
apiVersion: v1
kind: ConfigMap
metadata:
name: filebeat-config
namespace: elk
data:
filebeat.yml: |-
# =========================== Filebeat autodiscover ==============================
filebeat.autodiscover: #通过filebeat自动发现机制采集日志
providers:
- type: kubernetes #收集kubernetes集群日志
templates: #自动发现模板
# =================== 收集kube-system空间日志 ============================
- condition: #定义条件
equals: #等于
kubernetes.namespace: kube-system #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stderr #收集错误日志
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# =================== 收集ingress-nginx 访问日志 =========================
- condition: #定义条件
equals: #等于
kubernetes.namespace: ingress-nginx #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stdout #对于nginx来说,访问日志默认写入到stdout中
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# =================== 收集ingress-nginx 错误日志 =========================
- condition: #定义条件
equals: #等于
kubernetes.namespace: ingress-nginx #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stderr #收集错误日志
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# =========================== Output =====================================
# 先将日志内容输出到console看效果,容器启动后可通过 kubectl logs Pod名称 查看日志输出
output.console:
pretty: true
enable: true配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: elk | 与实际命名空间一致;使用默认命名空间时可不写。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
收集 kubelet 组件日志
| 项目 | 应该怎么做 |
|---|---|
| 配置类型 | Kubernetes ConfigMap |
| 文件名 | filebeat-config.yaml |
| 写在哪里 | 保存到 ~/k8s-manifests/elk/filebeat-config.yaml;这是 Kubernetes 清单文件,不是容器内 /etc 配置。 |
| 在哪台机器执行 | Kubernetes 管理节点,或已配置正确 kubeconfig 且能执行 kubectl 的运维机。 |
| 复制后重点改 | namespace、日志路径、采集命名空间或正则规则 |
| 应用配置 | kubectl apply -f filebeat-config.yaml |
| 验证结果 | kubectl get configmap filebeat-config -n elk |
| 注意事项 | 只修改与你的日志来源对应的采集规则。 |
apiVersion: v1
kind: ConfigMap
metadata:
name: filebeat-config
namespace: elk
data:
filebeat.yml: |-
# ============================== Filebeat inputs kubelet ================================
filebeat.inputs:
- type: log
paths: /var/log/messages #kubelet日志默认写入到该文件中
include_lines: ['kubelet'] #在messages文件中只获取与kubelet相关的日志
fields: #为收集到的日志内容添加新字段名称
NameSpace: kubelet #增加新字段,后边作为索引名称
fields_under_root: true #并设置为顶级字段,否则到logstash中无法识别索引名称
exclude_lines: ["^.*\\[info\\].*"] #使用正则表达式排除info相关日志,info日志属于正常日志(\表示匹配\,\表示转义)
# =========================== Filebeat autodiscover ==============================
filebeat.autodiscover: #通过filebeat自动发现机制采集日志
providers:
- type: kubernetes #收集kubernetes集群日志
templates: #自动发现模板
# =================== 收集kube-system空间日志 ============================
- condition: #定义条件
equals: #等于
kubernetes.namespace: kube-system #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stderr #收集错误日志
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# =================== 收集ingress-nginx 访问日志 =========================
- condition: #定义条件
equals: #等于
kubernetes.namespace: ingress-nginx #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stdout #对于nginx来说,访问日志默认写入到stdout中
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
json.keys_under_root: true #默认将json解析存储至messages,true则不存储至message
json.overwrite_keys: true #覆盖默认message字段,使用自定义json格式的key
# =================== 收集ingress-nginx 错误日志 =========================
- condition: #定义条件
equals: #等于
kubernetes.namespace: ingress-nginx #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stderr #收集错误日志
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# =========================== Output =====================================
# 先将日志内容输出到console看效果,容器启动后可通过 kubectl logs Pod名称 查看日志输出
output.console:
pretty: true
enable: true配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: elk | 与实际命名空间一致;使用默认命名空间时可不写。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
收集中洲养老项目日志
- filebeat定义收集zzyl命名空间日志
| 项目 | 应该怎么做 |
|---|---|
| 配置类型 | Kubernetes ConfigMap |
| 文件名 | filebeat-config.yaml |
| 写在哪里 | 保存到 ~/k8s-manifests/elk/filebeat-config.yaml;这是 Kubernetes 清单文件,不是容器内 /etc 配置。 |
| 在哪台机器执行 | Kubernetes 管理节点,或已配置正确 kubeconfig 且能执行 kubectl 的运维机。 |
| 复制后重点改 | namespace、日志路径、采集命名空间或正则规则 |
| 应用配置 | kubectl apply -f filebeat-config.yaml |
| 验证结果 | kubectl get configmap filebeat-config -n elk |
| 注意事项 | 只修改与你的日志来源对应的采集规则。 |
apiVersion: v1
kind: ConfigMap
metadata:
name: filebeat-config
namespace: elk
data:
filebeat.yml: |-
# ============================== Filebeat inputs kubelet ================================
filebeat.inputs:
- type: log
paths: /var/log/messages #kubelet日志默认写入到该文件中
include_lines: ['kubelet'] #在messages文件中只获取与kubelet相关的日志
fields: #为收集到的日志内容添加新字段名称
NameSpace: kubelet #增加新字段,后边作为索引名称
fields_under_root: true #并设置为顶级字段,否则到logstash中无法识别索引名称
exclude_lines: ["^.*\\[info\\].*"] #使用正则表达式排除info相关日志,info日志属于正常日志(\表示匹配\,\表示转义)
# =========================== Filebeat autodiscover ==============================
filebeat.autodiscover: #通过filebeat自动发现机制采集日志
providers:
- type: kubernetes #收集kubernetes集群日志
templates: #自动发现模板
# =================== 收集kube-system空间日志 ============================
- condition: #定义条件
equals: #等于
kubernetes.namespace: kube-system #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stderr #收集错误日志
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# =================== 收集ingress-nginx 访问日志 =========================
- condition: #定义条件
equals: #等于
kubernetes.namespace: ingress-nginx #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stdout #对于nginx来说,访问日志默认写入到stdout中
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
#json.keys_under_root: true #默认将json解析存储至messages,true则不存储至message
#json.overwrite_keys: true #覆盖默认message字段,使用自定义json格式的key
# =================== 收集ingress-nginx 错误日志 =========================
- condition: #定义条件
equals: #等于
kubernetes.namespace: ingress-nginx #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stderr #收集错误日志
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# =================== 收集zzyl空间日志 ============================
- condition: #定义条件
equals: #等于
kubernetes.namespace: zzyl #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: all #收集所有日志信息
encoding: utf-8 #字符集
multiline.pattern: '^\d{2}' #匹配以2个数字开头的行(日期开头)\d 匹配数字,等价于[0-9]
multiline.negate: true #将不符合规则的行合并在一起
multiline.match: after #合并到上一行的末尾
multiline.max_lines: 50 #默认最大合并的行为500,可根据实际情况调整
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# ============================== Filebeat对输出字段优化 ================================
processors:
- rename: #重写字段名称
fields:
- from: "kubernetes.namespace"
to: "NameSpace"
- from: "kubernetes.pod.name"
to: "PodName"
- drop_fields: #删除无用的字段
fields: ["log","agent","ecs","input","kubernetes"]
# =========================== Output =====================================
# 先将日志内容输出到console看效果,容器启动后可通过 kubectl logs Pod名称 查看日志输出
output.console:
pretty: true
enable: true配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: elk | 与实际命名空间一致;使用默认命名空间时可不写。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
filebeat 优化日志内容
| 项目 | 应该怎么做 |
|---|---|
| 配置类型 | Kubernetes ConfigMap |
| 文件名 | filebeat-config.yaml |
| 写在哪里 | 保存到 ~/k8s-manifests/elk/filebeat-config.yaml;这是 Kubernetes 清单文件,不是容器内 /etc 配置。 |
| 在哪台机器执行 | Kubernetes 管理节点,或已配置正确 kubeconfig 且能执行 kubectl 的运维机。 |
| 复制后重点改 | namespace、日志路径、采集命名空间或正则规则 |
| 应用配置 | kubectl apply -f filebeat-config.yaml |
| 验证结果 | kubectl get configmap filebeat-config -n elk |
| 注意事项 | 只修改与你的日志来源对应的采集规则。 |
apiVersion: v1
kind: ConfigMap
metadata:
name: filebeat-config
namespace: elk
data:
filebeat.yml: |-
# ============================== Filebeat inputs kubelet ================================
filebeat.inputs:
- type: log
paths: /var/log/messages #kubelet日志默认写入到该文件中
include_lines: ['kubelet'] #在messages文件中只获取与kubelet相关的日志
fields: #为收集到的日志内容添加新字段名称
NameSpace: kubelet #增加新字段,后边作为索引名称
fields_under_root: true #并设置为顶级字段,否则到logstash中无法识别索引名称
exclude_lines: ["^.*\\[info\\].*"] #使用正则表达式排除info相关日志,info日志属于正常日志(\表示匹配\,\表示转义)
# =========================== Filebeat autodiscover ==============================
filebeat.autodiscover: #通过filebeat自动发现机制采集日志
providers:
- type: kubernetes #收集kubernetes集群日志
templates: #自动发现模板
# =================== 收集kube-system空间日志 ============================
- condition: #定义条件
equals: #等于
kubernetes.namespace: kube-system #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stderr #收集错误日志
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# =================== 收集ingress-nginx 访问日志 =========================
- condition: #定义条件
equals: #等于
kubernetes.namespace: ingress-nginx #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stdout #对于nginx来说,访问日志默认写入到stdout中
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
json.keys_under_root: true #默认将json解析存储至messages,true则不存储至message
json.overwrite_keys: true #覆盖默认message字段,使用自定义json格式的key
# =================== 收集ingress-nginx 错误日志 =========================
- condition: #定义条件
equals: #等于
kubernetes.namespace: ingress-nginx #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stderr #收集错误日志
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# =================== 收集zzyl空间日志 ============================
- condition: #定义条件
equals: #等于
kubernetes.namespace: zzyl #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: all #收集所有日志信息
encoding: utf-8 #字符集
multiline.pattern: '^\d{2}' #匹配以2个数字开头的行(日期开头)\d 匹配数字,等价于[0-9]
multiline.negate: true #将不符合规则的行合并在一起
multiline.match: after #合并到上一行的末尾
multiline.max_lines: 1000 #默认最大合并的行为500,可根据实际情况调整
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# ============================== Filebeat对输出字段优化 ================================
processors:
- rename: #重写字段名称
fields:
- from: "kubernetes.namespace"
to: "NameSpace"
- from: "kubernetes.pod.name"
to: "PodName"
- drop_fields: #删除无用的字段
fields: ["log","agent","host","ecs","input","kubernetes"]
# =========================== Output =====================================
# 先将日志内容输出到console看效果,容器启动后可通过 kubectl logs Pod名称 查看日志输出
output.console:
pretty: true
enable: true配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: elk | 与实际命名空间一致;使用默认命名空间时可不写。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
k8s 环境部署 Logstash
- 创建ConfigMap过滤日志
| 项目 | 应该怎么做 |
|---|---|
| 配置类型 | Kubernetes ConfigMap |
| 文件名 | logstash-configmap.yml |
| 写在哪里 | 保存到 ~/k8s-manifests/elk/logstash-configmap.yml;这是 Kubernetes 清单文件,不是容器内 /etc 配置。 |
| 在哪台机器执行 | Kubernetes 管理节点,或已配置正确 kubeconfig 且能执行 kubectl 的运维机。 |
| 复制后重点改 | namespace、Logstash 输出地址或处理规则 |
| 应用配置 | kubectl apply -f logstash-configmap.yml |
| 验证结果 | kubectl get configmap logstash-config -n elk |
| 注意事项 | 文件名、ConfigMap 名称和工作负载挂载名称必须一致。 |
apiVersion: v1
kind: ConfigMap
metadata:
name: logstash-config
namespace: elk
data:
logstash-kubernetes.conf: |-
input {
beats {
port => 5044
}
}
filter {
#如果 NameSpace 的值等于 "kubelet" 则执行判断中的语句
#add_field用于添加字段名(后续作为索引名称),target_index 用于存储索引名称
if [NameSpace] == "kubelet" {
mutate {
add_field => { "target_index" => "%{[NameSpace]}-%{+YYYY.MM.dd}" }
}
}
#如果PodName 字段中包含字符串 "kube-apiserver-master" 则执行判断中的语句
if "kube-apiserver-master" in [PodName] {
mutate {
add_field => { "target_index" => "%{[PodName]}-%{+YYYY.MM.dd}" }
}
}
#如果PodName 字段中包含字符串 "kube-controller-manager-master" 则执行判断中的语句
if "kube-controller-manager-master" in [PodName] {
mutate {
add_field => { "target_index" => "%{[PodName]}-%{+YYYY.MM.dd}" }
}
}
#如果PodName 字段中包含字符串 "etcd-master" 则执行判断中的语句
if "etcd-master" in [PodName] {
mutate {
add_field => { "target_index" => "%{[PodName]}-%{+YYYY.MM.dd}" }
}
}
#如果PodName 字段中包含字符串 "coredns" 则执行判断中的语句
if "coredns" in [PodName] {
mutate {
add_field => { "target_index" => "%{[PodName]}-%{+YYYY.MM.dd}" }
}
}
#如果PodName 字段中包含字符串 "kube-proxy" 则执行判断中的语句
if "kube-proxy" in [PodName] {
mutate {
add_field => { "target_index" => "%{[PodName]}-%{+YYYY.MM.dd}" }
}
}
#如果PodName 字段中包含字符串 "calico" 则执行判断中的语句
if "calico" in [PodName] {
mutate {
add_field => { "target_index" => "%{[PodName]}-%{+YYYY.MM.dd}" }
}
}
#当 NameSpace 的值等于 "ingress-nginx" 并且 stream 字段的值等于 "stdout" 时,条件才会被满足
if [NameSpace] == "ingress-nginx" and [stream] == "stdout" {
#通过geoip获取客户端地理位置
geoip {
source => "clientip"
}
#通过useragent获取客户端操作系统、浏览器等信息
useragent {
#source用于指定要解析的字段
source => "user_agent"
#target用于指定转化后的值保存到那个字段中
target => "user_agent"
}
#获取日志生成时间,替换@timestamp(logstash过滤日志时间)
date {
match => ["timestamp","ISO8601"]
target => "@timestamp"
timezone => "Asia/Shanghai"
}
#通过convert对日志中的字段的数据类型进行转换
#bytes字段是发送给客户端的文件内容的大小,转换为整数类型
#response_time字段是服务端的响应时间,转换为浮点类型
#upstream_response_time字段是负载均衡服务器响应时间,转换为浮点类型
mutate {
convert => {
"bytes" => "integer"
"responsetime" => "float"
"upstreamtime" => "float"
}
add_field => { "target_index" => "%{[NameSpace]}-%{[stream]}-%{+YYYY.MM.dd}" }
}
}
#为ingress-nginx错误日志添加索引
if [NameSpace] == "ingress-nginx" and [stream] == "stderr" {
mutate {
add_field => { "target_index" => "%{[NameSpace]}-%{[stream]}-%{+YYYY.MM.dd}" }
}
}
#为zzyl-admin添加索引
if "zzyl-admin" in [PodName] {
mutate {
add_field => { "target_index" => "%{[PodName]}-%{+YYYY.MM.dd}" }
}
}
}
output {
elasticsearch {
hosts => ["es-cluster-svc:9200"]
index => "%{[target_index]}"
}
}
#创建
[root@master elk]# kubectl apply -f logstash-configmp.yml配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: elk | 与实际命名空间一致;使用默认命名空间时可不写。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
cat logstash.yaml可复制 YAML:
| 项目 | 应该怎么做 |
|---|---|
| 配置类型 | Kubernetes StatefulSet + Service |
| 文件名 | logstash.yml |
| 写在哪里 | 保存到 ~/k8s-manifests/elk/logstash.yml;这是 Kubernetes 清单文件,不是容器内 /etc 配置。 |
| 在哪台机器执行 | Kubernetes 管理节点,或已配置正确 kubeconfig 且能执行 kubectl 的运维机。 |
| 复制后重点改 | namespace、Logstash image、replicas、存储参数 |
| 应用配置 | kubectl apply -f logstash.yml |
| 验证结果 | kubectl get pod,svc -n elk |
| 注意事项 | 先确保 Logstash ConfigMap 已创建,再部署工作负载。 |
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: logstash
namespace: elk
spec:
serviceName: "logstash-svc"
replicas: 1
selector:
matchLabels:
app: logstash
template:
metadata:
labels:
app: logstash
spec:
initContainers:
- name: fix-logstash-permissions
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/busybox:1.32
command:
- sh
- -c
- |
chown -R 1000:1000 /usr/share/logstash/data
chmod -R 775 /usr/share/logstash/data
securityContext:
runAsUser: 0
volumeMounts:
- name: data
mountPath: /usr/share/logstash/data
containers:
- name: logstash
image: harbor.lanqicheng.top/library/logstash-oss:7.8.1
ports:
- containerPort: 5044 #指定logstash的监听端口,用于接收filebeat的日志
#指定logstash启动时加载的日志过滤文件
args:
- logstash
- "-f"
- "/usr/share/logstash/pipeline/logstash-kubernetes.conf"
resources:
limits:
memory: 1024Mi
env:
- name: PIPELINE_WORKERS #指定logstash的进程数量(与CPU核心保持一致)
value: "4"
- name: PIPELINE_BATCH_SIZE #每个线程每批处理的事件数量,默认125,增加数量可以提升logstash性能,但也会增加内存开销。
value: "10000"
lifecycle:
postStart: #postStart属性用于在容器启动后执行一些命令,通过postStart设定JVM内存
exec:
command:
- "/bin/bash"
- "-c"
- "sed -i -e '/^-Xms/c-Xms512m' -e '/^-Xmx/c-Xmx512m' /usr/share/logstash/config/jvm.options"
volumeMounts:
- name: data #持久化数据目录
mountPath: /usr/share/logstash/data
- name: conf
mountPath: /usr/share/logstash/pipeline/logstash-kubernetes.conf
subPath: logstash-kubernetes.conf
volumes:
- name: conf
configMap:
name: logstash-config
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "nfs-storage"
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: logstash-svc
namespace: elk
spec:
clusterIP: None
selector:
app: logstash
ports:
- port: 5044
targetPort: 5044
[root@master elk]# kubectl apply -f logstash.yaml配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: elk | 与实际命名空间一致;使用默认命名空间时可不写。 |
replicas: 1 | 按可用性和资源容量设置副本数。 |
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/busybox:1.32 | 替换为实际可拉取的镜像地址和版本。 |
image: harbor.lanqicheng.top/library/logstash-oss:7.8.1 | 替换为实际可拉取的镜像地址和版本。 |
accessModes: ["ReadWriteOnce"] | 按存储类型与读写需求确认。 |
storageClassName: nfs-storage | 替换为集群中存在的 StorageClass。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
- 镜像地址、版本号和拉取权限要确认,否则 Pod 会进入
ImagePullBackOff。
filebeat to Logstash
- 修改 filebeat 的 configMap 文件,将日志输出到Logstash
| 项目 | 应该怎么做 |
|---|---|
| 配置类型 | Kubernetes ConfigMap |
| 文件名 | filebeat-config.yaml |
| 写在哪里 | 保存到 ~/k8s-manifests/elk/filebeat-config.yaml;这是 Kubernetes 清单文件,不是容器内 /etc 配置。 |
| 在哪台机器执行 | Kubernetes 管理节点,或已配置正确 kubeconfig 且能执行 kubectl 的运维机。 |
| 复制后重点改 | namespace、Logstash 地址、日志路径或采集规则 |
| 应用配置 | kubectl apply -f filebeat-config.yaml |
| 验证结果 | kubectl get configmap filebeat-config -n elk |
| 注意事项 | Logstash 地址必须与 Service 名称和端口一致。 |
apiVersion: v1
kind: ConfigMap
metadata:
name: filebeat-config
namespace: elk
data:
filebeat.yml: |-
# ============================== Filebeat inputs kubelet ================================
filebeat.inputs:
- type: log
paths: /var/log/messages #kubelet日志默认写入到该文件中
include_lines: ['kubelet'] #在messages文件中只获取与kubelet相关的日志
fields: #为收集到的日志内容添加新字段名称
NameSpace: kubelet #增加新字段,后边作为索引名称
fields_under_root: true #并设置为顶级字段,否则到logstash中无法识别索引名称
exclude_lines: ["^.*\\[info\\].*"] #使用正则表达式排除info相关日志,info日志属于正常日志(\表示匹配\,\表示转义)
# =========================== Filebeat autodiscover ==============================
filebeat.autodiscover: #通过filebeat自动发现机制采集日志
providers:
- type: kubernetes #收集kubernetes集群日志
templates: #自动发现模板
# =================== 收集kube-system空间日志 ============================
- condition: #定义条件
equals: #等于
kubernetes.namespace: kube-system #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: all #收集错误日志
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# =================== 收集ingress-nginx 访问日志 =========================
- condition: #定义条件
equals: #等于
kubernetes.namespace: ingress-nginx #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stdout #对于nginx来说,访问日志默认写入到stdout中
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
#json.keys_under_root: true #默认将json解析存储至messages,true则不存储至message
#json.overwrite_keys: true #覆盖默认message字段,使用自定义json格式的key
# =================== 收集ingress-nginx 错误日志 =========================
- condition: #定义条件
equals: #等于
kubernetes.namespace: ingress-nginx #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: stderr #收集错误日志
encoding: utf-8 #字符集
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# =================== 收集zzyl空间日志 ============================
- condition: #定义条件
equals: #等于
kubernetes.namespace: zzyl #收集该名称空间下的日志
config: #定义配置信息
- type: container #日志类型为容器日志
stream: all #收集所有日志信息
encoding: utf-8 #字符集
multiline.pattern: '^\d{2}' #匹配以2个数字开头的行(日期开头)\d 匹配数字,等价于[0-9]
multiline.negate: true #将不符合规则的行合并在一起
multiline.match: after #合并到上一行的末尾
multiline.max_lines: 1000 #默认最大合并的行为500,可根据实际情况调整
paths: #日志路径
- /var/log/containers/*-${data.kubernetes.container.id}.log #通过自动发现的内置变量来识别容器ID
# ============================== Filebeat对输出字段优化 ================================
processors:
- rename: #重写字段名称
fields:
- from: "kubernetes.namespace"
to: "NameSpace"
- from: "kubernetes.pod.name"
to: "PodName"
- drop_fields: #删除无用的字段
fields: ["log","agent","ecs","input","kubernetes"]
# =========================== Output =====================================
# 先将日志内容输出到console看效果,容器启动后可通过 kubectl logs Pod名称 查看日志输出
output.logstash:
hosts: ["logstash-svc:5044"]配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: elk | 与实际命名空间一致;使用默认命名空间时可不写。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
使用Kibana进行索引管理
查看ElasticSearch集群索引
登录http://kibana.lanqicheng.top/


Kibana 索引模式
- 什么是 Kibana 索引模式(Index Pattern / Data View)
- Elasticsearch 里存放的是 索引(index),类似数据库里的表。比如:
kubelet-2025.09.25
ingress-nginx-stderr-2025.09.25
kube-apiserver-master-2025.09.25
- Kibana 要去 Elasticsearch 里查询和展示数据,但它需要知道 该查哪些索引,这就是 索引模式(Index Pattern,Kibana 7.x 之后叫 Data View)
创建索引模式




- 索引模式创建成功

查看索引日志


选定字段进行模版保存

Elasticsearch 进阶
4.1 什么是 Elasticsearch
Elasticsearch(简称 ES)是一个 分布式、RESTful 风格的搜索与分析引擎
底层基于 Apache Lucene,对外提供 JSON + HTTP 接口
核心能力:
- 海量数据存储
- 快速全文搜索
- 实时/近实时数据分析
4.2 ES 中的数据特点
- Index(索引):一类数据的集合,类似数据库里的表
- Document(文档):一条 JSON 数据,类似一行记录
- Field(字段):文档中的键值对
- ES 与传统数据库的区别
<sheet sheet-id="0ZCiI3" token="PBwgsKCiIh1axTtdBvhcb7pUnfc"></sheet>
- 数据存储物理结构Shard(分片):
- Primary Shard(主分片)
- Replica Shard(副本分片)
- 分片数量原则
- 分片 ≠ 越多越好
- 建议:
- shard 数量 ≈ 节点数 × 1\~2
- 副本数量=1
- 副本作用
- 高可用
- 提升查询并发
4.3 ES 集群架构
- 什么是集群(Cluster)
- 多个 ES 节点组成
- 共享集群名(cluster.name)
- 自动发现与选主
env:
- name: TZ
value: "Asia/Shanghai"
# 自定义集群名
- name: cluster.name
value: k8s-es
# 定义节点名,使用metadata.name名称
- name: node.name #当前节点在集群名称
valueFrom:
fieldRef:
fieldPath: metadata.name #名称通过该属性下定义的值获取,即:es-cluster-0,es-cluster-1,es-cluster-2
# 初始化集群时,ES从中选出master节点
- name: cluster.initial_master_nodes
# 对应metadata.name名称加编号,编号从0开始
value: "es-cluster-0,es-cluster-1,es-cluster-2"
# 发现节点的地址,discovery.seed_hosts的值应包括所有master候选节点
- name: discovery.seed_hosts
value: "es-cluster-svc"
# 配置JVM堆内存(JVM 的堆内存是 Java 应用程序中对象和数组的主要存储区域,负责动态内存管理和垃圾回收,是 Java 程序运行的核心部分)注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
4.4 索引日常管理指令
- 查看索引
# 查看所有索引
curl -X GET "http://localhost:9200/_cat/indices?v"
# 查看指定索引
curl -X GET "http://localhost:9200/_cat/indices/logs-*?v"
# 按大小排序
curl -X GET "http://localhost:9200/_cat/indices?v&s=store.size:desc"
# 查看索引分片
curl -X GET "http://localhost:9200/_cat/shards?v"
curl -X GET "http://localhost:9200/_cat/shards/my-index?v"注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
# 创建索引
curl -X PUT "http://localhost:9200/my-index" -H 'Content-Type: application/json' -d'
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}
'
# 删除索引
curl -X DELETE "http://localhost:9200/my-index"
# 关闭索引
curl -X POST "http://localhost:9200/my-index/_close"
# 打开索引
curl -X POST "http://localhost:9200/my-index/_open"命令作用:
- 访问
目标 URL;curl默认把响应写到终端,wget默认下载到文件。可据 HTTP 状态、响应内容或下载结果判断服务是否可访问。
- 访问
http://localhost:9200/my-index;curl默认把响应写到终端,wget默认下载到文件。可据 HTTP 状态、响应内容或下载结果判断服务是否可访问。
- 访问
http://localhost:9200/my-index/_close;curl默认把响应写到终端,wget默认下载到文件。可据 HTTP 状态、响应内容或下载结果判断服务是否可访问。
- 访问
http://localhost:9200/my-index/_open;curl默认把响应写到终端,wget默认下载到文件。可据 HTTP 状态、响应内容或下载结果判断服务是否可访问。
执行结果:
- 成功后会显示服务器响应或按选项写入文件;HTTP 状态和响应内容可用于验证服务。
关键参数:
| 参数 | 说明 | |
|---|---|---|
http://localhost:9200/my-index | 普通 | 目标 URL http://localhost:9200/my-index,命令会访问这个地址或从这里下载内容。 |
http://localhost:9200/my-index/_close | 普通 | 目标 URL http://localhost:9200/my-index/_close,命令会访问这个地址或从这里下载内容。 |
http://localhost:9200/my-index/_open | 普通 | 目标 URL http://localhost:9200/my-index/_open,命令会访问这个地址或从这里下载内容。 |
注意事项:
本文由飞书云文档同步生成。涉及命令、SQL、配置示例时,请以飞书源文档和实际环境执行结果为准。