K8s事件默认仅在etcd中保留1小时,需导出至Elasticsearch等外部存储以支持历史异常分析;应部署eventrouter通过List-Watch采集事件,配置ES地址、索引并启用CORS,最后通过日志和ES count验证写入成功。

K8s集群事件默认只保留在etcd中1小时,超出时间后无法检索,排查历史调度异常、Pod驱逐原因或资源争用问题时直接丢失关键线索。必须将Events导出到外部存储才能支撑深度运维分析。
准备Elasticsearch接收端
确保Elasticsearch集群已就绪且可写入。若使用Docker快速验证,执行:docker run -d --name es01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "ES_JAVA_OPTS=-Xms1g -Xmx1g" -e "http.cors.enabled=true" -e "http.cors.allow-origin=*" docker.elastic.co/elasticsearch/elasticsearch:8.15.0。
启动后必须修改Elasticsearch配置启用CORS,否则eventrouter等客户端无法连接——【未开启http.cors.allow-origin会导致所有事件推送失败且无明确报错】。
进入容器执行curl -XPUT 'http://localhost:9200/k8s-events'手动创建索引,避免首次写入时自动创建导致mapping不兼容。
部署eventrouter采集器
eventrouter采用List-Watch机制监听集群Events,比轮询更高效且不丢事件。
方法一:直接应用官方YAML(推荐)
下载https://raw.githubusercontent.com/heptiolabs/eventrouter/master/deploy/clusterrole.yaml→clusterrolebinding.yaml→deployment.yaml三份文件,编辑deployment.yaml中容器环境变量:
env:- name: EVENT_ROUTER_BACKEND value: "elasticsearch"- name: ELASTICSEARCH_URL value: "http://elasticsearch.default.svc.cluster.local:9200"- name: ELASTICSEARCH_INDEX value: "k8s-events"
若Elasticsearch不在同Namespace,需将Service地址改为实际可用地址,例如NodePort或Ingress暴露的域名。
方法二:使用ConfigMap解耦配置
创建ConfigMap保存后端参数,避免硬编码在Deployment中:
kubectl create configmap eventrouter-config --from-literal=backend=elasticsearch --from-literal=es-url=http://10.96.200.50:9200 --from-literal=es-index=k8s-events -n kube-system
然后在Deployment的envFrom字段引用该ConfigMap,便于后续切换存储目标。
验证事件写入效果
第一步:触发一条测试事件
执行kubectl get nodes && sleep 1 && kubectl describe node $(kubectl get nodes -o jsonpath='{.items[0].metadata.name}'),强制生成一次节点描述事件。
第二步:检查eventrouter日志是否上报成功
运行kubectl logs -n kube-system deploy/eventrouter | tail -20,确认输出含Sent X events to elasticsearch字样,且无connection refused或400 Bad Request错误。
第三步:直查Elasticsearch确认索引有数据
执行curl 'http://<es_ip>:9200/k8s-events/_count?pretty'</es_ip>,返回"count":1或更大数值即表示事件已落库。
注意:首次查询可能延迟3~5秒,因eventrouter默认批量发送(batch size=10或10s超时),小规模集群建议调低BATCH_SIZE和FLUSH_INTERVAL环境变量加快验证。
第四步:在Kibana中添加index pattern为k8s-events,选择@timestamp作为时间字段,即可开始按namespace、reason、involvedObject.kind等维度筛选分析。

















